]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/20_util/variant/compile.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 20_util / variant / compile.cc
1 // { dg-do compile { target c++17 } }
2
3 // Copyright (C) 2016-2022 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING3. If not see
18 // <http://www.gnu.org/licenses/>.
19
20 #include <variant>
21 #include <string>
22 #include <vector>
23
24 using namespace std;
25
26 struct AllDeleted
27 {
28 AllDeleted() = delete;
29 AllDeleted(const AllDeleted&) = delete;
30 AllDeleted(AllDeleted&&) = delete;
31 AllDeleted& operator=(const AllDeleted&) = delete;
32 AllDeleted& operator=(AllDeleted&&) = delete;
33 };
34
35 struct Empty
36 {
37 Empty() { };
38 Empty(const Empty&) { };
39 Empty(Empty&&) { };
40 Empty& operator=(const Empty&) { return *this; };
41 Empty& operator=(Empty&&) { return *this; };
42 };
43
44 struct DefaultNoexcept
45 {
46 DefaultNoexcept() noexcept = default;
47 DefaultNoexcept(const DefaultNoexcept&) noexcept = default;
48 DefaultNoexcept(DefaultNoexcept&&) noexcept = default;
49 DefaultNoexcept& operator=(const DefaultNoexcept&) noexcept = default;
50 DefaultNoexcept& operator=(DefaultNoexcept&&) noexcept = default;
51 };
52
53 struct MoveCtorOnly
54 {
55 MoveCtorOnly() noexcept = delete;
56 MoveCtorOnly(const MoveCtorOnly&) noexcept = delete;
57 MoveCtorOnly(MoveCtorOnly&&) noexcept { }
58 MoveCtorOnly& operator=(const MoveCtorOnly&) noexcept = delete;
59 MoveCtorOnly& operator=(MoveCtorOnly&&) noexcept = delete;
60 };
61
62 struct MoveCtorAndSwapOnly : MoveCtorOnly { };
63 void swap(MoveCtorAndSwapOnly&, MoveCtorAndSwapOnly&) { }
64
65 struct DeletedMoves
66 {
67 DeletedMoves() = default;
68 DeletedMoves(const DeletedMoves&) = default;
69 DeletedMoves(DeletedMoves&&) = delete;
70 DeletedMoves& operator=(const DeletedMoves&) = default;
71 DeletedMoves& operator=(DeletedMoves&&) = delete;
72 };
73
74 struct nonliteral
75 {
76 nonliteral() { }
77
78 bool operator<(const nonliteral&) const;
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 };
85
86 struct virtual_default_dtor {
87 virtual ~virtual_default_dtor() = default;
88 };
89
90 void default_ctor()
91 {
92 static_assert(is_default_constructible_v<variant<int, string>>);
93 static_assert(is_default_constructible_v<variant<string, string>>);
94 static_assert(!is_default_constructible_v<variant<AllDeleted, string>>);
95 static_assert(is_default_constructible_v<variant<string, AllDeleted>>);
96 static_assert(is_default_constructible_v<variant<DeletedMoves>>);
97
98 static_assert(noexcept(variant<int>()));
99 static_assert(!noexcept(variant<Empty>()));
100 static_assert(noexcept(variant<DefaultNoexcept>()));
101 {
102 variant<virtual_default_dtor> a;
103 }
104 }
105
106 void copy_ctor()
107 {
108 static_assert(is_copy_constructible_v<variant<int, string>>);
109 static_assert(!is_copy_constructible_v<variant<AllDeleted, string>>);
110 static_assert(is_trivially_copy_constructible_v<variant<int>>);
111 static_assert(!is_trivially_copy_constructible_v<variant<std::string>>);
112 static_assert(is_trivially_copy_constructible_v<variant<DeletedMoves>>);
113
114 {
115 variant<int> a;
116 static_assert(noexcept(variant<int>(a)));
117 }
118 {
119 variant<string> a;
120 static_assert(!noexcept(variant<string>(a)));
121 }
122 {
123 variant<int, string> a;
124 static_assert(!noexcept(variant<int, string>(a)));
125 }
126 {
127 variant<int, char> a;
128 static_assert(noexcept(variant<int, char>(a)));
129 }
130 }
131
132 void move_ctor()
133 {
134 static_assert(is_move_constructible_v<variant<int, string>>);
135 static_assert(!is_move_constructible_v<variant<AllDeleted, string>>);
136 static_assert(is_move_constructible_v<variant<int, DeletedMoves>>); // uses copy ctor
137 static_assert(is_trivially_move_constructible_v<variant<int>>);
138 static_assert(!is_trivially_move_constructible_v<variant<std::string>>);
139 static_assert(!noexcept(variant<int, Empty>(declval<variant<int, Empty>>())));
140 static_assert(noexcept(variant<int, DefaultNoexcept>(declval<variant<int, DefaultNoexcept>>())));
141 }
142
143 void arbitrary_ctor()
144 {
145 static_assert(!is_constructible_v<variant<string, string>, const char*>);
146 static_assert(is_constructible_v<variant<int, string>, const char*>);
147 static_assert(noexcept(variant<int, Empty>(int{})));
148 static_assert(noexcept(variant<int, DefaultNoexcept>(int{})));
149 static_assert(!noexcept(variant<int, Empty>(Empty{})));
150 static_assert(noexcept(variant<int, DefaultNoexcept>(DefaultNoexcept{})));
151
152 // P0608R3 disallow narrowing conversions and boolean conversions
153 static_assert(!is_constructible_v<variant<float>, int>);
154 static_assert(!is_constructible_v<variant<float, vector<int>>, int>);
155 static_assert(is_constructible_v<variant<float, int>, char>);
156 static_assert(!is_constructible_v<variant<float, char>, int>);
157 static_assert(is_constructible_v<variant<float, long>, int>);
158 struct big_int { big_int(int) { } };
159 static_assert(is_constructible_v<variant<float, big_int>, int>);
160
161 static_assert(!is_constructible_v<variant<int>, unsigned>);
162 static_assert(!is_constructible_v<variant<bool>, int>);
163 static_assert(!is_constructible_v<variant<bool>, void*>);
164
165 // P1957R2 Converting from T* to bool should be considered narrowing
166 struct ConvertibleToBool
167 {
168 operator bool() const { return true; }
169 };
170 static_assert(is_constructible_v<variant<bool>, ConvertibleToBool>);
171 static_assert(is_constructible_v<variant<bool, int>, ConvertibleToBool>);
172 }
173
174 struct None { None() = delete; };
175 struct Any { template <typename T> Any(T&&) {} };
176
177 void in_place_index_ctor()
178 {
179 variant<string, string> a(in_place_index<0>, "a");
180 variant<string, string> b(in_place_index<1>, {'a'});
181
182 static_assert(!is_constructible_v<variant<None, Any>, std::in_place_index_t<0>>, "PR libstdc++/90165");
183 }
184
185 void in_place_type_ctor()
186 {
187 variant<int, string, int> a(in_place_type<string>, "a");
188 variant<int, string, int> b(in_place_type<string>, {'a'});
189 static_assert(!is_constructible_v<variant<string, string>, in_place_type_t<string>, const char*>);
190 static_assert(!is_constructible_v<variant<None, Any>, std::in_place_type_t<None>>, "PR libstdc++/90165");
191 }
192
193 void dtor()
194 {
195 static_assert(is_destructible_v<variant<int, string>>);
196 static_assert(is_destructible_v<variant<AllDeleted, string>>);
197 }
198
199 void copy_assign()
200 {
201 static_assert(is_copy_assignable_v<variant<int, string>>);
202 static_assert(!is_copy_assignable_v<variant<AllDeleted, string>>);
203 static_assert(is_trivially_copy_assignable_v<variant<int>>);
204 static_assert(!is_trivially_copy_assignable_v<variant<string>>);
205 static_assert(is_trivially_copy_assignable_v<variant<DeletedMoves>>);
206 {
207 variant<Empty> a;
208 static_assert(!noexcept(a = a));
209 }
210 {
211 variant<DefaultNoexcept> a;
212 static_assert(noexcept(a = a));
213 }
214 }
215
216 void move_assign()
217 {
218 static_assert(is_move_assignable_v<variant<int, string>>);
219 static_assert(!is_move_assignable_v<variant<AllDeleted, string>>);
220 static_assert(is_move_assignable_v<variant<int, DeletedMoves>>); // uses copy assignment
221 static_assert(is_trivially_move_assignable_v<variant<int>>);
222 static_assert(!is_trivially_move_assignable_v<variant<string>>);
223 {
224 variant<Empty> a;
225 static_assert(!noexcept(a = std::move(a)));
226 }
227 {
228 variant<DefaultNoexcept> a;
229 static_assert(noexcept(a = std::move(a)));
230 }
231 }
232
233 void arbitrary_assign()
234 {
235 static_assert(!is_assignable_v<variant<string, string>, const char*>);
236 static_assert(is_assignable_v<variant<int, string>, const char*>);
237 static_assert(noexcept(variant<int, Empty>() = int{}));
238 static_assert(noexcept(variant<int, DefaultNoexcept>() = int{}));
239 static_assert(!noexcept(variant<int, Empty>() = Empty{}));
240 static_assert(noexcept(variant<int, DefaultNoexcept>() = DefaultNoexcept{}));
241 }
242
243 void test_get()
244 {
245 static_assert(is_same<decltype(get<0>(variant<int, string>())), int&&>::value);
246 static_assert(is_same<decltype(get<1>(variant<int, string>())), string&&>::value);
247 static_assert(is_same<decltype(get<1>(variant<int, const string>())), const string&&>::value);
248
249 static_assert(is_same<decltype(get<int>(variant<int, string>())), int&&>::value);
250 static_assert(is_same<decltype(get<string>(variant<int, string>())), string&&>::value);
251 static_assert(is_same<decltype(get<const string>(variant<int, const string>())), const string&&>::value);
252 }
253
254 void test_relational()
255 {
256 {
257 constexpr variant<int, nonliteral> a(42), b(43);
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 constexpr variant<int, nonliteral> a(42), b(42);
267 static_assert(!(a < b));
268 static_assert(!(a > b));
269 static_assert((a <= b));
270 static_assert((a == b));
271 static_assert(!(a != b));
272 static_assert((a >= b));
273 }
274 {
275 constexpr variant<int, nonliteral> a(43), b(42);
276 static_assert(!(a < b));
277 static_assert((a > b));
278 static_assert(!(a <= b));
279 static_assert(!(a == b));
280 static_assert((a != b));
281 static_assert((a >= b));
282 }
283 {
284 constexpr monostate a, b;
285 static_assert(!(a < b));
286 static_assert(!(a > b));
287 static_assert((a <= b));
288 static_assert((a == b));
289 static_assert(!(a != b));
290 static_assert((a >= b));
291 }
292 }
293
294 // Not swappable, and variant<C> not swappable via the generic std::swap.
295 struct C { };
296 void swap(C&, C&) = delete;
297
298 static_assert( !std::is_swappable_v<variant<C>> );
299 static_assert( !std::is_swappable_v<variant<int, C>> );
300 static_assert( !std::is_swappable_v<variant<C, int>> );
301
302 // Not swappable, and variant<D> not swappable via the generic std::swap.
303 struct D { D(D&&) = delete; };
304
305 static_assert( !std::is_swappable_v<variant<D>> );
306 static_assert( !std::is_swappable_v<variant<int, D>> );
307 static_assert( !std::is_swappable_v<variant<D, int>> );
308
309 void test_swap()
310 {
311 static_assert(is_swappable_v<variant<int, string>>);
312 static_assert(!is_swappable_v<variant<MoveCtorOnly>>);
313 static_assert(is_swappable_v<variant<MoveCtorAndSwapOnly>>);
314 static_assert(!is_swappable_v<variant<AllDeleted>>);
315 }
316
317 void test_visit()
318 {
319 {
320 struct Visitor
321 {
322 void operator()(monostate) {}
323 void operator()(const int&) {}
324 };
325 struct CVisitor
326 {
327 void operator()(monostate) const {}
328 void operator()(const int&) const {}
329 };
330 }
331 {
332 struct Visitor
333 {
334 bool operator()(int, float) { return false; }
335 bool operator()(int, double) { return false; }
336 bool operator()(char, float) { return false; }
337 bool operator()(char, double) { return false; }
338 };
339 visit(Visitor(), variant<int, char>(), variant<float, double>());
340 }
341 {
342 struct Visitor
343 {
344 constexpr bool operator()(const int&) { return true; }
345 constexpr bool operator()(const nonliteral&) { return false; }
346 };
347 static_assert(visit(Visitor(), variant<int, nonliteral>(0)));
348 }
349 {
350 struct Visitor
351 {
352 constexpr bool operator()(const int&) { return true; }
353 constexpr bool operator()(const nonliteral&) { return false; }
354 };
355 static_assert(visit(Visitor(), variant<int, nonliteral>(0)));
356 }
357 // PR libstdc++/79513
358 {
359 std::variant<int> v [[gnu::unused]] (5);
360 std::visit([](int&){}, v);
361 std::visit([](int&&){}, std::move(v));
362 }
363 }
364
365 void test_constexpr()
366 {
367 constexpr variant<int> a;
368 static_assert(holds_alternative<int>(a));
369 constexpr variant<int, char> b(in_place_index<0>, int{});
370 static_assert(holds_alternative<int>(b));
371 constexpr variant<int, char> c(in_place_type<int>, int{});
372 static_assert(holds_alternative<int>(c));
373 constexpr variant<int, char> d(in_place_index<1>, char{});
374 static_assert(holds_alternative<char>(d));
375 constexpr variant<int, char> e(in_place_type<char>, char{});
376 static_assert(holds_alternative<char>(e));
377 constexpr variant<int, char> f(char{});
378 static_assert(holds_alternative<char>(f));
379
380 {
381 struct literal {
382 constexpr literal() = default;
383 };
384
385 constexpr variant<literal, nonliteral> v{};
386 constexpr variant<literal, nonliteral> v1{in_place_type<literal>};
387 constexpr variant<literal, nonliteral> v2{in_place_index<0>};
388 }
389
390 {
391 constexpr variant<int> a(42);
392 static_assert(get<0>(a) == 42);
393 }
394 {
395 constexpr variant<int, nonliteral> a(42);
396 static_assert(get<0>(a) == 42);
397 }
398 {
399 constexpr variant<nonliteral, int> a(42);
400 static_assert(get<1>(a) == 42);
401 }
402 {
403 constexpr variant<int> a(42);
404 static_assert(get<int>(a) == 42);
405 }
406 {
407 constexpr variant<int, nonliteral> a(42);
408 static_assert(get<int>(a) == 42);
409 }
410 {
411 constexpr variant<nonliteral, int> a(42);
412 static_assert(get<int>(a) == 42);
413 }
414 {
415 constexpr variant<int> a(42);
416 static_assert(get<0>(std::move(a)) == 42);
417 }
418 {
419 constexpr variant<int, nonliteral> a(42);
420 static_assert(get<0>(std::move(a)) == 42);
421 }
422 {
423 constexpr variant<nonliteral, int> a(42);
424 static_assert(get<1>(std::move(a)) == 42);
425 }
426 {
427 constexpr variant<int> a(42);
428 static_assert(get<int>(std::move(a)) == 42);
429 }
430 {
431 constexpr variant<int, nonliteral> a(42);
432 static_assert(get<int>(std::move(a)) == 42);
433 }
434 {
435 constexpr variant<nonliteral, int> a(42);
436 static_assert(get<int>(std::move(a)) == 42);
437 }
438 }
439
440 void test_pr77641()
441 {
442 struct X {
443 constexpr X() { }
444 };
445
446 constexpr std::variant<X> v1 = X{};
447 }
448
449 namespace adl_trap
450 {
451 struct X {
452 X() = default;
453 X(int) { }
454 X(std::initializer_list<int>, const X&) { }
455 };
456 template<typename T> void move(T&) { }
457 template<typename T> void forward(T&) { }
458
459 struct Visitor {
460 template<typename T> void operator()(T&&) { }
461 };
462 }
463
464 void test_adl()
465 {
466 using adl_trap::X;
467 X x;
468 std::initializer_list<int> il;
469 adl_trap::Visitor vis;
470
471 std::variant<X> v0(x);
472 v0 = x;
473 v0.emplace<0>(x);
474 v0.emplace<0>(il, x);
475 visit(vis, v0);
476 variant<X> v1{in_place_index<0>, x};
477 variant<X> v2{in_place_type<X>, x};
478 variant<X> v3{in_place_index<0>, il, x};
479 variant<X> v4{in_place_type<X>, il, x};
480 }
481
482 void test_variant_alternative()
483 {
484 static_assert(is_same_v<variant_alternative_t<0, variant<int, string>>, int>);
485 static_assert(is_same_v<variant_alternative_t<1, variant<int, string>>, string>);
486
487 static_assert(is_same_v<variant_alternative_t<0, const variant<int>>, const int>);
488 static_assert(is_same_v<variant_alternative_t<0, volatile variant<int>>, volatile int>);
489 static_assert(is_same_v<variant_alternative_t<0, const volatile variant<int>>, const volatile int>);
490 }
491
492 template<typename V, typename T>
493 constexpr auto has_type_emplace(int) -> decltype((declval<V>().template emplace<T>(), true))
494 { return true; };
495
496 template<typename V, typename T>
497 constexpr bool has_type_emplace(...)
498 { return false; };
499
500 template<typename V, size_t N>
501 constexpr auto has_index_emplace(int) -> decltype((declval<V>().template emplace<N>(), true))
502 { return true; };
503
504 template<typename V, size_t T>
505 constexpr bool has_index_emplace(...)
506 { return false; };
507
508 void test_emplace()
509 {
510 static_assert(has_type_emplace<variant<int>, int>(0));
511 static_assert(!has_type_emplace<variant<long>, int>(0));
512 static_assert(has_index_emplace<variant<int>, 0>(0));
513 static_assert(!has_type_emplace<variant<AllDeleted>, AllDeleted>(0));
514 static_assert(!has_index_emplace<variant<AllDeleted>, 0>(0));
515 static_assert(has_type_emplace<variant<int, AllDeleted>, int>(0));
516 static_assert(has_index_emplace<variant<int, AllDeleted>, 0>(0));
517 static_assert(has_type_emplace<variant<int, vector<int>, AllDeleted>, vector<int>>(0));
518 static_assert(has_index_emplace<variant<int, vector<int>, AllDeleted>, 1>(0));
519
520 // The above tests only check the emplace members are available for
521 // overload resolution. The following odr-uses will instantiate them:
522 variant<int, vector<int>, AllDeleted> v;
523 v.emplace<0>(1);
524 v.emplace<int>(1);
525 v.emplace<1>(1, 1);
526 v.emplace<vector<int>>(1, 1);
527 v.emplace<1>({1, 2, 3, 4});
528 v.emplace<vector<int>>({1, 2, 3, 4});
529 }
530
531 void test_triviality()
532 {
533 #define TEST_TEMPLATE(DT, CC, MC, CA, MA, CC_VAL, MC_VAL, CA_VAL, MA_VAL) \
534 { \
535 struct A \
536 { \
537 ~A() DT; \
538 A(const A&) CC; \
539 A(A&&) MC; \
540 A& operator=(const A&) CA; \
541 A& operator=(A&&) MA; \
542 }; \
543 static_assert(CC_VAL == is_trivially_copy_constructible_v<variant<A>>); \
544 static_assert(MC_VAL == is_trivially_move_constructible_v<variant<A>>); \
545 static_assert(CA_VAL == is_trivially_copy_assignable_v<variant<A>>); \
546 static_assert(MA_VAL == is_trivially_move_assignable_v<variant<A>>); \
547 }
548 TEST_TEMPLATE(=default, =default, =default, =default, =default, true, true, true, true)
549 TEST_TEMPLATE(=default, =default, =default, =default, , true, true, true, false)
550 TEST_TEMPLATE(=default, =default, =default, , =default, true, true, false, true)
551 TEST_TEMPLATE(=default, =default, =default, , , true, true, false, false)
552 TEST_TEMPLATE(=default, =default, , =default, =default, true, false, true, false)
553 TEST_TEMPLATE(=default, =default, , =default, , true, false, true, false)
554 TEST_TEMPLATE(=default, =default, , , =default, true, false, false, false)
555 TEST_TEMPLATE(=default, =default, , , , true, false, false, false)
556 TEST_TEMPLATE(=default, , =default, =default, =default, false, true, false, true)
557 TEST_TEMPLATE(=default, , =default, =default, , false, true, false, false)
558 TEST_TEMPLATE(=default, , =default, , =default, false, true, false, true)
559 TEST_TEMPLATE(=default, , =default, , , false, true, false, false)
560 TEST_TEMPLATE(=default, , , =default, =default, false, false, false, false)
561 TEST_TEMPLATE(=default, , , =default, , false, false, false, false)
562 TEST_TEMPLATE(=default, , , , =default, false, false, false, false)
563 TEST_TEMPLATE(=default, , , , , false, false, false, false)
564 TEST_TEMPLATE( , =default, =default, =default, =default, false, false, false, false)
565 TEST_TEMPLATE( , =default, =default, =default, , false, false, false, false)
566 TEST_TEMPLATE( , =default, =default, , =default, false, false, false, false)
567 TEST_TEMPLATE( , =default, =default, , , false, false, false, false)
568 TEST_TEMPLATE( , =default, , =default, =default, false, false, false, false)
569 TEST_TEMPLATE( , =default, , =default, , false, false, false, false)
570 TEST_TEMPLATE( , =default, , , =default, false, false, false, false)
571 TEST_TEMPLATE( , =default, , , , false, false, false, false)
572 TEST_TEMPLATE( , , =default, =default, =default, false, false, false, false)
573 TEST_TEMPLATE( , , =default, =default, , false, false, false, false)
574 TEST_TEMPLATE( , , =default, , =default, false, false, false, false)
575 TEST_TEMPLATE( , , =default, , , false, false, false, false)
576 TEST_TEMPLATE( , , , =default, =default, false, false, false, false)
577 TEST_TEMPLATE( , , , =default, , false, false, false, false)
578 TEST_TEMPLATE( , , , , =default, false, false, false, false)
579 TEST_TEMPLATE( , , , , , false, false, false, false)
580 #undef TEST_TEMPLATE
581
582 #define TEST_TEMPLATE(CC, MC, CA, MA) \
583 { \
584 struct A \
585 { \
586 A(const A&) CC; \
587 A(A&&) MC; \
588 A& operator=(const A&) CA; \
589 A& operator=(A&&) MA; \
590 }; \
591 static_assert(!is_trivially_copy_constructible_v<variant<AllDeleted, A>>); \
592 static_assert(!is_trivially_move_constructible_v<variant<AllDeleted, A>>); \
593 static_assert(!is_trivially_copy_assignable_v<variant<AllDeleted, A>>); \
594 static_assert(!is_trivially_move_assignable_v<variant<AllDeleted, A>>); \
595 }
596 TEST_TEMPLATE(=default, =default, =default, =default)
597 TEST_TEMPLATE(=default, =default, =default, )
598 TEST_TEMPLATE(=default, =default, , =default)
599 TEST_TEMPLATE(=default, =default, , )
600 TEST_TEMPLATE(=default, , =default, =default)
601 TEST_TEMPLATE(=default, , =default, )
602 TEST_TEMPLATE(=default, , , =default)
603 TEST_TEMPLATE(=default, , , )
604 TEST_TEMPLATE( , =default, =default, =default)
605 TEST_TEMPLATE( , =default, =default, )
606 TEST_TEMPLATE( , =default, , =default)
607 TEST_TEMPLATE( , =default, , )
608 TEST_TEMPLATE( , , =default, =default)
609 TEST_TEMPLATE( , , =default, )
610 TEST_TEMPLATE( , , , =default)
611 TEST_TEMPLATE( , , , )
612 #undef TEST_TEMPLATE
613
614 static_assert(is_trivially_copy_constructible_v<variant<DefaultNoexcept, int, char, float, double>>);
615 static_assert(is_trivially_move_constructible_v<variant<DefaultNoexcept, int, char, float, double>>);
616 static_assert(is_trivially_copy_assignable_v<variant<DefaultNoexcept, int, char, float, double>>);
617 static_assert(is_trivially_move_assignable_v<variant<DefaultNoexcept, int, char, float, double>>);
618 }