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