1 // { dg-do compile { target c++17 } }
3 // Copyright (C) 2016-2022 Free Software Foundation, Inc.
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)
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.
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/>.
28 AllDeleted() = delete;
29 AllDeleted(const AllDeleted
&) = delete;
30 AllDeleted(AllDeleted
&&) = delete;
31 AllDeleted
& operator=(const AllDeleted
&) = delete;
32 AllDeleted
& operator=(AllDeleted
&&) = delete;
38 Empty(const Empty
&) { };
40 Empty
& operator=(const Empty
&) { return *this; };
41 Empty
& operator=(Empty
&&) { return *this; };
44 struct DefaultNoexcept
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;
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;
62 struct MoveCtorAndSwapOnly
: MoveCtorOnly
{ };
63 void swap(MoveCtorAndSwapOnly
&, MoveCtorAndSwapOnly
&) { }
67 DeletedMoves() = default;
68 DeletedMoves(const DeletedMoves
&) = default;
69 DeletedMoves(DeletedMoves
&&) = delete;
70 DeletedMoves
& operator=(const DeletedMoves
&) = default;
71 DeletedMoves
& operator=(DeletedMoves
&&) = delete;
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;
86 struct virtual_default_dtor
{
87 virtual ~virtual_default_dtor() = default;
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
>>);
98 static_assert(noexcept(variant
<int>()));
99 static_assert(!noexcept(variant
<Empty
>()));
100 static_assert(noexcept(variant
<DefaultNoexcept
>()));
102 variant
<virtual_default_dtor
> a
;
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
>>);
116 static_assert(noexcept(variant
<int>(a
)));
120 static_assert(!noexcept(variant
<string
>(a
)));
123 variant
<int, string
> a
;
124 static_assert(!noexcept(variant
<int, string
>(a
)));
127 variant
<int, char> a
;
128 static_assert(noexcept(variant
<int, char>(a
)));
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
>>())));
143 void arbitrary_ctor()
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
{})));
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>);
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*>);
165 // P1957R2 Converting from T* to bool should be considered narrowing
166 struct ConvertibleToBool
168 operator bool() const { return true; }
170 static_assert(is_constructible_v
<variant
<bool>, ConvertibleToBool
>);
171 static_assert(is_constructible_v
<variant
<bool, int>, ConvertibleToBool
>);
174 struct None
{ None() = delete; };
175 struct Any
{ template <typename T
> Any(T
&&) {} };
177 void in_place_index_ctor()
179 variant
<string
, string
> a(in_place_index
<0>, "a");
180 variant
<string
, string
> b(in_place_index
<1>, {'a'});
182 static_assert(!is_constructible_v
<variant
<None
, Any
>, std::in_place_index_t
<0>>, "PR libstdc++/90165");
185 void in_place_type_ctor()
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");
195 static_assert(is_destructible_v
<variant
<int, string
>>);
196 static_assert(is_destructible_v
<variant
<AllDeleted
, string
>>);
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
>>);
208 static_assert(!noexcept(a
= a
));
211 variant
<DefaultNoexcept
> a
;
212 static_assert(noexcept(a
= a
));
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
>>);
225 static_assert(!noexcept(a
= std::move(a
)));
228 variant
<DefaultNoexcept
> a
;
229 static_assert(noexcept(a
= std::move(a
)));
233 void arbitrary_assign()
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
{}));
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
);
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
);
254 void test_relational()
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
));
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
));
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
));
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
));
294 // Not swappable, and variant<C> not swappable via the generic std::swap.
296 void swap(C
&, C
&) = delete;
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>> );
302 // Not swappable, and variant<D> not swappable via the generic std::swap.
303 struct D
{ D(D
&&) = delete; };
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>> );
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
>>);
322 void operator()(monostate
) {}
323 void operator()(const int&) {}
327 void operator()(monostate
) const {}
328 void operator()(const int&) const {}
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; }
339 visit(Visitor(), variant
<int, char>(), variant
<float, double>());
344 constexpr bool operator()(const int&) { return true; }
345 constexpr bool operator()(const nonliteral
&) { return false; }
347 static_assert(visit(Visitor(), variant
<int, nonliteral
>(0)));
352 constexpr bool operator()(const int&) { return true; }
353 constexpr bool operator()(const nonliteral
&) { return false; }
355 static_assert(visit(Visitor(), variant
<int, nonliteral
>(0)));
357 // PR libstdc++/79513
359 std::variant
<int> v
[[gnu::unused
]] (5);
360 std::visit([](int&){}, v
);
361 std::visit([](int&&){}, std::move(v
));
365 void test_constexpr()
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
));
382 constexpr literal() = default;
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>};
391 constexpr variant
<int> a(42);
392 static_assert(get
<0>(a
) == 42);
395 constexpr variant
<int, nonliteral
> a(42);
396 static_assert(get
<0>(a
) == 42);
399 constexpr variant
<nonliteral
, int> a(42);
400 static_assert(get
<1>(a
) == 42);
403 constexpr variant
<int> a(42);
404 static_assert(get
<int>(a
) == 42);
407 constexpr variant
<int, nonliteral
> a(42);
408 static_assert(get
<int>(a
) == 42);
411 constexpr variant
<nonliteral
, int> a(42);
412 static_assert(get
<int>(a
) == 42);
415 constexpr variant
<int> a(42);
416 static_assert(get
<0>(std::move(a
)) == 42);
419 constexpr variant
<int, nonliteral
> a(42);
420 static_assert(get
<0>(std::move(a
)) == 42);
423 constexpr variant
<nonliteral
, int> a(42);
424 static_assert(get
<1>(std::move(a
)) == 42);
427 constexpr variant
<int> a(42);
428 static_assert(get
<int>(std::move(a
)) == 42);
431 constexpr variant
<int, nonliteral
> a(42);
432 static_assert(get
<int>(std::move(a
)) == 42);
435 constexpr variant
<nonliteral
, int> a(42);
436 static_assert(get
<int>(std::move(a
)) == 42);
446 constexpr std::variant
<X
> v1
= X
{};
454 X(std::initializer_list
<int>, const X
&) { }
456 template<typename T
> void move(T
&) { }
457 template<typename T
> void forward(T
&) { }
460 template<typename T
> void operator()(T
&&) { }
468 std::initializer_list
<int> il
;
469 adl_trap::Visitor vis
;
471 std::variant
<X
> v0(x
);
474 v0
.emplace
<0>(il
, x
);
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
};
482 void test_variant_alternative()
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
>);
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>);
492 template<typename V
, typename T
>
493 constexpr auto has_type_emplace(int) -> decltype((declval
<V
>().template emplace
<T
>(), true))
496 template<typename V
, typename T
>
497 constexpr bool has_type_emplace(...)
500 template<typename V
, size_t N
>
501 constexpr auto has_index_emplace(int) -> decltype((declval
<V
>().template emplace
<N
>(), true))
504 template<typename V
, size_t T
>
505 constexpr bool has_index_emplace(...)
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));
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
;
526 v
.emplace
<vector
<int>>(1, 1);
527 v
.emplace
<1>({1, 2, 3, 4});
528 v
.emplace
<vector
<int>>({1, 2, 3, 4});
531 void test_triviality()
533 #define TEST_TEMPLATE(DT, CC, MC, CA, MA, CC_VAL, MC_VAL, CA_VAL, MA_VAL) \
540 A& operator=(const A&) CA; \
541 A& operator=(A&&) MA; \
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>>); \
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)
582 #define TEST_TEMPLATE(CC, MC, CA, MA) \
588 A& operator=(const A&) CA; \
589 A& operator=(A&&) MA; \
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>>); \
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( , , , )
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>>);