1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11// owning_view() requires default_initializable<R> = default;
12// constexpr owning_view(R&& t);
13
14#include <ranges>
15
16#include <cassert>
17#include <concepts>
18#include <type_traits>
19#include <utility>
20
21#include "test_macros.h"
22
23struct DefaultConstructible {
24 int i;
25 constexpr explicit DefaultConstructible(int j = 42) : i(j) {}
26 int *begin() const;
27 int *end() const;
28};
29
30struct NotDefaultConstructible {
31 int i;
32 constexpr explicit NotDefaultConstructible(int j) : i(j) {}
33 int *begin() const;
34 int *end() const;
35};
36
37struct MoveChecker {
38 int i;
39 constexpr explicit MoveChecker(int j) : i(j) {}
40 constexpr MoveChecker(MoveChecker&& v) : i(std::exchange(obj&: v.i, new_val: -1)) {}
41 MoveChecker& operator=(MoveChecker&&);
42 int *begin() const;
43 int *end() const;
44};
45
46struct NoexceptChecker {
47 int *begin() const;
48 int *end() const;
49};
50
51constexpr bool test()
52{
53 {
54 using OwningView = std::ranges::owning_view<DefaultConstructible>;
55 static_assert(std::is_constructible_v<OwningView>);
56 static_assert(std::default_initializable<OwningView>);
57 static_assert(std::movable<OwningView>);
58 static_assert(std::is_trivially_move_constructible_v<OwningView>);
59 static_assert(std::is_trivially_move_assignable_v<OwningView>);
60 static_assert(!std::is_copy_constructible_v<OwningView>);
61 static_assert(!std::is_copy_assignable_v<OwningView>);
62 static_assert(!std::is_constructible_v<OwningView, int>);
63 static_assert(!std::is_constructible_v<OwningView, DefaultConstructible&>);
64 static_assert(std::is_constructible_v<OwningView, DefaultConstructible&&>);
65 static_assert(!std::is_convertible_v<int, OwningView>);
66 static_assert(std::is_convertible_v<DefaultConstructible&&, OwningView>);
67 {
68 OwningView ov;
69 assert(ov.base().i == 42);
70 }
71 {
72 OwningView ov = OwningView(DefaultConstructible(1));
73 assert(ov.base().i == 1);
74 }
75 }
76 {
77 using OwningView = std::ranges::owning_view<NotDefaultConstructible>;
78 static_assert(!std::is_constructible_v<OwningView>);
79 static_assert(!std::default_initializable<OwningView>);
80 static_assert(std::movable<OwningView>);
81 static_assert(std::is_trivially_move_constructible_v<OwningView>);
82 static_assert(std::is_trivially_move_assignable_v<OwningView>);
83 static_assert(!std::is_copy_constructible_v<OwningView>);
84 static_assert(!std::is_copy_assignable_v<OwningView>);
85 static_assert(!std::is_constructible_v<OwningView, int>);
86 static_assert(!std::is_constructible_v<OwningView, NotDefaultConstructible&>);
87 static_assert(std::is_constructible_v<OwningView, NotDefaultConstructible&&>);
88 static_assert(!std::is_convertible_v<int, OwningView>);
89 static_assert(std::is_convertible_v<NotDefaultConstructible&&, OwningView>);
90 {
91 OwningView ov = OwningView(NotDefaultConstructible(1));
92 assert(ov.base().i == 1);
93 }
94 }
95 {
96 using OwningView = std::ranges::owning_view<MoveChecker>;
97 static_assert(!std::is_constructible_v<OwningView>);
98 static_assert(!std::default_initializable<OwningView>);
99 static_assert(std::movable<OwningView>);
100 static_assert(!std::is_trivially_move_constructible_v<OwningView>);
101 static_assert(!std::is_trivially_move_assignable_v<OwningView>);
102 static_assert(!std::is_copy_constructible_v<OwningView>);
103 static_assert(!std::is_copy_assignable_v<OwningView>);
104 static_assert(!std::is_constructible_v<OwningView, int>);
105 static_assert(!std::is_constructible_v<OwningView, MoveChecker&>);
106 static_assert(std::is_constructible_v<OwningView, MoveChecker&&>);
107 static_assert(!std::is_convertible_v<int, OwningView>);
108 static_assert(std::is_convertible_v<MoveChecker&&, OwningView>);
109 {
110 // Check that the constructor does indeed move from the target object.
111 auto m = MoveChecker(42);
112 OwningView ov = OwningView(std::move(m));
113 assert(ov.base().i == 42);
114 assert(m.i == -1);
115 }
116 }
117 {
118 // Check that the defaulted constructors are (not) noexcept when appropriate.
119
120 static_assert( std::is_nothrow_constructible_v<NoexceptChecker>); // therefore,
121 static_assert( std::is_nothrow_constructible_v<std::ranges::owning_view<NoexceptChecker>>);
122 static_assert(!std::is_nothrow_constructible_v<DefaultConstructible>); // therefore,
123 static_assert(!std::is_nothrow_constructible_v<std::ranges::owning_view<DefaultConstructible>>);
124
125 static_assert( std::is_nothrow_move_constructible_v<NoexceptChecker>); // therefore,
126 static_assert( std::is_nothrow_move_constructible_v<std::ranges::owning_view<NoexceptChecker>>);
127 static_assert(!std::is_nothrow_move_constructible_v<MoveChecker>); // therefore,
128 static_assert(!std::is_nothrow_move_constructible_v<std::ranges::owning_view<MoveChecker>>);
129 }
130 return true;
131}
132
133int main(int, char**) {
134 test();
135 static_assert(test());
136
137 return 0;
138}
139

source code of libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/constructor.pass.cpp