]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/optional/requirements.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / optional / requirements.cc
1 // { dg-options "-std=gnu++17" }
2 // { dg-do run }
3
4 // Copyright (C) 2013-2018 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3. If not see
19 // <http://www.gnu.org/licenses/>.
20
21 #include <optional>
22 #include <testsuite_hooks.h>
23
24 #include <tuple>
25
26 using std::bad_optional_access;
27 static_assert( std::is_default_constructible<bad_optional_access>::value, "" );
28
29 struct trivially_destructible
30 {
31 trivially_destructible() = delete;
32 trivially_destructible(trivially_destructible const&) = delete;
33 trivially_destructible& operator=(trivially_destructible const&) = delete;
34 trivially_destructible(trivially_destructible&&) = delete;
35 trivially_destructible& operator=(trivially_destructible&&) = delete;
36 ~trivially_destructible() noexcept = default;
37 };
38
39 static_assert( std::is_trivially_destructible<trivially_destructible>(), "" );
40
41 struct no_default_constructor
42 {
43 no_default_constructor() = delete;
44 };
45
46 struct no_copy_constructor
47 {
48 no_copy_constructor() = default;
49 no_copy_constructor(no_copy_constructor const&) = delete;
50 no_copy_constructor& operator=(no_copy_constructor const&) = default;
51 no_copy_constructor(no_copy_constructor&&) = default;
52 no_copy_constructor& operator=(no_copy_constructor&&) = default;
53 };
54
55 struct no_copy_assignment
56 {
57 no_copy_assignment() = default;
58 no_copy_assignment(no_copy_assignment const&) = default;
59 no_copy_assignment(no_copy_assignment&&) = default;
60 no_copy_assignment& operator=(no_copy_assignment&&) = default;
61 };
62
63 struct no_move_constructor
64 {
65 no_move_constructor() = default;
66 no_move_constructor(no_move_constructor const&) = default;
67 no_move_constructor& operator=(no_move_constructor const&) = default;
68 no_move_constructor(no_move_constructor&&) = delete;
69 no_move_constructor& operator=(no_move_constructor&&) = default;
70 };
71
72 struct no_move_assignment
73 {
74 no_move_assignment() = default;
75 no_move_assignment(no_move_assignment const&) = default;
76 no_move_assignment& operator=(no_move_assignment const&) = default;
77 no_move_assignment(no_move_assignment&&) = default;
78 no_move_assignment& operator=(no_move_assignment&&) = delete;
79 };
80
81 struct no_copy : no_copy_constructor, no_copy_assignment { };
82 struct no_move : no_move_constructor, no_move_assignment { };
83
84 // Laxest possible model of a value type for optional
85 struct only_destructible
86 {
87 only_destructible(only_destructible&&) = delete;
88 };
89
90 int main()
91 {
92 {
93 static_assert( std::is_trivially_destructible<std::optional<trivially_destructible>>(), "" );
94 }
95
96 {
97 using T = no_default_constructor;
98 using O = std::optional<T>;
99 static_assert( std::is_same<O::value_type, T>(), "" );
100 static_assert( std::is_default_constructible<O>(), "" );
101 { O o; }
102 static_assert( std::is_copy_constructible<O>(), "" );
103 { O o; auto copy = o; }
104 static_assert( std::is_copy_assignable<O>(), "" );
105 { O o, p; p = o; }
106 static_assert( std::is_move_constructible<O>(), "" );
107 { O o; auto moved_to = std::move(o); }
108 static_assert( std::is_move_assignable<O>(), "" );
109 { O o, p; p = std::move(o); }
110 }
111
112 {
113 using T = no_copy_constructor;
114 using O = std::optional<T>;
115 static_assert( std::is_same<O::value_type, T>(), "" );
116 static_assert( std::is_default_constructible<O>(), "" );
117 { O o; }
118 static_assert( !std::is_copy_constructible<O>(), "" );
119 static_assert( !std::is_copy_assignable<O>(), "" );
120 static_assert( std::is_move_constructible<O>(), "" );
121 { O o; auto moved_to = std::move(o); }
122 static_assert( std::is_move_assignable<O>(), "" );
123 { O o, p; p = std::move(o); }
124 }
125
126 {
127 using T = no_copy_assignment;
128 using O = std::optional<T>;
129 static_assert( std::is_default_constructible<O>(), "" );
130 { O o; }
131 static_assert( std::is_copy_constructible<O>(), "" );
132 { O o; auto copy = o; }
133 static_assert( !std::is_copy_assignable<O>(), "" );
134 static_assert( std::is_move_constructible<O>(), "" );
135 { O o; auto moved_to = std::move(o); }
136 static_assert( std::is_move_assignable<O>(), "" );
137 { O o, p; p = std::move(o); }
138 }
139
140 {
141 using T = no_copy;
142 using O = std::optional<T>;
143 static_assert( std::is_same<O::value_type, T>(), "" );
144 static_assert( std::is_default_constructible<O>(), "" );
145 { O o; }
146 static_assert( !std::is_copy_constructible<O>(), "" );
147 static_assert( !std::is_copy_assignable<O>(), "" );
148 static_assert( std::is_move_constructible<O>(), "" );
149 { O o; auto moved_to = std::move(o); }
150 static_assert( std::is_move_assignable<O>(), "" );
151 { O o, p; p = std::move(o); }
152 }
153
154 {
155 using T = no_move_constructor;
156 using O = std::optional<T>;
157 static_assert( std::is_same<O::value_type, T>(), "" );
158 static_assert( std::is_default_constructible<O>(), "" );
159 { O o; }
160 static_assert( std::is_copy_constructible<O>(), "" );
161 { O o; auto copy = o; }
162 static_assert( std::is_copy_assignable<O>(), "" );
163 /*
164 * T should be move constructible due to [12.8/11], which is a new rule in C++1y
165 * not yet implemented by GCC. Because there is already a special exception in C++11
166 * for the generation of the special members that GCC implements (at least some of the
167 * time), this does not affect the std::optional implementation however. So the assertion
168 * for T should be changed (or removed altogether) when the time comes, but the rest
169 * should however remain correct and unchanged.
170 */
171 static_assert( !std::is_move_constructible<T>(), "" );
172 static_assert( std::is_move_constructible<O>(), "" );
173 { O o; auto moved_to = std::move(o); }
174 static_assert( std::is_move_assignable<O>(), "" );
175 { O o, p; p = std::move(o); }
176 }
177
178 {
179 using T = no_move_assignment;
180 using O = std::optional<T>;
181 static_assert( std::is_same<O::value_type, T>(), "" );
182 static_assert( std::is_default_constructible<O>(), "" );
183 { O o; }
184 static_assert( std::is_copy_constructible<O>(), "" );
185 { O o; auto copy = o; }
186 static_assert( std::is_copy_assignable<O>(), "" );
187 { O o, p; p = o; }
188 static_assert( std::is_move_constructible<O>(), "" );
189 { O o; auto moved_to = std::move(o); }
190 /*
191 * Paragraph 23 of same leads to a similar situation but with respect to move
192 * assignment.
193 */
194 static_assert( !std::is_move_assignable<T>(), "" );
195 static_assert( std::is_move_assignable<O>(), "" );
196 { O o, p; p = std::move(o); }
197 }
198
199 {
200 using T = no_move;
201 using O = std::optional<T>;
202 static_assert( std::is_same<O::value_type, T>(), "" );
203 static_assert( std::is_default_constructible<O>(), "" );
204 { O o; }
205 static_assert( std::is_copy_constructible<O>(), "" );
206 { O o; auto copy = o; }
207 static_assert( std::is_copy_assignable<O>(), "" );
208 { O o, p; p = o; }
209 static_assert( std::is_move_constructible<O>(), "" );
210 { O o; auto moved_to = std::move(o); }
211 static_assert( std::is_move_assignable<O>(), "" );
212 { O o, p; p = std::move(o); }
213 }
214
215 {
216 using T = only_destructible;
217 using O = std::optional<T>;
218 static_assert( std::is_same<O::value_type, T>(), "" );
219 static_assert( std::is_default_constructible<O>(), "" );
220 { O o; }
221 static_assert( !std::is_copy_constructible<O>(), "" );
222 static_assert( !std::is_copy_assignable<O>(), "" );
223 static_assert( !std::is_move_constructible<O>(), "" );
224 static_assert( !std::is_move_assignable<O>(), "" );
225 }
226
227 {
228 /*
229 * Should not complain about 'invalid' specializations as long as
230 * they're not instantiated.
231 */
232 using A = std::optional<int&>;
233 using B = std::optional<int&&>;
234 using C1 = std::optional<std::in_place_t>;
235 using C2 = std::optional<std::in_place_t const>;
236 using C3 = std::optional<std::in_place_t volatile>;
237 using C4 = std::optional<std::in_place_t const volatile>;
238 using D1 = std::optional<std::nullopt_t>;
239 using D2 = std::optional<std::nullopt_t const>;
240 using D3 = std::optional<std::nullopt_t volatile>;
241 using D4 = std::optional<std::nullopt_t const volatile>;
242
243 using X = std::tuple<A, B, C1, C2, C3, C4, D1, D2, D3, D4>;
244 }
245
246 {
247 std::optional<const int> o { 42 };
248 static_assert( std::is_same<decltype(o)::value_type, const int>(), "" );
249 VERIFY( o );
250 VERIFY( *o == 42 );
251 }
252
253 {
254 constexpr std::optional<const int> o { 33 };
255 static_assert( std::is_same<decltype(o)::value_type, const int>(), "" );
256 static_assert( o, "" );
257 static_assert( *o == 33, "" );
258 }
259 }
260
261 using std::void_t;
262 using std::declval;
263 using std::true_type;
264 using std::false_type;
265
266 template <class T, class = void>
267 struct is_eq_comparable : false_type {};
268 template <class T>
269 struct is_eq_comparable<T, void_t<decltype(declval<T>() == declval<T>())>>
270 : true_type {};
271
272 template <class T, class = void>
273 struct is_neq_comparable : false_type {};
274 template <class T>
275 struct is_neq_comparable<T, void_t<decltype(declval<T>() != declval<T>())>>
276 : true_type {};
277
278 template <class T, class = void>
279 struct is_lt_comparable : false_type {};
280 template <class T>
281 struct is_lt_comparable<T, void_t<decltype(declval<T>() < declval<T>())>>
282 : true_type {};
283
284 template <class T, class = void>
285 struct is_gt_comparable : false_type {};
286 template <class T>
287 struct is_gt_comparable<T, void_t<decltype(declval<T>() > declval<T>())>>
288 : true_type {};
289
290 template <class T, class = void>
291 struct is_le_comparable : false_type {};
292 template <class T>
293 struct is_le_comparable<T, void_t<decltype(declval<T>() <= declval<T>())>>
294 : true_type {};
295
296 template <class T, class = void>
297 struct is_ge_comparable : false_type {};
298 template <class T>
299 struct is_ge_comparable<T, void_t<decltype(declval<T>() >= declval<T>())>>
300 : true_type {};
301
302 using std::optional;
303
304 static_assert(is_eq_comparable<optional<int>>::value, "");
305 static_assert(is_neq_comparable<optional<int>>::value, "");
306 static_assert(is_lt_comparable<optional<int>>::value, "");
307 static_assert(is_gt_comparable<optional<int>>::value, "");
308 static_assert(is_le_comparable<optional<int>>::value, "");
309 static_assert(is_ge_comparable<optional<int>>::value, "");
310
311 struct JustEq {};
312 bool operator==(const JustEq&, const JustEq&);
313
314 static_assert(is_eq_comparable<optional<JustEq>>::value, "");
315 static_assert(!is_neq_comparable<optional<JustEq>>::value, "");
316 static_assert(!is_lt_comparable<optional<JustEq>>::value, "");
317 static_assert(!is_gt_comparable<optional<JustEq>>::value, "");
318 static_assert(!is_le_comparable<optional<JustEq>>::value, "");
319 static_assert(!is_ge_comparable<optional<JustEq>>::value, "");
320
321 struct JustLt {};
322 bool operator<(const JustLt&, const JustLt&);
323
324 static_assert(!is_eq_comparable<optional<JustLt>>::value, "");
325 static_assert(!is_neq_comparable<optional<JustLt>>::value, "");
326 static_assert(is_lt_comparable<optional<JustLt>>::value, "");
327 static_assert(!is_gt_comparable<optional<JustLt>>::value, "");
328 static_assert(!is_le_comparable<optional<JustLt>>::value, "");
329 static_assert(!is_ge_comparable<optional<JustLt>>::value, "");
330
331 static_assert(!std::is_assignable<optional<JustEq>&,
332 optional<JustLt>>::value, "");
333 static_assert(!std::is_assignable<optional<JustEq>&,
334 JustLt>::value, "");
335 static_assert(!std::is_assignable<optional<JustEq>&,
336 optional<JustLt>&>::value, "");
337 static_assert(!std::is_assignable<optional<JustEq>&,
338 JustLt&>::value, "");