1 // { dg-options "-std=gnu++17" }
2 // { dg-do compile }
3
4 // Copyright (C) 2016-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 <variant>
22 #include <string>
23 #include <vector>
24
25 using namespace std;
26
27 struct AllDeleted
28 {
29 AllDeleted() = delete;
30 AllDeleted(const AllDeleted&) = delete;
31 AllDeleted(AllDeleted&&) = delete;
32 AllDeleted& operator=(const AllDeleted&) = delete;
33 AllDeleted& operator=(AllDeleted&&) = delete;
34 };
35
36 struct Empty
37 {
EmptyEmpty38 Empty() { };
EmptyEmpty39 Empty(const Empty&) { };
EmptyEmpty40 Empty(Empty&&) { };
operator =Empty41 Empty& operator=(const Empty&) { return *this; };
operator =Empty42 Empty& operator=(Empty&&) { return *this; };
43 };
44
45 struct DefaultNoexcept
46 {
47 DefaultNoexcept() noexcept = default;
48 DefaultNoexcept(const DefaultNoexcept&) noexcept = default;
49 DefaultNoexcept(DefaultNoexcept&&) noexcept = default;
50 DefaultNoexcept& operator=(const DefaultNoexcept&) noexcept = default;
51 DefaultNoexcept& operator=(DefaultNoexcept&&) noexcept = default;
52 };
53
54 struct MoveCtorOnly
55 {
56 MoveCtorOnly() noexcept = delete;
57 MoveCtorOnly(const DefaultNoexcept&) noexcept = delete;
MoveCtorOnlyMoveCtorOnly58 MoveCtorOnly(DefaultNoexcept&&) noexcept { }
59 MoveCtorOnly& operator=(const DefaultNoexcept&) noexcept = delete;
60 MoveCtorOnly& operator=(DefaultNoexcept&&) noexcept = delete;
61 };
62
63 struct nonliteral
64 {
nonliteralnonliteral65 nonliteral() { }
66
67 bool operator<(const nonliteral&) const;
68 bool operator<=(const nonliteral&) const;
69 bool operator==(const nonliteral&) const;
70 bool operator!=(const nonliteral&) const;
71 bool operator>=(const nonliteral&) const;
72 bool operator>(const nonliteral&) const;
73 };
74
default_ctor()75 void default_ctor()
76 {
77 static_assert(is_default_constructible_v<variant<int, string>>, "");
78 static_assert(is_default_constructible_v<variant<string, string>>, "");
79 static_assert(!is_default_constructible_v<variant<AllDeleted, string>>, "");
80 static_assert(is_default_constructible_v<variant<string, AllDeleted>>, "");
81
82 static_assert(noexcept(variant<int>()), "");
83 static_assert(!noexcept(variant<Empty>()), "");
84 static_assert(noexcept(variant<DefaultNoexcept>()), "");
85 }
86
copy_ctor()87 void copy_ctor()
88 {
89 static_assert(is_copy_constructible_v<variant<int, string>>, "");
90 static_assert(!is_copy_constructible_v<variant<AllDeleted, string>>, "");
91 static_assert(is_trivially_copy_constructible_v<variant<int>>, "");
92 static_assert(!is_trivially_copy_constructible_v<variant<std::string>>, "");
93
94 {
95 variant<int> a;
96 static_assert(noexcept(variant<int>(a)), "");
97 }
98 {
99 variant<string> a;
100 static_assert(!noexcept(variant<string>(a)), "");
101 }
102 {
103 variant<int, string> a;
104 static_assert(!noexcept(variant<int, string>(a)), "");
105 }
106 {
107 variant<int, char> a;
108 static_assert(noexcept(variant<int, char>(a)), "");
109 }
110 }
111
move_ctor()112 void move_ctor()
113 {
114 static_assert(is_move_constructible_v<variant<int, string>>, "");
115 static_assert(!is_move_constructible_v<variant<AllDeleted, string>>, "");
116 static_assert(is_trivially_move_constructible_v<variant<int>>, "");
117 static_assert(!is_trivially_move_constructible_v<variant<std::string>>, "");
118 static_assert(!noexcept(variant<int, Empty>(declval<variant<int, Empty>>())), "");
119 static_assert(noexcept(variant<int, DefaultNoexcept>(declval<variant<int, DefaultNoexcept>>())), "");
120 }
121
arbitrary_ctor()122 void arbitrary_ctor()
123 {
124 static_assert(!is_constructible_v<variant<string, string>, const char*>, "");
125 static_assert(is_constructible_v<variant<int, string>, const char*>, "");
126 static_assert(noexcept(variant<int, Empty>(int{})), "");
127 static_assert(noexcept(variant<int, DefaultNoexcept>(int{})), "");
128 static_assert(!noexcept(variant<int, Empty>(Empty{})), "");
129 static_assert(noexcept(variant<int, DefaultNoexcept>(DefaultNoexcept{})), "");
130 }
131
132 struct none { none() = delete; };
anyany133 struct any { template <typename T> any(T&&) {} };
134
in_place_index_ctor()135 void in_place_index_ctor()
136 {
137 variant<string, string> a(in_place_index<0>, "a");
138 variant<string, string> b(in_place_index<1>, {'a'});
139
140 static_assert(!is_constructible_v<variant<none, any>, std::in_place_index_t<0>>, "PR libstdc++/90165");
141 }
142
in_place_type_ctor()143 void in_place_type_ctor()
144 {
145 variant<int, string, int> a(in_place_type<string>, "a");
146 variant<int, string, int> b(in_place_type<string>, {'a'});
147 static_assert(!is_constructible_v<variant<string, string>, in_place_type_t<string>, const char*>, "");
148 static_assert(!is_constructible_v<variant<none, any>, std::in_place_type_t<none>>, "PR libstdc++/90165");
149 }
150
dtor()151 void dtor()
152 {
153 static_assert(is_destructible_v<variant<int, string>>, "");
154 static_assert(is_destructible_v<variant<AllDeleted, string>>, "");
155 }
156
copy_assign()157 void copy_assign()
158 {
159 static_assert(is_copy_assignable_v<variant<int, string>>, "");
160 static_assert(!is_copy_assignable_v<variant<AllDeleted, string>>, "");
161 static_assert(is_trivially_copy_assignable_v<variant<int>>, "");
162 static_assert(!is_trivially_copy_assignable_v<variant<string>>, "");
163 {
164 variant<Empty> a;
165 static_assert(!noexcept(a = a), "");
166 }
167 {
168 variant<DefaultNoexcept> a;
169 static_assert(noexcept(a = a), "");
170 }
171 }
172
move_assign()173 void move_assign()
174 {
175 static_assert(is_move_assignable_v<variant<int, string>>, "");
176 static_assert(!is_move_assignable_v<variant<AllDeleted, string>>, "");
177 static_assert(is_trivially_move_assignable_v<variant<int>>, "");
178 static_assert(!is_trivially_move_assignable_v<variant<string>>, "");
179 {
180 variant<Empty> a;
181 static_assert(!noexcept(a = std::move(a)), "");
182 }
183 {
184 variant<DefaultNoexcept> a;
185 static_assert(noexcept(a = std::move(a)), "");
186 }
187 }
188
arbitrary_assign()189 void arbitrary_assign()
190 {
191 static_assert(!is_assignable_v<variant<string, string>, const char*>, "");
192 static_assert(is_assignable_v<variant<int, string>, const char*>, "");
193 static_assert(noexcept(variant<int, Empty>() = int{}), "");
194 static_assert(noexcept(variant<int, DefaultNoexcept>() = int{}), "");
195 static_assert(!noexcept(variant<int, Empty>() = Empty{}), "");
196 static_assert(noexcept(variant<int, DefaultNoexcept>() = DefaultNoexcept{}), "");
197 }
198
test_get()199 void test_get()
200 {
201 static_assert(is_same<decltype(get<0>(variant<int, string>())), int&&>::value, "");
202 static_assert(is_same<decltype(get<1>(variant<int, string>())), string&&>::value, "");
203 static_assert(is_same<decltype(get<1>(variant<int, const string>())), const string&&>::value, "");
204
205 static_assert(is_same<decltype(get<int>(variant<int, string>())), int&&>::value, "");
206 static_assert(is_same<decltype(get<string>(variant<int, string>())), string&&>::value, "");
207 static_assert(is_same<decltype(get<const string>(variant<int, const string>())), const string&&>::value, "");
208 }
209
test_relational()210 void test_relational()
211 {
212 {
213 constexpr variant<int, nonliteral> a(42), b(43);
214 static_assert((a < b), "");
215 static_assert(!(a > b), "");
216 static_assert((a <= b), "");
217 static_assert(!(a == b), "");
218 static_assert((a != b), "");
219 static_assert(!(a >= b), "");
220 }
221 {
222 constexpr variant<int, nonliteral> a(42), b(42);
223 static_assert(!(a < b), "");
224 static_assert(!(a > b), "");
225 static_assert((a <= b), "");
226 static_assert((a == b), "");
227 static_assert(!(a != b), "");
228 static_assert((a >= b), "");
229 }
230 {
231 constexpr variant<int, nonliteral> a(43), b(42);
232 static_assert(!(a < b), "");
233 static_assert((a > b), "");
234 static_assert(!(a <= b), "");
235 static_assert(!(a == b), "");
236 static_assert((a != b), "");
237 static_assert((a >= b), "");
238 }
239 {
240 constexpr monostate a, b;
241 static_assert(!(a < b), "");
242 static_assert(!(a > b), "");
243 static_assert((a <= b), "");
244 static_assert((a == b), "");
245 static_assert(!(a != b), "");
246 static_assert((a >= b), "");
247 }
248 }
249
250 // Not swappable, and variant<C> not swappable via the generic std::swap.
251 struct C { };
252 void swap(C&, C&) = delete;
253
254 static_assert( !std::is_swappable_v<variant<C>> );
255 static_assert( !std::is_swappable_v<variant<int, C>> );
256 static_assert( !std::is_swappable_v<variant<C, int>> );
257
258 // Not swappable, and variant<D> not swappable via the generic std::swap.
259 struct D { D(D&&) = delete; };
260
261 static_assert( !std::is_swappable_v<variant<D>> );
262 static_assert( !std::is_swappable_v<variant<int, D>> );
263 static_assert( !std::is_swappable_v<variant<D, int>> );
264
test_swap()265 void test_swap()
266 {
267 static_assert(is_swappable_v<variant<int, string>>, "");
268 static_assert(is_swappable_v<variant<MoveCtorOnly>>, "");
269 static_assert(!is_swappable_v<variant<AllDeleted>>, "");
270 }
271
test_visit()272 void test_visit()
273 {
274 {
275 struct Visitor
276 {
277 void operator()(monostate) {}
278 void operator()(const int&) {}
279 };
280 struct CVisitor
281 {
282 void operator()(monostate) const {}
283 void operator()(const int&) const {}
284 };
285 }
286 {
287 struct Visitor
288 {
289 bool operator()(int, float) { return false; }
290 bool operator()(int, double) { return false; }
291 bool operator()(char, float) { return false; }
292 bool operator()(char, double) { return false; }
293 };
294 visit(Visitor(), variant<int, char>(), variant<float, double>());
295 }
296 {
297 struct Visitor
298 {
299 constexpr bool operator()(const int&) { return true; }
300 constexpr bool operator()(const nonliteral&) { return false; }
301 };
302 static_assert(visit(Visitor(), variant<int, nonliteral>(0)), "");
303 }
304 {
305 struct Visitor
306 {
307 constexpr bool operator()(const int&) { return true; }
308 constexpr bool operator()(const nonliteral&) { return false; }
309 };
310 static_assert(visit(Visitor(), variant<int, nonliteral>(0)), "");
311 }
312 // PR libstdc++/79513
313 {
314 std::variant<int> v [[gnu::unused]] (5);
315 std::visit([](int&){}, v);
316 std::visit([](int&&){}, std::move(v));
317 }
318 }
319
test_constexpr()320 void test_constexpr()
321 {
322 constexpr variant<int> a;
323 static_assert(holds_alternative<int>(a), "");
324 constexpr variant<int, char> b(in_place_index<0>, int{});
325 static_assert(holds_alternative<int>(b), "");
326 constexpr variant<int, char> c(in_place_type<int>, int{});
327 static_assert(holds_alternative<int>(c), "");
328 constexpr variant<int, char> d(in_place_index<1>, char{});
329 static_assert(holds_alternative<char>(d), "");
330 constexpr variant<int, char> e(in_place_type<char>, char{});
331 static_assert(holds_alternative<char>(e), "");
332 constexpr variant<int, char> f(char{});
333 static_assert(holds_alternative<char>(f), "");
334
335 {
336 struct literal {
337 constexpr literal() = default;
338 };
339
340 constexpr variant<literal, nonliteral> v{};
341 constexpr variant<literal, nonliteral> v1{in_place_type<literal>};
342 constexpr variant<literal, nonliteral> v2{in_place_index<0>};
343 }
344
345 {
346 constexpr variant<int> a(42);
347 static_assert(get<0>(a) == 42, "");
348 }
349 {
350 constexpr variant<int, nonliteral> a(42);
351 static_assert(get<0>(a) == 42, "");
352 }
353 {
354 constexpr variant<nonliteral, int> a(42);
355 static_assert(get<1>(a) == 42, "");
356 }
357 {
358 constexpr variant<int> a(42);
359 static_assert(get<int>(a) == 42, "");
360 }
361 {
362 constexpr variant<int, nonliteral> a(42);
363 static_assert(get<int>(a) == 42, "");
364 }
365 {
366 constexpr variant<nonliteral, int> a(42);
367 static_assert(get<int>(a) == 42, "");
368 }
369 {
370 constexpr variant<int> a(42);
371 static_assert(get<0>(std::move(a)) == 42, "");
372 }
373 {
374 constexpr variant<int, nonliteral> a(42);
375 static_assert(get<0>(std::move(a)) == 42, "");
376 }
377 {
378 constexpr variant<nonliteral, int> a(42);
379 static_assert(get<1>(std::move(a)) == 42, "");
380 }
381 {
382 constexpr variant<int> a(42);
383 static_assert(get<int>(std::move(a)) == 42, "");
384 }
385 {
386 constexpr variant<int, nonliteral> a(42);
387 static_assert(get<int>(std::move(a)) == 42, "");
388 }
389 {
390 constexpr variant<nonliteral, int> a(42);
391 static_assert(get<int>(std::move(a)) == 42, "");
392 }
393 }
394
test_pr77641()395 void test_pr77641()
396 {
397 struct X {
398 constexpr X() { }
399 };
400
401 constexpr std::variant<X> v1 = X{};
402 }
403
404 namespace adl_trap
405 {
406 struct X {
407 X() = default;
Xadl_trap::X408 X(int) { }
Xadl_trap::X409 X(std::initializer_list<int>, const X&) { }
410 };
move(T &)411 template<typename T> void move(T&) { }
forward(T &)412 template<typename T> void forward(T&) { }
413
414 struct Visitor {
operator ()adl_trap::Visitor415 template<typename T> void operator()(T&&) { }
416 };
417 }
418
test_adl()419 void test_adl()
420 {
421 using adl_trap::X;
422 X x;
423 std::initializer_list<int> il;
424 adl_trap::Visitor vis;
425
426 std::variant<X> v0(x);
427 v0 = x;
428 v0.emplace<0>(x);
429 v0.emplace<0>(il, x);
430 visit(vis, v0);
431 variant<X> v1{in_place_index<0>, x};
432 variant<X> v2{in_place_type<X>, x};
433 variant<X> v3{in_place_index<0>, il, x};
434 variant<X> v4{in_place_type<X>, il, x};
435 }
436
test_variant_alternative()437 void test_variant_alternative()
438 {
439 static_assert(is_same_v<variant_alternative_t<0, variant<int, string>>, int>, "");
440 static_assert(is_same_v<variant_alternative_t<1, variant<int, string>>, string>, "");
441
442 static_assert(is_same_v<variant_alternative_t<0, const variant<int>>, const int>, "");
443 static_assert(is_same_v<variant_alternative_t<0, volatile variant<int>>, volatile int>, "");
444 static_assert(is_same_v<variant_alternative_t<0, const volatile variant<int>>, const volatile int>, "");
445 }
446
447 template<typename V, typename T>
has_type_emplace(int)448 constexpr auto has_type_emplace(int) -> decltype((declval<V>().template emplace<T>(), true))
449 { return true; };
450
451 template<typename V, typename T>
has_type_emplace(...)452 constexpr bool has_type_emplace(...)
453 { return false; };
454
455 template<typename V, size_t N>
has_index_emplace(int)456 constexpr auto has_index_emplace(int) -> decltype((declval<V>().template emplace<N>(), true))
457 { return true; };
458
459 template<typename V, size_t T>
has_index_emplace(...)460 constexpr bool has_index_emplace(...)
461 { return false; };
462
test_emplace()463 void test_emplace()
464 {
465 static_assert(has_type_emplace<variant<int>, int>(0), "");
466 static_assert(!has_type_emplace<variant<long>, int>(0), "");
467 static_assert(has_index_emplace<variant<int>, 0>(0), "");
468 static_assert(!has_type_emplace<variant<AllDeleted>, AllDeleted>(0), "");
469 static_assert(!has_index_emplace<variant<AllDeleted>, 0>(0), "");
470 }
471
test_triviality()472 void test_triviality()
473 {
474 #define TEST_TEMPLATE(DT, CC, MC, CA, MA, CC_VAL, MC_VAL, CA_VAL, MA_VAL) \
475 { \
476 struct A \
477 { \
478 ~A() DT; \
479 A(const A&) CC; \
480 A(A&&) MC; \
481 A& operator=(const A&) CA; \
482 A& operator=(A&&) MA; \
483 }; \
484 static_assert(CC_VAL == is_trivially_copy_constructible_v<variant<A>>, ""); \
485 static_assert(MC_VAL == is_trivially_move_constructible_v<variant<A>>, ""); \
486 static_assert(CA_VAL == is_trivially_copy_assignable_v<variant<A>>, ""); \
487 static_assert(MA_VAL == is_trivially_move_assignable_v<variant<A>>, ""); \
488 }
489 TEST_TEMPLATE(=default, =default, =default, =default, =default, true, true, true, true)
490 TEST_TEMPLATE(=default, =default, =default, =default, , true, true, true, false)
491 TEST_TEMPLATE(=default, =default, =default, , =default, true, true, false, true)
492 TEST_TEMPLATE(=default, =default, =default, , , true, true, false, false)
493 TEST_TEMPLATE(=default, =default, , =default, =default, true, false, true, true)
494 TEST_TEMPLATE(=default, =default, , =default, , true, false, true, false)
495 TEST_TEMPLATE(=default, =default, , , =default, true, false, false, true)
496 TEST_TEMPLATE(=default, =default, , , , true, false, false, false)
497 TEST_TEMPLATE(=default, , =default, =default, =default, false, true, true, true)
498 TEST_TEMPLATE(=default, , =default, =default, , false, true, true, false)
499 TEST_TEMPLATE(=default, , =default, , =default, false, true, false, true)
500 TEST_TEMPLATE(=default, , =default, , , false, true, false, false)
501 TEST_TEMPLATE(=default, , , =default, =default, false, false, true, true)
502 TEST_TEMPLATE(=default, , , =default, , false, false, true, false)
503 TEST_TEMPLATE(=default, , , , =default, false, false, false, true)
504 TEST_TEMPLATE(=default, , , , , false, false, false, false)
505 TEST_TEMPLATE( , =default, =default, =default, =default, false, false, false, false)
506 TEST_TEMPLATE( , =default, =default, =default, , false, false, false, false)
507 TEST_TEMPLATE( , =default, =default, , =default, false, false, false, false)
508 TEST_TEMPLATE( , =default, =default, , , false, false, false, false)
509 TEST_TEMPLATE( , =default, , =default, =default, false, false, false, false)
510 TEST_TEMPLATE( , =default, , =default, , false, false, false, false)
511 TEST_TEMPLATE( , =default, , , =default, false, false, false, false)
512 TEST_TEMPLATE( , =default, , , , false, false, false, false)
513 TEST_TEMPLATE( , , =default, =default, =default, false, false, false, false)
514 TEST_TEMPLATE( , , =default, =default, , false, false, false, false)
515 TEST_TEMPLATE( , , =default, , =default, false, false, false, false)
516 TEST_TEMPLATE( , , =default, , , false, false, false, false)
517 TEST_TEMPLATE( , , , =default, =default, false, false, false, false)
518 TEST_TEMPLATE( , , , =default, , false, false, false, false)
519 TEST_TEMPLATE( , , , , =default, false, false, false, false)
520 TEST_TEMPLATE( , , , , , false, false, false, false)
521 #undef TEST_TEMPLATE
522
523 #define TEST_TEMPLATE(CC, MC, CA, MA) \
524 { \
525 struct A \
526 { \
527 A(const A&) CC; \
528 A(A&&) MC; \
529 A& operator=(const A&) CA; \
530 A& operator=(A&&) MA; \
531 }; \
532 static_assert(!is_trivially_copy_constructible_v<variant<AllDeleted, A>>, ""); \
533 static_assert(!is_trivially_move_constructible_v<variant<AllDeleted, A>>, ""); \
534 static_assert(!is_trivially_copy_assignable_v<variant<AllDeleted, A>>, ""); \
535 static_assert(!is_trivially_move_assignable_v<variant<AllDeleted, A>>, ""); \
536 }
537 TEST_TEMPLATE(=default, =default, =default, =default)
538 TEST_TEMPLATE(=default, =default, =default, )
539 TEST_TEMPLATE(=default, =default, , =default)
540 TEST_TEMPLATE(=default, =default, , )
541 TEST_TEMPLATE(=default, , =default, =default)
542 TEST_TEMPLATE(=default, , =default, )
543 TEST_TEMPLATE(=default, , , =default)
544 TEST_TEMPLATE(=default, , , )
545 TEST_TEMPLATE( , =default, =default, =default)
546 TEST_TEMPLATE( , =default, =default, )
547 TEST_TEMPLATE( , =default, , =default)
548 TEST_TEMPLATE( , =default, , )
549 TEST_TEMPLATE( , , =default, =default)
550 TEST_TEMPLATE( , , =default, )
551 TEST_TEMPLATE( , , , =default)
552 TEST_TEMPLATE( , , , )
553 #undef TEST_TEMPLATE
554
555 static_assert(is_trivially_copy_constructible_v<variant<DefaultNoexcept, int, char, float, double>>, "");
556 static_assert(is_trivially_move_constructible_v<variant<DefaultNoexcept, int, char, float, double>>, "");
557 static_assert(is_trivially_copy_assignable_v<variant<DefaultNoexcept, int, char, float, double>>, "");
558 static_assert(is_trivially_move_assignable_v<variant<DefaultNoexcept, int, char, float, double>>, "");
559 }
560