xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/constructor.pass.cpp (revision b8cb1dc9ea87faa8e8e9ab7a31710a8c0bb8b084)
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 
23 struct DefaultConstructible {
24   int i;
DefaultConstructibleDefaultConstructible25   constexpr explicit DefaultConstructible(int j = 42) : i(j) {}
26   int *begin() const;
27   int *end() const;
28 };
29 
30 struct NotDefaultConstructible {
31   int i;
NotDefaultConstructibleNotDefaultConstructible32   constexpr explicit NotDefaultConstructible(int j) : i(j) {}
33   int *begin() const;
34   int *end() const;
35 };
36 
37 struct MoveChecker {
38   int i;
MoveCheckerMoveChecker39   constexpr explicit MoveChecker(int j) : i(j) {}
MoveCheckerMoveChecker40   constexpr MoveChecker(MoveChecker&& v) : i(std::exchange(v.i, -1)) {}
41   MoveChecker& operator=(MoveChecker&&);
42   int *begin() const;
43   int *end() const;
44 };
45 
46 struct NoexceptChecker {
47   int *begin() const;
48   int *end() const;
49 };
50 
test()51 constexpr 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 
main(int,char **)133 int main(int, char**) {
134   test();
135   static_assert(test());
136 
137   return 0;
138 }
139