1 // { dg-options "-std=gnu++17" }
4 // Copyright (C) 2016-2017 Free Software Foundation, Inc.
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)
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.
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/>.
29 AllDeleted() = delete;
30 AllDeleted(const AllDeleted
&) = delete;
31 AllDeleted(AllDeleted
&&) = delete;
32 AllDeleted
& operator=(const AllDeleted
&) = delete;
33 AllDeleted
& operator=(AllDeleted
&&) = delete;
39 Empty(const Empty
&) { };
41 Empty
& operator=(const Empty
&) { return *this; };
42 Empty
& operator=(Empty
&&) { return *this; };
45 struct DefaultNoexcept
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;
56 MoveCtorOnly() noexcept
= delete;
57 MoveCtorOnly(const DefaultNoexcept
&) noexcept
= delete;
58 MoveCtorOnly(DefaultNoexcept
&&) noexcept
{ }
59 MoveCtorOnly
& operator=(const DefaultNoexcept
&) noexcept
= delete;
60 MoveCtorOnly
& operator=(DefaultNoexcept
&&) noexcept
= delete;
67 bool operator<(const nonliteral
&) const;
68 bool operator==(const nonliteral
&) const;
73 static_assert(is_default_constructible_v
<variant
<int, string
>>, "");
74 static_assert(is_default_constructible_v
<variant
<string
, string
>>, "");
75 static_assert(!is_default_constructible_v
<variant
<AllDeleted
, string
>>, "");
76 static_assert(is_default_constructible_v
<variant
<string
, AllDeleted
>>, "");
78 static_assert(noexcept(variant
<int>()), "");
79 static_assert(!noexcept(variant
<Empty
>()), "");
80 static_assert(noexcept(variant
<DefaultNoexcept
>()), "");
85 static_assert(is_copy_constructible_v
<variant
<int, string
>>, "");
86 static_assert(!is_copy_constructible_v
<variant
<AllDeleted
, string
>>, "");
90 static_assert(!noexcept(variant
<int>(a
)), "");
94 static_assert(!noexcept(variant
<string
>(a
)), "");
97 variant
<int, string
> a
;
98 static_assert(!noexcept(variant
<int, string
>(a
)), "");
101 variant
<int, char> a
;
102 static_assert(!noexcept(variant
<int, char>(a
)), "");
108 static_assert(is_move_constructible_v
<variant
<int, string
>>, "");
109 static_assert(!is_move_constructible_v
<variant
<AllDeleted
, string
>>, "");
110 static_assert(!noexcept(variant
<int, Empty
>(declval
<variant
<int, Empty
>>())), "");
111 static_assert(noexcept(variant
<int, DefaultNoexcept
>(declval
<variant
<int, DefaultNoexcept
>>())), "");
114 void arbitrary_ctor()
116 static_assert(!is_constructible_v
<variant
<string
, string
>, const char*>, "");
117 static_assert(is_constructible_v
<variant
<int, string
>, const char*>, "");
118 static_assert(noexcept(variant
<int, Empty
>(int{})), "");
119 static_assert(noexcept(variant
<int, DefaultNoexcept
>(int{})), "");
120 static_assert(!noexcept(variant
<int, Empty
>(Empty
{})), "");
121 static_assert(noexcept(variant
<int, DefaultNoexcept
>(DefaultNoexcept
{})), "");
124 void in_place_index_ctor()
126 variant
<string
, string
> a(in_place_index
<0>, "a");
127 variant
<string
, string
> b(in_place_index
<1>, {'a'});
130 void in_place_type_ctor()
132 variant
<int, string
, int> a(in_place_type
<string
>, "a");
133 variant
<int, string
, int> b(in_place_type
<string
>, {'a'});
134 static_assert(!is_constructible_v
<variant
<string
, string
>, in_place_type_t
<string
>, const char*>, "");
139 static_assert(is_destructible_v
<variant
<int, string
>>, "");
140 static_assert(is_destructible_v
<variant
<AllDeleted
, string
>>, "");
145 static_assert(is_copy_assignable_v
<variant
<int, string
>>, "");
146 static_assert(!is_copy_assignable_v
<variant
<AllDeleted
, string
>>, "");
149 static_assert(!noexcept(a
= a
), "");
152 variant
<DefaultNoexcept
> a
;
153 static_assert(!noexcept(a
= a
), "");
159 static_assert(is_move_assignable_v
<variant
<int, string
>>, "");
160 static_assert(!is_move_assignable_v
<variant
<AllDeleted
, string
>>, "");
163 static_assert(!noexcept(a
= std::move(a
)), "");
166 variant
<DefaultNoexcept
> a
;
167 static_assert(noexcept(a
= std::move(a
)), "");
171 void arbitrary_assign()
173 static_assert(!is_assignable_v
<variant
<string
, string
>, const char*>, "");
174 static_assert(is_assignable_v
<variant
<int, string
>, const char*>, "");
175 static_assert(noexcept(variant
<int, Empty
>() = int{}), "");
176 static_assert(noexcept(variant
<int, DefaultNoexcept
>() = int{}), "");
177 static_assert(!noexcept(variant
<int, Empty
>() = Empty
{}), "");
178 static_assert(noexcept(variant
<int, DefaultNoexcept
>() = DefaultNoexcept
{}), "");
183 static_assert(is_same
<decltype(get
<0>(variant
<int, string
>())), int&&>::value
, "");
184 static_assert(is_same
<decltype(get
<1>(variant
<int, string
>())), string
&&>::value
, "");
185 static_assert(is_same
<decltype(get
<1>(variant
<int, const string
>())), const string
&&>::value
, "");
187 static_assert(is_same
<decltype(get
<int>(variant
<int, string
>())), int&&>::value
, "");
188 static_assert(is_same
<decltype(get
<string
>(variant
<int, string
>())), string
&&>::value
, "");
189 static_assert(is_same
<decltype(get
<const string
>(variant
<int, const string
>())), const string
&&>::value
, "");
192 void test_relational()
195 constexpr variant
<int, nonliteral
> a(42), b(43);
196 static_assert((a
< b
), "");
197 static_assert(!(a
> b
), "");
198 static_assert((a
<= b
), "");
199 static_assert(!(a
== b
), "");
200 static_assert((a
!= b
), "");
201 static_assert(!(a
>= b
), "");
204 constexpr variant
<int, nonliteral
> a(42), b(42);
205 static_assert(!(a
< b
), "");
206 static_assert(!(a
> b
), "");
207 static_assert((a
<= b
), "");
208 static_assert((a
== b
), "");
209 static_assert(!(a
!= b
), "");
210 static_assert((a
>= b
), "");
213 constexpr variant
<int, nonliteral
> a(43), b(42);
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
), "");
222 constexpr monostate a
, b
;
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
), "");
232 // Not swappable, and variant<C> not swappable via the generic std::swap.
234 void swap(C
&, C
&) = delete;
236 static_assert( !std::is_swappable_v
<variant
<C
>> );
237 static_assert( !std::is_swappable_v
<variant
<int, C
>> );
238 static_assert( !std::is_swappable_v
<variant
<C
, int>> );
240 // Not swappable, and variant<D> not swappable via the generic std::swap.
241 struct D
{ D(D
&&) = delete; };
243 static_assert( !std::is_swappable_v
<variant
<D
>> );
244 static_assert( !std::is_swappable_v
<variant
<int, D
>> );
245 static_assert( !std::is_swappable_v
<variant
<D
, int>> );
249 static_assert(is_swappable_v
<variant
<int, string
>>, "");
250 static_assert(is_swappable_v
<variant
<MoveCtorOnly
>>, "");
251 static_assert(!is_swappable_v
<variant
<AllDeleted
>>, "");
259 void operator()(monostate
) {}
260 void operator()(const int&) {}
264 void operator()(monostate
) const {}
265 void operator()(const int&) const {}
271 bool operator()(int, float) { return false; }
272 bool operator()(int, double) { return false; }
273 bool operator()(char, float) { return false; }
274 bool operator()(char, double) { return false; }
276 visit(Visitor(), variant
<int, char>(), variant
<float, double>());
281 constexpr bool operator()(const int&) { return true; }
282 constexpr bool operator()(const nonliteral
&) { return false; }
284 static_assert(visit(Visitor(), variant
<int, nonliteral
>(0)), "");
289 constexpr bool operator()(const int&) { return true; }
290 constexpr bool operator()(const nonliteral
&) { return false; }
292 static_assert(visit(Visitor(), variant
<int, nonliteral
>(0)), "");
296 void test_constexpr()
298 constexpr variant
<int> a
;
299 static_assert(holds_alternative
<int>(a
), "");
300 constexpr variant
<int, char> b(in_place_index
<0>, int{});
301 static_assert(holds_alternative
<int>(b
), "");
302 constexpr variant
<int, char> c(in_place_type
<int>, int{});
303 static_assert(holds_alternative
<int>(c
), "");
304 constexpr variant
<int, char> d(in_place_index
<1>, char{});
305 static_assert(holds_alternative
<char>(d
), "");
306 constexpr variant
<int, char> e(in_place_type
<char>, char{});
307 static_assert(holds_alternative
<char>(e
), "");
308 constexpr variant
<int, char> f(char{});
309 static_assert(holds_alternative
<char>(f
), "");
313 constexpr literal() = default;
316 constexpr variant
<literal
, nonliteral
> v
{};
317 constexpr variant
<literal
, nonliteral
> v1
{in_place_type
<literal
>};
318 constexpr variant
<literal
, nonliteral
> v2
{in_place_index
<0>};
322 constexpr variant
<int> a(42);
323 static_assert(get
<0>(a
) == 42, "");
326 constexpr variant
<int, nonliteral
> a(42);
327 static_assert(get
<0>(a
) == 42, "");
330 constexpr variant
<nonliteral
, int> a(42);
331 static_assert(get
<1>(a
) == 42, "");
334 constexpr variant
<int> a(42);
335 static_assert(get
<int>(a
) == 42, "");
338 constexpr variant
<int, nonliteral
> a(42);
339 static_assert(get
<int>(a
) == 42, "");
342 constexpr variant
<nonliteral
, int> a(42);
343 static_assert(get
<int>(a
) == 42, "");
346 constexpr variant
<int> a(42);
347 static_assert(get
<0>(std::move(a
)) == 42, "");
350 constexpr variant
<int, nonliteral
> a(42);
351 static_assert(get
<0>(std::move(a
)) == 42, "");
354 constexpr variant
<nonliteral
, int> a(42);
355 static_assert(get
<1>(std::move(a
)) == 42, "");
358 constexpr variant
<int> a(42);
359 static_assert(get
<int>(std::move(a
)) == 42, "");
362 constexpr variant
<int, nonliteral
> a(42);
363 static_assert(get
<int>(std::move(a
)) == 42, "");
366 constexpr variant
<nonliteral
, int> a(42);
367 static_assert(get
<int>(std::move(a
)) == 42, "");
377 constexpr std::variant
<X
> v1
= X
{};
385 X(std::initializer_list
<int>, const X
&) { }
387 template<typename T
> void move(T
&) { }
388 template<typename T
> void forward(T
&) { }
391 template<typename T
> void operator()(T
&&) { }
399 std::initializer_list
<int> il
;
400 adl_trap::Visitor vis
;
402 std::variant
<X
> v0(x
);
405 v0
.emplace
<0>(il
, x
);
407 variant
<X
> v1
{in_place_index
<0>, x
};
408 variant
<X
> v2
{in_place_type
<X
>, x
};
409 variant
<X
> v3
{in_place_index
<0>, il
, x
};
410 variant
<X
> v4
{in_place_type
<X
>, il
, x
};
413 void test_variant_alternative()
415 static_assert(is_same_v
<variant_alternative_t
<0, variant
<int, string
>>, int>, "");
416 static_assert(is_same_v
<variant_alternative_t
<1, variant
<int, string
>>, string
>, "");
418 static_assert(is_same_v
<variant_alternative_t
<0, const variant
<int>>, const int>, "");
419 static_assert(is_same_v
<variant_alternative_t
<0, volatile variant
<int>>, volatile int>, "");
420 static_assert(is_same_v
<variant_alternative_t
<0, const volatile variant
<int>>, const volatile int>, "");
423 template<typename V
, typename T
>
424 constexpr auto has_type_emplace(int) -> decltype((declval
<V
>().template emplace
<T
>(), true))
427 template<typename V
, typename T
>
428 constexpr bool has_type_emplace(...)
431 template<typename V
, size_t N
>
432 constexpr auto has_index_emplace(int) -> decltype((declval
<V
>().template emplace
<N
>(), true))
435 template<typename V
, size_t T
>
436 constexpr bool has_index_emplace(...)
441 static_assert(has_type_emplace
<variant
<int>, int>(0), "");
442 static_assert(!has_type_emplace
<variant
<long>, int>(0), "");
443 static_assert(has_index_emplace
<variant
<int>, 0>(0), "");
444 static_assert(!has_type_emplace
<variant
<AllDeleted
>, AllDeleted
>(0), "");
445 static_assert(!has_index_emplace
<variant
<AllDeleted
>, 0>(0), "");