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