blob: 0830d3dde1b7a9d5c4ac7609bf337112d2a969d5 [file] [log] [blame]
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001// -*- C++ -*-
2//===------------------------------ variant -------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Eric Fiselier94cdacc2016-12-02 23:00:05 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_VARIANT
11#define _LIBCPP_VARIANT
12
13/*
14 variant synopsis
15
16namespace std {
17
18 // 20.7.2, class template variant
19 template <class... Types>
20 class variant {
21 public:
22
23 // 20.7.2.1, constructors
24 constexpr variant() noexcept(see below);
Louis Dionnecee59012019-01-10 20:06:11 +000025 variant(const variant&); // constexpr in C++20
26 variant(variant&&) noexcept(see below); // constexpr in C++20
Eric Fiselier94cdacc2016-12-02 23:00:05 +000027
28 template <class T> constexpr variant(T&&) noexcept(see below);
29
30 template <class T, class... Args>
31 constexpr explicit variant(in_place_type_t<T>, Args&&...);
32
33 template <class T, class U, class... Args>
34 constexpr explicit variant(
35 in_place_type_t<T>, initializer_list<U>, Args&&...);
36
37 template <size_t I, class... Args>
38 constexpr explicit variant(in_place_index_t<I>, Args&&...);
39
40 template <size_t I, class U, class... Args>
41 constexpr explicit variant(
42 in_place_index_t<I>, initializer_list<U>, Args&&...);
43
44 // 20.7.2.2, destructor
45 ~variant();
46
47 // 20.7.2.3, assignment
Louis Dionnecee59012019-01-10 20:06:11 +000048 variant& operator=(const variant&); // constexpr in C++20
49 variant& operator=(variant&&) noexcept(see below); // constexpr in C++20
Eric Fiselier94cdacc2016-12-02 23:00:05 +000050
51 template <class T> variant& operator=(T&&) noexcept(see below);
52
53 // 20.7.2.4, modifiers
54 template <class T, class... Args>
Eric Fiselier62928442017-04-15 19:32:02 +000055 T& emplace(Args&&...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +000056
57 template <class T, class U, class... Args>
Eric Fiselier62928442017-04-15 19:32:02 +000058 T& emplace(initializer_list<U>, Args&&...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +000059
60 template <size_t I, class... Args>
Eric Fiselier62928442017-04-15 19:32:02 +000061 variant_alternative_t<I, variant>& emplace(Args&&...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +000062
63 template <size_t I, class U, class... Args>
Eric Fiselier62928442017-04-15 19:32:02 +000064 variant_alternative_t<I, variant>& emplace(initializer_list<U>, Args&&...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +000065
66 // 20.7.2.5, value status
67 constexpr bool valueless_by_exception() const noexcept;
68 constexpr size_t index() const noexcept;
69
70 // 20.7.2.6, swap
71 void swap(variant&) noexcept(see below);
72 };
73
74 // 20.7.3, variant helper classes
75 template <class T> struct variant_size; // undefined
76
77 template <class T>
Marshall Clowf1bf62f2018-01-02 17:17:01 +000078 inline constexpr size_t variant_size_v = variant_size<T>::value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +000079
80 template <class T> struct variant_size<const T>;
81 template <class T> struct variant_size<volatile T>;
82 template <class T> struct variant_size<const volatile T>;
83
84 template <class... Types>
85 struct variant_size<variant<Types...>>;
86
87 template <size_t I, class T> struct variant_alternative; // undefined
88
89 template <size_t I, class T>
90 using variant_alternative_t = typename variant_alternative<I, T>::type;
91
92 template <size_t I, class T> struct variant_alternative<I, const T>;
93 template <size_t I, class T> struct variant_alternative<I, volatile T>;
94 template <size_t I, class T> struct variant_alternative<I, const volatile T>;
95
96 template <size_t I, class... Types>
97 struct variant_alternative<I, variant<Types...>>;
98
Marshall Clowf1bf62f2018-01-02 17:17:01 +000099 inline constexpr size_t variant_npos = -1;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000100
101 // 20.7.4, value access
102 template <class T, class... Types>
103 constexpr bool holds_alternative(const variant<Types...>&) noexcept;
104
105 template <size_t I, class... Types>
106 constexpr variant_alternative_t<I, variant<Types...>>&
107 get(variant<Types...>&);
108
109 template <size_t I, class... Types>
110 constexpr variant_alternative_t<I, variant<Types...>>&&
111 get(variant<Types...>&&);
112
113 template <size_t I, class... Types>
114 constexpr variant_alternative_t<I, variant<Types...>> const&
115 get(const variant<Types...>&);
116
117 template <size_t I, class... Types>
118 constexpr variant_alternative_t<I, variant<Types...>> const&&
119 get(const variant<Types...>&&);
120
121 template <class T, class... Types>
122 constexpr T& get(variant<Types...>&);
123
124 template <class T, class... Types>
125 constexpr T&& get(variant<Types...>&&);
126
127 template <class T, class... Types>
128 constexpr const T& get(const variant<Types...>&);
129
130 template <class T, class... Types>
131 constexpr const T&& get(const variant<Types...>&&);
132
133 template <size_t I, class... Types>
134 constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
135 get_if(variant<Types...>*) noexcept;
136
137 template <size_t I, class... Types>
138 constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
139 get_if(const variant<Types...>*) noexcept;
140
141 template <class T, class... Types>
142 constexpr add_pointer_t<T>
143 get_if(variant<Types...>*) noexcept;
144
145 template <class T, class... Types>
146 constexpr add_pointer_t<const T>
147 get_if(const variant<Types...>*) noexcept;
148
149 // 20.7.5, relational operators
150 template <class... Types>
151 constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
152
153 template <class... Types>
154 constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
155
156 template <class... Types>
157 constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
158
159 template <class... Types>
160 constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
161
162 template <class... Types>
163 constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
164
165 template <class... Types>
166 constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
167
168 // 20.7.6, visitation
169 template <class Visitor, class... Variants>
170 constexpr see below visit(Visitor&&, Variants&&...);
171
172 // 20.7.7, class monostate
173 struct monostate;
174
175 // 20.7.8, monostate relational operators
176 constexpr bool operator<(monostate, monostate) noexcept;
177 constexpr bool operator>(monostate, monostate) noexcept;
178 constexpr bool operator<=(monostate, monostate) noexcept;
179 constexpr bool operator>=(monostate, monostate) noexcept;
180 constexpr bool operator==(monostate, monostate) noexcept;
181 constexpr bool operator!=(monostate, monostate) noexcept;
182
183 // 20.7.9, specialized algorithms
184 template <class... Types>
185 void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
186
187 // 20.7.10, class bad_variant_access
188 class bad_variant_access;
189
190 // 20.7.11, hash support
191 template <class T> struct hash;
192 template <class... Types> struct hash<variant<Types...>>;
193 template <> struct hash<monostate>;
194
195} // namespace std
196
197*/
198
199#include <__config>
Louis Dionne73912b22020-11-04 15:01:25 -0500200#include <__availability>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000201#include <__tuple>
202#include <array>
203#include <exception>
204#include <functional>
205#include <initializer_list>
206#include <new>
207#include <tuple>
208#include <type_traits>
209#include <utility>
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000210#include <limits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000211#include <version>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000212
213#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
214#pragma GCC system_header
215#endif
216
Eric Fiselier8625d332017-11-19 04:57:22 +0000217_LIBCPP_PUSH_MACROS
218#include <__undef_macros>
219
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000220namespace std { // explicitly not using versioning namespace
221
Louis Dionnecef92e62018-11-19 15:37:04 +0000222class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000223public:
Saleem Abdulrasool5ee83382016-12-31 17:34:26 +0000224 virtual const char* what() const _NOEXCEPT;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000225};
226
227} // namespace std
228
229_LIBCPP_BEGIN_NAMESPACE_STD
230
Louis Dionne7202cd62020-07-22 15:24:16 -0400231// TODO: GCC 5 lies about its support for C++17 (it says it supports it but it
232// really doesn't). That breaks variant, which uses some C++17 features.
233// Remove this once we drop support for GCC 5.
Louis Dionne129391d2020-07-22 15:59:09 -0400234#if _LIBCPP_STD_VER > 14 && !(defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW < 6000)
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000235
Eric Fiselier10642ea2016-12-03 01:58:07 +0000236_LIBCPP_NORETURN
237inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +0000238_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier10642ea2016-12-03 01:58:07 +0000239void __throw_bad_variant_access() {
240#ifndef _LIBCPP_NO_EXCEPTIONS
241 throw bad_variant_access();
242#else
243 _VSTD::abort();
244#endif
245}
246
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000247template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000248class _LIBCPP_TEMPLATE_VIS variant;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000249
250template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000251struct _LIBCPP_TEMPLATE_VIS variant_size;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000252
253template <class _Tp>
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000254_LIBCPP_INLINE_VAR constexpr size_t variant_size_v = variant_size<_Tp>::value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000255
256template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000257struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000258
259template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000260struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000261
262template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000263struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000264 : variant_size<_Tp> {};
265
266template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000267struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000268 : integral_constant<size_t, sizeof...(_Types)> {};
269
270template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000271struct _LIBCPP_TEMPLATE_VIS variant_alternative;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000272
273template <size_t _Ip, class _Tp>
274using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;
275
276template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000277struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000278 : add_const<variant_alternative_t<_Ip, _Tp>> {};
279
280template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000281struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000282 : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
283
284template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000285struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000286 : add_cv<variant_alternative_t<_Ip, _Tp>> {};
287
288template <size_t _Ip, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000289struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
Marshall Clow185577f2017-06-12 16:13:17 +0000290 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000291 using type = __type_pack_element<_Ip, _Types...>;
292};
293
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000294_LIBCPP_INLINE_VAR constexpr size_t variant_npos = static_cast<size_t>(-1);
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000295
296constexpr int __choose_index_type(unsigned int __num_elem) {
297 if (__num_elem < std::numeric_limits<unsigned char>::max())
298 return 0;
299 if (__num_elem < std::numeric_limits<unsigned short>::max())
300 return 1;
301 return 2;
302}
303
304template <size_t _NumAlts>
305using __variant_index_t =
306#ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
307 unsigned int;
308#else
309 std::tuple_element_t<
310 __choose_index_type(_NumAlts),
311 std::tuple<unsigned char, unsigned short, unsigned int>
312 >;
313#endif
314
315template <class _IndexType>
316constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000317
318namespace __find_detail {
319
320template <class _Tp, class... _Types>
321inline _LIBCPP_INLINE_VISIBILITY
322constexpr size_t __find_index() {
323 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
324 size_t __result = __not_found;
325 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
326 if (__matches[__i]) {
327 if (__result != __not_found) {
328 return __ambiguous;
329 }
330 __result = __i;
331 }
332 }
333 return __result;
334}
335
336template <size_t _Index>
337struct __find_unambiguous_index_sfinae_impl
338 : integral_constant<size_t, _Index> {};
339
340template <>
341struct __find_unambiguous_index_sfinae_impl<__not_found> {};
342
343template <>
344struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
345
346template <class _Tp, class... _Types>
347struct __find_unambiguous_index_sfinae
348 : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};
349
350} // namespace __find_detail
351
352namespace __variant_detail {
353
354struct __valueless_t {};
355
356enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
357
Michael Parkeac50dd2020-10-26 12:34:22 -0400358template <class _Tp,
359 template <class> class _IsTriviallyAvailable,
360 template <class> class _IsAvailable>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000361constexpr _Trait __trait =
362 _IsTriviallyAvailable<_Tp>::value
363 ? _Trait::_TriviallyAvailable
364 : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
365
366inline _LIBCPP_INLINE_VISIBILITY
367constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
368 _Trait __result = _Trait::_TriviallyAvailable;
369 for (_Trait __t : __traits) {
370 if (static_cast<int>(__t) > static_cast<int>(__result)) {
371 __result = __t;
372 }
373 }
374 return __result;
375}
376
Michael Parkeac50dd2020-10-26 12:34:22 -0400377template <class... _Types>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000378struct __traits {
379 static constexpr _Trait __copy_constructible_trait =
380 __common_trait({__trait<_Types,
381 is_trivially_copy_constructible,
382 is_copy_constructible>...});
383
384 static constexpr _Trait __move_constructible_trait =
385 __common_trait({__trait<_Types,
386 is_trivially_move_constructible,
387 is_move_constructible>...});
388
389 static constexpr _Trait __copy_assignable_trait = __common_trait(
390 {__copy_constructible_trait,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000391 __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
392
393 static constexpr _Trait __move_assignable_trait = __common_trait(
394 {__move_constructible_trait,
395 __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
396
397 static constexpr _Trait __destructible_trait = __common_trait(
398 {__trait<_Types, is_trivially_destructible, is_destructible>...});
399};
400
401namespace __access {
402
403struct __union {
404 template <class _Vp>
405 inline _LIBCPP_INLINE_VISIBILITY
406 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
407 return _VSTD::forward<_Vp>(__v).__head;
408 }
409
410 template <class _Vp, size_t _Ip>
411 inline _LIBCPP_INLINE_VISIBILITY
412 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
413 return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
414 }
415};
416
417struct __base {
418 template <size_t _Ip, class _Vp>
419 inline _LIBCPP_INLINE_VISIBILITY
420 static constexpr auto&& __get_alt(_Vp&& __v) {
421 return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
422 in_place_index<_Ip>);
423 }
424};
425
426struct __variant {
427 template <size_t _Ip, class _Vp>
428 inline _LIBCPP_INLINE_VISIBILITY
429 static constexpr auto&& __get_alt(_Vp&& __v) {
430 return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl);
431 }
432};
433
434} // namespace __access
435
436namespace __visitation {
437
Michael Parkeac50dd2020-10-26 12:34:22 -0400438#define _LIBCPP_VARIANT_CASES_4(_Case, _Base) \
439 _Case(_Base + 0) \
440 _Case(_Base + 1) \
441 _Case(_Base + 2) \
442 _Case(_Base + 3)
443
444#define _LIBCPP_VARIANT_CASES_16(_Case, _Base) \
445 _LIBCPP_VARIANT_CASES_4(_Case, _Base + 4 * 0) \
446 _LIBCPP_VARIANT_CASES_4(_Case, _Base + 4 * 1) \
447 _LIBCPP_VARIANT_CASES_4(_Case, _Base + 4 * 2) \
448 _LIBCPP_VARIANT_CASES_4(_Case, _Base + 4 * 3)
449
450#define _LIBCPP_VARIANT_CASES_64(_Case, _Base) \
451 _LIBCPP_VARIANT_CASES_16(_Case, _Base + 16 * 0) \
452 _LIBCPP_VARIANT_CASES_16(_Case, _Base + 16 * 1) \
453 _LIBCPP_VARIANT_CASES_16(_Case, _Base + 16 * 2) \
454 _LIBCPP_VARIANT_CASES_16(_Case, _Base + 16 * 3)
455
456#define _LIBCPP_VARIANT_CASES_256(_Case, _Base) \
457 _LIBCPP_VARIANT_CASES_64(_Case, _Base + 64 * 0) \
458 _LIBCPP_VARIANT_CASES_64(_Case, _Base + 64 * 1) \
459 _LIBCPP_VARIANT_CASES_64(_Case, _Base + 64 * 2) \
460 _LIBCPP_VARIANT_CASES_64(_Case, _Base + 64 * 3)
461
462#define _LIBCPP_VARIANT_CASES(_NumCases, _Case) \
463 _LIBCPP_CONCAT(_LIBCPP_VARIANT_CASES_, _NumCases)(_Case, 0)
464
465#define _LIBCPP_VARIANT_SWITCH_MAX 256
466
467template <class _Iter, class _Fp, size_t... _Is>
468inline _LIBCPP_INLINE_VISIBILITY
469static constexpr void __fill_cartesian_impl(
470 _Iter __iter, _Fp __f, index_sequence<_Is...>) {
471 *__iter = __f(integral_constant<size_t, _Is>{}...);
472}
473
474template <class _Iter, class _Fp, size_t... _Is, size_t... _Js, class... _Ls>
475inline _LIBCPP_INLINE_VISIBILITY
476static constexpr void __fill_cartesian_impl(
477 _Iter __iter, _Fp __f, index_sequence<_Is...>, index_sequence<_Js...>, _Ls... __ls) {
478 constexpr size_t _Mp = (1 * ... * _Ls::size());
479 (__fill_cartesian_impl(
480 __iter + _Js * _Mp, __f, index_sequence<_Is..., _Js>{}, __ls...), ...);
481}
482
483template <size_t... _Ns, class _Iter, class _Fp>
484inline _LIBCPP_INLINE_VISIBILITY
485static constexpr void __fill_cartesian(_Iter __iter, _Fp __f) {
486 __fill_cartesian_impl(
487 __iter, __f, index_sequence<>{}, make_index_sequence<_Ns>{}...);
488}
489
490template <size_t _Np, size_t... _Ns>
491struct __multi {
492 inline _LIBCPP_INLINE_VISIBILITY
493 static constexpr size_t __size = (_Np * ... * _Ns);
494
495 inline _LIBCPP_INLINE_VISIBILITY
496 static constexpr size_t
497 __index(const size_t (&__is)[sizeof...(_Ns) + 1]) noexcept {
498 constexpr size_t __ns[] = {_Ns..., 1};
499 size_t __result = 0;
500 for (size_t __i = 0; __i < sizeof...(_Ns) + 1; ++__i) {
501 if (__is[__i] == variant_npos) {
502 return variant_npos;
503 }
504 __result += __is[__i];
505 __result *= __ns[__i];
506 }
507 return __result;
508 }
509};
510
511template <size_t... _Ns>
512struct __indices {
513 inline _LIBCPP_INLINE_VISIBILITY
514 static constexpr auto __value = [] {
515 using _Tp = array<size_t, sizeof...(_Ns)>;
516 array<_Tp, (1 * ... * _Ns)> __result = {};
517 __fill_cartesian<_Ns...>(__result.begin(),
518 [](auto... __is) -> _Tp { return {__is...}; });
519 return __result;
520 }();
521};
522
523template <size_t... _Ns, class _Fp, class _Rp, class... _Args>
524inline _LIBCPP_INLINE_VISIBILITY
525static constexpr auto __make_vtable_impl(_Fp __f, _Rp (*)(_Args...)) {
526 array<_Rp (*)(_Args...), (1 * ... * _Ns) + 1> __result = {
527 [](_Args...) -> _Rp { __throw_bad_variant_access(); }
528 };
529 __fill_cartesian<_Ns...>(__result.begin() + 1, __f);
530 return __result;
531}
532
533template <size_t... _Ns, class _Fp>
534inline _LIBCPP_INLINE_VISIBILITY
535static constexpr auto __make_vtable(_Fp __f) {
536 using _Tp = decltype(__f(integral_constant<size_t, (_Ns, 0)>{}...));
537 return __make_vtable_impl<_Ns...>(__f, _Tp{});
538}
539
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000540struct __base {
Michael Parkeac50dd2020-10-26 12:34:22 -0400541 template <class _Vis, class... _Vs>
542 struct __dispatch {
543 template <size_t... _Is>
Michael Park32334da2020-08-30 12:42:35 -0400544 inline _LIBCPP_INLINE_VISIBILITY
Michael Parkeac50dd2020-10-26 12:34:22 -0400545 constexpr auto operator()(integral_constant<size_t, _Is>...) const noexcept {
546 return +[](_Vis&& __vis, _Vs&&... __vs) -> decltype(auto) {
Michael Park32334da2020-08-30 12:42:35 -0400547 return __invoke_constexpr(
Michael Parkeac50dd2020-10-26 12:34:22 -0400548 _VSTD::forward<_Vis>(__vis),
549 __access::__base::__get_alt<_Is>(_VSTD::forward<_Vs>(__vs))...);
550 };
Michael Park32334da2020-08-30 12:42:35 -0400551 }
552 };
553
Michael Parkeac50dd2020-10-26 12:34:22 -0400554 template <class _Vis, class _Vp, class _Wp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000555 inline _LIBCPP_INLINE_VISIBILITY
Michael Parkeac50dd2020-10-26 12:34:22 -0400556 static constexpr decltype(auto)
557 __visit_alt_at(size_t __index, _Vis&& __vis, _Vp&& __v, _Wp&& __w) {
558 constexpr size_t __size = __uncvref_t<_Vp>::__size();
559 static_assert(__size == __uncvref_t<_Wp>::__size());
560 constexpr auto __dispatch_at = [](auto __i) {
561 return __dispatch<_Vis, _Vp, _Wp>{}(__i, __i);
562 };
563#define _LIBCPP_VARIANT_CASE(_Ip) \
564 case _Ip: { \
565 if constexpr (_Ip < __size) { \
566 return __dispatch_at(integral_constant<size_t, _Ip>{})( \
567 _VSTD::forward<_Vis>(__vis), \
568 _VSTD::forward<_Vp>(__v), \
569 _VSTD::forward<_Wp>(__w)); \
570 } else { \
571 _LIBCPP_UNREACHABLE(); \
572 } \
573 }
574 if constexpr (__size <= _LIBCPP_VARIANT_SWITCH_MAX) {
575 switch (__index) {
576 _LIBCPP_VARIANT_CASES(_LIBCPP_VARIANT_SWITCH_MAX, _LIBCPP_VARIANT_CASE)
577 default: __throw_bad_variant_access();
578 }
579 } else {
580 constexpr auto __vtable = __make_vtable<__size>(__dispatch_at);
581 return __vtable[__index + 1](_VSTD::forward<_Vis>(__vis),
582 _VSTD::forward<_Vp>(__v),
583 _VSTD::forward<_Wp>(__w));
584 }
585#undef _LIBCPP_VARIANT_CASE
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000586 }
587
Michael Parkeac50dd2020-10-26 12:34:22 -0400588 template <size_t... _Is, class _Vis, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000589 inline _LIBCPP_INLINE_VISIBILITY
Michael Parkeac50dd2020-10-26 12:34:22 -0400590 static constexpr decltype(auto) __visit_alt(_Vis&& __vis, _Vs&&... __vs) {
591 if constexpr (sizeof...(_Vs) == 0) {
592 return __invoke_constexpr(_VSTD::forward<_Vis>(__vis));
593 } else {
594 return __visit_alt_impl(index_sequence_for<_Vs...>{},
595 _VSTD::forward<_Vis>(__vis),
596 _VSTD::forward<_Vs>(__vs)...);
597 }
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000598 }
599
Michael Parkeac50dd2020-10-26 12:34:22 -0400600 template <size_t... _Is, class _Vis, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000601 inline _LIBCPP_INLINE_VISIBILITY
Michael Parkeac50dd2020-10-26 12:34:22 -0400602 static constexpr decltype(auto)
603 __visit_alt_impl(index_sequence<_Is...>, _Vis&& __vis, _Vs&&... __vs) {
604 using __multi = __multi<__uncvref_t<_Vs>::__size()...>;
605 constexpr __dispatch<_Vis, _Vs...> __dispatch;
606#define _LIBCPP_VARIANT_CASE(_Ip) \
607 case _Ip: { \
608 if constexpr (_Ip < __multi::__size) { \
609 return __dispatch(integral_constant<size_t, __itable[_Ip][_Is]>{}...)( \
610 _VSTD::forward<_Vis>(__vis), _VSTD::forward<_Vs>(__vs)...); \
611 } else { \
612 _LIBCPP_UNREACHABLE(); \
613 } \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000614 }
Michael Parkeac50dd2020-10-26 12:34:22 -0400615 if constexpr (__multi::__size <= _LIBCPP_VARIANT_SWITCH_MAX) {
616 constexpr const auto& __itable =
617 __indices<__uncvref_t<_Vs>::__size()...>::__value;
618 switch (__multi::__index({__vs.index()...})) {
619 _LIBCPP_VARIANT_CASES(_LIBCPP_VARIANT_SWITCH_MAX, _LIBCPP_VARIANT_CASE)
620 default: __throw_bad_variant_access();
621 }
622 } else {
623 constexpr auto __vtable =
624 __make_vtable<__uncvref_t<_Vs>::__size()...>(__dispatch);
625 return __vtable[__multi::__index({__vs.index()...}) + 1](
626 _VSTD::forward<_Vis>(__vis), _VSTD::forward<_Vs>(__vs)...);
627 }
628#undef _LIBCPP_VARIANT_CASE
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000629 }
630};
631
632struct __variant {
Michael Parkeac50dd2020-10-26 12:34:22 -0400633 template <class _Vis, class _Vp, class _Wp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000634 inline _LIBCPP_INLINE_VISIBILITY
635 static constexpr decltype(auto)
Michael Parkeac50dd2020-10-26 12:34:22 -0400636 __visit_alt_at(size_t __index, _Vis&& __vis, _Vp&& __v, _Wp&& __w) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000637 return __base::__visit_alt_at(__index,
Michael Parkeac50dd2020-10-26 12:34:22 -0400638 _VSTD::forward<_Vis>(__vis),
639 _VSTD::forward<_Vp>(__v).__impl,
640 _VSTD::forward<_Wp>(__w).__impl);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000641 }
642
Michael Parkeac50dd2020-10-26 12:34:22 -0400643 template <class _Vis, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000644 inline _LIBCPP_INLINE_VISIBILITY
Michael Parkeac50dd2020-10-26 12:34:22 -0400645 static constexpr decltype(auto) __visit_alt(_Vis&& __vis, _Vs&&... __vs) {
646 return __base::__visit_alt(_VSTD::forward<_Vis>(__vis),
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000647 _VSTD::forward<_Vs>(__vs).__impl...);
648 }
649
Michael Parkeac50dd2020-10-26 12:34:22 -0400650 template <class _Vis, class _Vp, class _Wp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000651 inline _LIBCPP_INLINE_VISIBILITY
652 static constexpr decltype(auto)
Michael Parkeac50dd2020-10-26 12:34:22 -0400653 __visit_value_at(size_t __index, _Vis&& __vis, _Vp&& __v, _Wp&& __w) {
654 return __visit_alt_at(__index,
655 __make_value_visitor(_VSTD::forward<_Vis>(__vis)),
656 _VSTD::forward<_Vp>(__v),
657 _VSTD::forward<_Wp>(__w));
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000658 }
659
Michael Parkeac50dd2020-10-26 12:34:22 -0400660 template <class _Vis, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000661 inline _LIBCPP_INLINE_VISIBILITY
Michael Parkeac50dd2020-10-26 12:34:22 -0400662 static constexpr decltype(auto) __visit_value(_Vis&& __vis, _Vs&&... __vs) {
663 return __visit_alt(__make_value_visitor(_VSTD::forward<_Vis>(__vis)),
664 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000665 }
666
667private:
Michael Parkeac50dd2020-10-26 12:34:22 -0400668 template <class _Vis, class... _Values>
669 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000670 static constexpr void __std_visit_exhaustive_visitor_check() {
Michael Parkeac50dd2020-10-26 12:34:22 -0400671 static_assert(is_invocable_v<_Vis, _Values...>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000672 "`std::visit` requires the visitor to be exhaustive.");
673 }
674
Michael Parkeac50dd2020-10-26 12:34:22 -0400675 template <class _Vis>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000676 struct __value_visitor {
677 template <class... _Alts>
678 inline _LIBCPP_INLINE_VISIBILITY
679 constexpr decltype(auto) operator()(_Alts&&... __alts) const {
680 __std_visit_exhaustive_visitor_check<
Michael Parkeac50dd2020-10-26 12:34:22 -0400681 _Vis, decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
682 return __invoke_constexpr(_VSTD::forward<_Vis>(__vis),
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000683 _VSTD::forward<_Alts>(__alts).__value...);
684 }
Michael Parkeac50dd2020-10-26 12:34:22 -0400685 _Vis&& __vis;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000686 };
687
Michael Parkeac50dd2020-10-26 12:34:22 -0400688 template <class _Vis>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000689 inline _LIBCPP_INLINE_VISIBILITY
Michael Parkeac50dd2020-10-26 12:34:22 -0400690 static constexpr auto __make_value_visitor(_Vis&& __vis) {
691 return __value_visitor<_Vis>{_VSTD::forward<_Vis>(__vis)};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000692 }
693};
694
Michael Parkeac50dd2020-10-26 12:34:22 -0400695#undef _LIBCPP_VARIANT_SWITCH_MAX
696#undef _LIBCPP_VARIANT_CASES
697#undef _LIBCPP_VARIANT_CASES_256
698#undef _LIBCPP_VARIANT_CASES_64
699#undef _LIBCPP_VARIANT_CASES_16
700#undef _LIBCPP_VARIANT_CASES_4
701
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000702} // namespace __visitation
703
704template <size_t _Index, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000705struct _LIBCPP_TEMPLATE_VIS __alt {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000706 using __value_type = _Tp;
707
708 template <class... _Args>
709 inline _LIBCPP_INLINE_VISIBILITY
710 explicit constexpr __alt(in_place_t, _Args&&... __args)
711 : __value(_VSTD::forward<_Args>(__args)...) {}
712
713 __value_type __value;
714};
715
716template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000717union _LIBCPP_TEMPLATE_VIS __union;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000718
719template <_Trait _DestructibleTrait, size_t _Index>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000720union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000721
722#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
723 template <size_t _Index, class _Tp, class... _Types> \
Michael Parkeac50dd2020-10-26 12:34:22 -0400724 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000725 _Index, \
726 _Tp, \
727 _Types...> { \
728 public: \
729 inline _LIBCPP_INLINE_VISIBILITY \
730 explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
731 \
732 template <class... _Args> \
733 inline _LIBCPP_INLINE_VISIBILITY \
734 explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
735 : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
736 \
737 template <size_t _Ip, class... _Args> \
738 inline _LIBCPP_INLINE_VISIBILITY \
739 explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
740 : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
741 \
742 __union(const __union&) = default; \
743 __union(__union&&) = default; \
744 \
745 destructor \
746 \
747 __union& operator=(const __union&) = default; \
748 __union& operator=(__union&&) = default; \
749 \
750 private: \
751 char __dummy; \
752 __alt<_Index, _Tp> __head; \
753 __union<destructible_trait, _Index + 1, _Types...> __tail; \
754 \
755 friend struct __access::__union; \
756 }
757
758_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
759_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {});
760_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
761
762#undef _LIBCPP_VARIANT_UNION
763
764template <_Trait _DestructibleTrait, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000765class _LIBCPP_TEMPLATE_VIS __base {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000766public:
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000767 using __index_t = __variant_index_t<sizeof...(_Types)>;
768
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000769 inline _LIBCPP_INLINE_VISIBILITY
770 explicit constexpr __base(__valueless_t tag) noexcept
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000771 : __data(tag), __index(__variant_npos<__index_t>) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000772
773 template <size_t _Ip, class... _Args>
774 inline _LIBCPP_INLINE_VISIBILITY
775 explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
Eric Fiselier2adf0872016-12-02 23:17:33 +0000776 :
777 __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
778 __index(_Ip) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000779
780 inline _LIBCPP_INLINE_VISIBILITY
781 constexpr bool valueless_by_exception() const noexcept {
782 return index() == variant_npos;
783 }
784
785 inline _LIBCPP_INLINE_VISIBILITY
786 constexpr size_t index() const noexcept {
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000787 return __index == __variant_npos<__index_t> ? variant_npos : __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000788 }
789
790protected:
791 inline _LIBCPP_INLINE_VISIBILITY
792 constexpr auto&& __as_base() & { return *this; }
793
794 inline _LIBCPP_INLINE_VISIBILITY
795 constexpr auto&& __as_base() && { return _VSTD::move(*this); }
796
797 inline _LIBCPP_INLINE_VISIBILITY
798 constexpr auto&& __as_base() const & { return *this; }
799
800 inline _LIBCPP_INLINE_VISIBILITY
801 constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
802
803 inline _LIBCPP_INLINE_VISIBILITY
804 static constexpr size_t __size() { return sizeof...(_Types); }
805
806 __union<_DestructibleTrait, 0, _Types...> __data;
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000807 __index_t __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000808
809 friend struct __access::__base;
810 friend struct __visitation::__base;
811};
812
813template <class _Traits, _Trait = _Traits::__destructible_trait>
Louis Dionneff05add2020-10-05 16:30:23 -0400814class _LIBCPP_TEMPLATE_VIS __dtor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000815
816#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \
817 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400818 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, \
819 destructible_trait> \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000820 : public __base<destructible_trait, _Types...> { \
821 using __base_type = __base<destructible_trait, _Types...>; \
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000822 using __index_t = typename __base_type::__index_t; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000823 \
824 public: \
825 using __base_type::__base_type; \
826 using __base_type::operator=; \
827 \
Louis Dionneff05add2020-10-05 16:30:23 -0400828 __dtor(const __dtor&) = default; \
829 __dtor(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000830 destructor \
Louis Dionneff05add2020-10-05 16:30:23 -0400831 __dtor& operator=(const __dtor&) = default; \
832 __dtor& operator=(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000833 \
834 protected: \
835 inline _LIBCPP_INLINE_VISIBILITY \
836 destroy \
837 }
838
839_LIBCPP_VARIANT_DESTRUCTOR(
840 _Trait::_TriviallyAvailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400841 ~__dtor() = default;,
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000842 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000843
844_LIBCPP_VARIANT_DESTRUCTOR(
845 _Trait::_Available,
Louis Dionneff05add2020-10-05 16:30:23 -0400846 ~__dtor() { __destroy(); },
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000847 void __destroy() noexcept {
848 if (!this->valueless_by_exception()) {
849 __visitation::__base::__visit_alt(
850 [](auto& __alt) noexcept {
Marshall Clowe61ba952018-02-12 15:41:25 +0000851 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000852 __alt.~__alt_type();
853 },
854 *this);
855 }
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000856 this->__index = __variant_npos<__index_t>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000857 });
858
859_LIBCPP_VARIANT_DESTRUCTOR(
860 _Trait::_Unavailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400861 ~__dtor() = delete;,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000862 void __destroy() noexcept = delete;);
863
864#undef _LIBCPP_VARIANT_DESTRUCTOR
865
866template <class _Traits>
Louis Dionneff05add2020-10-05 16:30:23 -0400867class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> {
868 using __base_type = __dtor<_Traits>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000869
870public:
871 using __base_type::__base_type;
872 using __base_type::operator=;
873
874protected:
875 template <size_t _Ip, class _Tp, class... _Args>
876 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000877 static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
Michael Parkeac50dd2020-10-26 12:34:22 -0400878 auto* __result = ::new ((void*)_VSTD::addressof(__a))
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000879 __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
Michael Parkeac50dd2020-10-26 12:34:22 -0400880 return __result->__value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000881 }
882
883 template <class _Rhs>
884 inline _LIBCPP_INLINE_VISIBILITY
Louis Dionneff05add2020-10-05 16:30:23 -0400885 static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000886 __lhs.__destroy();
887 if (!__rhs.valueless_by_exception()) {
888 __visitation::__base::__visit_alt_at(
889 __rhs.index(),
890 [](auto& __lhs_alt, auto&& __rhs_alt) {
891 __construct_alt(
892 __lhs_alt,
893 _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
894 },
895 __lhs, _VSTD::forward<_Rhs>(__rhs));
896 __lhs.__index = __rhs.index();
897 }
898 }
899};
900
901template <class _Traits, _Trait = _Traits::__move_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000902class _LIBCPP_TEMPLATE_VIS __move_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000903
904#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \
905 move_constructor) \
906 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400907 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \
908 move_constructible_trait> \
909 : public __ctor<__traits<_Types...>> { \
910 using __base_type = __ctor<__traits<_Types...>>; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000911 \
912 public: \
913 using __base_type::__base_type; \
914 using __base_type::operator=; \
915 \
916 __move_constructor(const __move_constructor&) = default; \
917 move_constructor \
918 ~__move_constructor() = default; \
919 __move_constructor& operator=(const __move_constructor&) = default; \
920 __move_constructor& operator=(__move_constructor&&) = default; \
921 }
922
923_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
924 _Trait::_TriviallyAvailable,
925 __move_constructor(__move_constructor&& __that) = default;);
926
927_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
928 _Trait::_Available,
929 __move_constructor(__move_constructor&& __that) noexcept(
930 __all<is_nothrow_move_constructible_v<_Types>...>::value)
931 : __move_constructor(__valueless_t{}) {
932 this->__generic_construct(*this, _VSTD::move(__that));
933 });
934
935_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
936 _Trait::_Unavailable,
937 __move_constructor(__move_constructor&&) = delete;);
938
939#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
940
941template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000942class _LIBCPP_TEMPLATE_VIS __copy_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000943
944#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
945 copy_constructor) \
946 template <class... _Types> \
Michael Parkeac50dd2020-10-26 12:34:22 -0400947 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000948 copy_constructible_trait> \
949 : public __move_constructor<__traits<_Types...>> { \
950 using __base_type = __move_constructor<__traits<_Types...>>; \
951 \
952 public: \
953 using __base_type::__base_type; \
954 using __base_type::operator=; \
955 \
956 copy_constructor \
957 __copy_constructor(__copy_constructor&&) = default; \
958 ~__copy_constructor() = default; \
959 __copy_constructor& operator=(const __copy_constructor&) = default; \
960 __copy_constructor& operator=(__copy_constructor&&) = default; \
961 }
962
963_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
964 _Trait::_TriviallyAvailable,
965 __copy_constructor(const __copy_constructor& __that) = default;);
966
967_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
968 _Trait::_Available,
969 __copy_constructor(const __copy_constructor& __that)
970 : __copy_constructor(__valueless_t{}) {
971 this->__generic_construct(*this, __that);
972 });
973
974_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
975 _Trait::_Unavailable,
976 __copy_constructor(const __copy_constructor&) = delete;);
977
978#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
979
980template <class _Traits>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000981class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000982 using __base_type = __copy_constructor<_Traits>;
983
984public:
985 using __base_type::__base_type;
986 using __base_type::operator=;
987
988 template <size_t _Ip, class... _Args>
989 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000990 auto& __emplace(_Args&&... __args) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000991 this->__destroy();
Eric Fiselier62928442017-04-15 19:32:02 +0000992 auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
Michael Parkeac50dd2020-10-26 12:34:22 -0400993 _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000994 this->__index = _Ip;
Eric Fiselier62928442017-04-15 19:32:02 +0000995 return __res;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000996 }
997
998protected:
Michael Park62118352017-06-07 10:22:43 +0000999 template <size_t _Ip, class _Tp, class _Arg>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001000 inline _LIBCPP_INLINE_VISIBILITY
Michael Park62118352017-06-07 10:22:43 +00001001 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001002 if (this->index() == _Ip) {
1003 __a.__value = _VSTD::forward<_Arg>(__arg);
1004 } else {
1005 struct {
1006 void operator()(true_type) const {
Michael Park62118352017-06-07 10:22:43 +00001007 __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001008 }
1009 void operator()(false_type) const {
Michael Park62118352017-06-07 10:22:43 +00001010 __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001011 }
1012 __assignment* __this;
1013 _Arg&& __arg;
1014 } __impl{this, _VSTD::forward<_Arg>(__arg)};
Michael Park62118352017-06-07 10:22:43 +00001015 __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||
1016 !is_nothrow_move_constructible_v<_Tp>>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001017 }
1018 }
1019
1020 template <class _That>
1021 inline _LIBCPP_INLINE_VISIBILITY
1022 void __generic_assign(_That&& __that) {
1023 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1024 // do nothing.
1025 } else if (__that.valueless_by_exception()) {
1026 this->__destroy();
1027 } else {
1028 __visitation::__base::__visit_alt_at(
1029 __that.index(),
1030 [this](auto& __this_alt, auto&& __that_alt) {
1031 this->__assign_alt(
1032 __this_alt,
Michael Park62118352017-06-07 10:22:43 +00001033 _VSTD::forward<decltype(__that_alt)>(__that_alt).__value);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001034 },
1035 *this, _VSTD::forward<_That>(__that));
1036 }
1037 }
1038};
1039
1040template <class _Traits, _Trait = _Traits::__move_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001041class _LIBCPP_TEMPLATE_VIS __move_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001042
1043#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
1044 move_assignment) \
1045 template <class... _Types> \
Michael Parkeac50dd2020-10-26 12:34:22 -04001046 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001047 move_assignable_trait> \
1048 : public __assignment<__traits<_Types...>> { \
1049 using __base_type = __assignment<__traits<_Types...>>; \
1050 \
1051 public: \
1052 using __base_type::__base_type; \
1053 using __base_type::operator=; \
1054 \
1055 __move_assignment(const __move_assignment&) = default; \
1056 __move_assignment(__move_assignment&&) = default; \
1057 ~__move_assignment() = default; \
1058 __move_assignment& operator=(const __move_assignment&) = default; \
1059 move_assignment \
1060 }
1061
1062_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1063 _Trait::_TriviallyAvailable,
1064 __move_assignment& operator=(__move_assignment&& __that) = default;);
1065
1066_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1067 _Trait::_Available,
1068 __move_assignment& operator=(__move_assignment&& __that) noexcept(
1069 __all<(is_nothrow_move_constructible_v<_Types> &&
1070 is_nothrow_move_assignable_v<_Types>)...>::value) {
1071 this->__generic_assign(_VSTD::move(__that));
1072 return *this;
1073 });
1074
1075_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1076 _Trait::_Unavailable,
1077 __move_assignment& operator=(__move_assignment&&) = delete;);
1078
1079#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
1080
1081template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001082class _LIBCPP_TEMPLATE_VIS __copy_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001083
1084#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
1085 copy_assignment) \
1086 template <class... _Types> \
Michael Parkeac50dd2020-10-26 12:34:22 -04001087 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001088 copy_assignable_trait> \
1089 : public __move_assignment<__traits<_Types...>> { \
1090 using __base_type = __move_assignment<__traits<_Types...>>; \
1091 \
1092 public: \
1093 using __base_type::__base_type; \
1094 using __base_type::operator=; \
1095 \
1096 __copy_assignment(const __copy_assignment&) = default; \
1097 __copy_assignment(__copy_assignment&&) = default; \
1098 ~__copy_assignment() = default; \
1099 copy_assignment \
1100 __copy_assignment& operator=(__copy_assignment&&) = default; \
1101 }
1102
1103_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1104 _Trait::_TriviallyAvailable,
1105 __copy_assignment& operator=(const __copy_assignment& __that) = default;);
1106
1107_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1108 _Trait::_Available,
1109 __copy_assignment& operator=(const __copy_assignment& __that) {
1110 this->__generic_assign(__that);
1111 return *this;
1112 });
1113
1114_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1115 _Trait::_Unavailable,
1116 __copy_assignment& operator=(const __copy_assignment&) = delete;);
1117
1118#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1119
1120template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001121class _LIBCPP_TEMPLATE_VIS __impl
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001122 : public __copy_assignment<__traits<_Types...>> {
1123 using __base_type = __copy_assignment<__traits<_Types...>>;
1124
1125public:
1126 using __base_type::__base_type;
1127 using __base_type::operator=;
1128
1129 template <size_t _Ip, class _Arg>
1130 inline _LIBCPP_INLINE_VISIBILITY
1131 void __assign(_Arg&& __arg) {
1132 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
Michael Park62118352017-06-07 10:22:43 +00001133 _VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001134 }
1135
1136 inline _LIBCPP_INLINE_VISIBILITY
1137 void __swap(__impl& __that) {
1138 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1139 // do nothing.
1140 } else if (this->index() == __that.index()) {
1141 __visitation::__base::__visit_alt_at(
1142 this->index(),
1143 [](auto& __this_alt, auto& __that_alt) {
1144 using _VSTD::swap;
1145 swap(__this_alt.__value, __that_alt.__value);
1146 },
1147 *this,
1148 __that);
1149 } else {
1150 __impl* __lhs = this;
1151 __impl* __rhs = _VSTD::addressof(__that);
1152 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1153 _VSTD::swap(__lhs, __rhs);
1154 }
1155 __impl __tmp(_VSTD::move(*__rhs));
Michael Park5dee7342020-06-16 15:15:10 -07001156#ifndef _LIBCPP_NO_EXCEPTIONS
Michael Park6a9ef642020-07-08 10:46:02 -07001157 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
Michael Park31967aa2020-06-16 13:29:23 -07001158 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1159 } else {
1160 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1161 // and `__tmp` is nothrow move constructible then we move `__tmp` back
1162 // into `__rhs` and provide the strong exception safety guarantee.
1163 try {
1164 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1165 } catch (...) {
1166 if (__tmp.__move_nothrow()) {
1167 this->__generic_construct(*__rhs, _VSTD::move(__tmp));
1168 }
1169 throw;
1170 }
1171 }
Michael Park5dee7342020-06-16 15:15:10 -07001172#else
1173 // this isn't consolidated with the `if constexpr` branch above due to
1174 // `throw` being ill-formed with exceptions disabled even when discarded.
1175 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1176#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001177 this->__generic_construct(*__lhs, _VSTD::move(__tmp));
1178 }
1179 }
1180
1181private:
1182 inline _LIBCPP_INLINE_VISIBILITY
1183 bool __move_nothrow() const {
1184 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1185 return this->valueless_by_exception() || __results[this->index()];
1186 }
1187};
1188
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001189struct __no_narrowing_check {
1190 template <class _Dest, class _Source>
1191 using _Apply = __identity<_Dest>;
1192};
1193
1194struct __narrowing_check {
1195 template <class _Dest>
1196 static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>;
1197 template <class _Dest, class _Source>
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001198 using _Apply _LIBCPP_NODEBUG_TYPE = decltype(__test_impl<_Dest>({std::declval<_Source>()}));
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001199};
1200
1201template <class _Dest, class _Source>
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001202using __check_for_narrowing _LIBCPP_NODEBUG_TYPE =
1203 typename _If<
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001204#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
1205 false &&
1206#endif
1207 is_arithmetic<_Dest>::value,
1208 __narrowing_check,
1209 __no_narrowing_check
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001210 >::template _Apply<_Dest, _Source>;
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001211
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001212template <class _Tp, size_t _Idx>
1213struct __overload {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001214 template <class _Up>
Eric Fiselier80f5dfb2019-07-14 18:31:55 +00001215 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001216};
1217
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001218template <class _Tp, size_t>
1219struct __overload_bool {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001220 template <class _Up, class _Ap = __uncvref_t<_Up>>
1221 auto operator()(bool, _Up&&) const
1222 -> enable_if_t<is_same_v<_Ap, bool>, __identity<_Tp>>;
1223};
1224
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001225template <size_t _Idx>
1226struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};
1227template <size_t _Idx>
1228struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};
1229template <size_t _Idx>
1230struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};
1231template <size_t _Idx>
1232struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};
1233
1234template <class ..._Bases>
1235struct __all_overloads : _Bases... {
1236 void operator()() const;
1237 using _Bases::operator()...;
1238};
1239
1240template <class IdxSeq>
1241struct __make_overloads_imp;
1242
1243template <size_t ..._Idx>
1244struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1245 template <class ..._Types>
1246 using _Apply _LIBCPP_NODEBUG_TYPE = __all_overloads<__overload<_Types, _Idx>...>;
1247};
1248
1249template <class ..._Types>
1250using _MakeOverloads _LIBCPP_NODEBUG_TYPE = typename __make_overloads_imp<
1251 __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
Zhihao Yuan821efb82019-06-20 22:09:40 +00001252
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001253template <class _Tp, class... _Types>
Zhihao Yuan821efb82019-06-20 22:09:40 +00001254using __best_match_t =
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001255 typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001256
1257} // __variant_detail
1258
1259template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001260class _LIBCPP_TEMPLATE_VIS variant
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001261 : private __sfinae_ctor_base<
1262 __all<is_copy_constructible_v<_Types>...>::value,
1263 __all<is_move_constructible_v<_Types>...>::value>,
1264 private __sfinae_assign_base<
1265 __all<(is_copy_constructible_v<_Types> &&
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001266 is_copy_assignable_v<_Types>)...>::value,
1267 __all<(is_move_constructible_v<_Types> &&
1268 is_move_assignable_v<_Types>)...>::value> {
1269 static_assert(0 < sizeof...(_Types),
1270 "variant must consist of at least one alternative.");
1271
1272 static_assert(__all<!is_array_v<_Types>...>::value,
1273 "variant can not have an array type as an alternative.");
1274
1275 static_assert(__all<!is_reference_v<_Types>...>::value,
1276 "variant can not have a reference type as an alternative.");
1277
1278 static_assert(__all<!is_void_v<_Types>...>::value,
1279 "variant can not have a void type as an alternative.");
1280
1281 using __first_type = variant_alternative_t<0, variant>;
1282
1283public:
1284 template <bool _Dummy = true,
1285 enable_if_t<__dependent_type<is_default_constructible<__first_type>,
1286 _Dummy>::value,
1287 int> = 0>
1288 inline _LIBCPP_INLINE_VISIBILITY
1289 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
1290 : __impl(in_place_index<0>) {}
1291
1292 variant(const variant&) = default;
1293 variant(variant&&) = default;
1294
1295 template <
1296 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001297 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
1298 enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0,
1299 enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001300 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1301 size_t _Ip =
1302 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1303 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1304 inline _LIBCPP_INLINE_VISIBILITY
1305 constexpr variant(_Arg&& __arg) noexcept(
1306 is_nothrow_constructible_v<_Tp, _Arg>)
1307 : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
1308
1309 template <size_t _Ip, class... _Args,
Eric Fiselier5d2df752018-03-23 23:42:30 +00001310 class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1311 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1312 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001313 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001314 explicit constexpr variant(
1315 in_place_index_t<_Ip>,
1316 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001317 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1318
Eric Fiselier5d2df752018-03-23 23:42:30 +00001319 template <
1320 size_t _Ip,
1321 class _Up,
1322 class... _Args,
1323 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1324 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001325 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1326 int> = 0>
1327 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001328 explicit constexpr variant(
1329 in_place_index_t<_Ip>,
1330 initializer_list<_Up> __il,
1331 _Args&&... __args) noexcept(
1332 is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001333 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1334
1335 template <
1336 class _Tp,
1337 class... _Args,
1338 size_t _Ip =
1339 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1340 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1341 inline _LIBCPP_INLINE_VISIBILITY
1342 explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1343 is_nothrow_constructible_v<_Tp, _Args...>)
1344 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1345
1346 template <
1347 class _Tp,
1348 class _Up,
1349 class... _Args,
1350 size_t _Ip =
1351 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1352 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1353 int> = 0>
1354 inline _LIBCPP_INLINE_VISIBILITY
1355 explicit constexpr variant(
1356 in_place_type_t<_Tp>,
1357 initializer_list<_Up> __il,
1358 _Args&&... __args) noexcept(
1359 is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
1360 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1361
1362 ~variant() = default;
1363
1364 variant& operator=(const variant&) = default;
1365 variant& operator=(variant&&) = default;
1366
1367 template <
1368 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001369 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001370 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1371 size_t _Ip =
1372 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1373 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
1374 int> = 0>
1375 inline _LIBCPP_INLINE_VISIBILITY
1376 variant& operator=(_Arg&& __arg) noexcept(
1377 is_nothrow_assignable_v<_Tp&, _Arg> &&
1378 is_nothrow_constructible_v<_Tp, _Arg>) {
1379 __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg));
1380 return *this;
1381 }
1382
1383 template <
1384 size_t _Ip,
1385 class... _Args,
1386 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1387 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1388 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1389 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001390 _Tp& emplace(_Args&&... __args) {
1391 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001392 }
1393
1394 template <
1395 size_t _Ip,
1396 class _Up,
1397 class... _Args,
1398 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1399 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1400 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1401 int> = 0>
1402 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001403 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1404 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001405 }
1406
1407 template <
1408 class _Tp,
1409 class... _Args,
1410 size_t _Ip =
1411 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1412 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1413 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001414 _Tp& emplace(_Args&&... __args) {
1415 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001416 }
1417
1418 template <
1419 class _Tp,
1420 class _Up,
1421 class... _Args,
1422 size_t _Ip =
1423 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1424 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1425 int> = 0>
1426 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001427 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1428 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001429 }
1430
1431 inline _LIBCPP_INLINE_VISIBILITY
1432 constexpr bool valueless_by_exception() const noexcept {
1433 return __impl.valueless_by_exception();
1434 }
1435
1436 inline _LIBCPP_INLINE_VISIBILITY
1437 constexpr size_t index() const noexcept { return __impl.index(); }
1438
1439 template <
1440 bool _Dummy = true,
1441 enable_if_t<
1442 __all<(
1443 __dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1444 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1445 int> = 0>
1446 inline _LIBCPP_INLINE_VISIBILITY
1447 void swap(variant& __that) noexcept(
1448 __all<(is_nothrow_move_constructible_v<_Types> &&
1449 is_nothrow_swappable_v<_Types>)...>::value) {
1450 __impl.__swap(__that.__impl);
1451 }
1452
1453private:
1454 __variant_detail::__impl<_Types...> __impl;
1455
1456 friend struct __variant_detail::__access::__variant;
1457 friend struct __variant_detail::__visitation::__variant;
1458};
1459
1460template <size_t _Ip, class... _Types>
1461inline _LIBCPP_INLINE_VISIBILITY
1462constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1463 return __v.index() == _Ip;
1464}
1465
1466template <class _Tp, class... _Types>
1467inline _LIBCPP_INLINE_VISIBILITY
1468constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1469 return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1470}
1471
1472template <size_t _Ip, class _Vp>
1473inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001474_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Richard Smith66d1c552018-08-27 21:41:50 +00001475constexpr auto&& __generic_get(_Vp&& __v) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001476 using __variant_detail::__access::__variant;
1477 if (!__holds_alternative<_Ip>(__v)) {
Eric Fiselier10642ea2016-12-03 01:58:07 +00001478 __throw_bad_variant_access();
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001479 }
1480 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1481}
1482
1483template <size_t _Ip, class... _Types>
1484inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001485_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001486constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
1487 variant<_Types...>& __v) {
1488 static_assert(_Ip < sizeof...(_Types));
1489 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1490 return __generic_get<_Ip>(__v);
1491}
1492
1493template <size_t _Ip, class... _Types>
1494inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001495_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001496constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
1497 variant<_Types...>&& __v) {
1498 static_assert(_Ip < sizeof...(_Types));
1499 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1500 return __generic_get<_Ip>(_VSTD::move(__v));
1501}
1502
1503template <size_t _Ip, class... _Types>
1504inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001505_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001506constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
1507 const variant<_Types...>& __v) {
1508 static_assert(_Ip < sizeof...(_Types));
1509 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1510 return __generic_get<_Ip>(__v);
1511}
1512
1513template <size_t _Ip, class... _Types>
1514inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001515_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001516constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
1517 const variant<_Types...>&& __v) {
1518 static_assert(_Ip < sizeof...(_Types));
1519 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1520 return __generic_get<_Ip>(_VSTD::move(__v));
1521}
1522
1523template <class _Tp, class... _Types>
1524inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001525_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001526constexpr _Tp& get(variant<_Types...>& __v) {
1527 static_assert(!is_void_v<_Tp>);
1528 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1529}
1530
1531template <class _Tp, class... _Types>
1532inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001533_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001534constexpr _Tp&& get(variant<_Types...>&& __v) {
1535 static_assert(!is_void_v<_Tp>);
1536 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1537 _VSTD::move(__v));
1538}
1539
1540template <class _Tp, class... _Types>
1541inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001542_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001543constexpr const _Tp& get(const variant<_Types...>& __v) {
1544 static_assert(!is_void_v<_Tp>);
1545 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1546}
1547
1548template <class _Tp, class... _Types>
1549inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001550_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001551constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1552 static_assert(!is_void_v<_Tp>);
1553 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1554 _VSTD::move(__v));
1555}
1556
1557template <size_t _Ip, class _Vp>
1558inline _LIBCPP_INLINE_VISIBILITY
1559constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1560 using __variant_detail::__access::__variant;
1561 return __v && __holds_alternative<_Ip>(*__v)
1562 ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value)
1563 : nullptr;
1564}
1565
1566template <size_t _Ip, class... _Types>
1567inline _LIBCPP_INLINE_VISIBILITY
1568constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1569get_if(variant<_Types...>* __v) noexcept {
1570 static_assert(_Ip < sizeof...(_Types));
1571 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1572 return __generic_get_if<_Ip>(__v);
1573}
1574
1575template <size_t _Ip, class... _Types>
1576inline _LIBCPP_INLINE_VISIBILITY
1577constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1578get_if(const variant<_Types...>* __v) noexcept {
1579 static_assert(_Ip < sizeof...(_Types));
1580 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1581 return __generic_get_if<_Ip>(__v);
1582}
1583
1584template <class _Tp, class... _Types>
1585inline _LIBCPP_INLINE_VISIBILITY
1586constexpr add_pointer_t<_Tp>
1587get_if(variant<_Types...>* __v) noexcept {
1588 static_assert(!is_void_v<_Tp>);
1589 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1590}
1591
1592template <class _Tp, class... _Types>
1593inline _LIBCPP_INLINE_VISIBILITY
1594constexpr add_pointer_t<const _Tp>
1595get_if(const variant<_Types...>* __v) noexcept {
1596 static_assert(!is_void_v<_Tp>);
1597 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1598}
1599
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001600template <class _Operator>
1601struct __convert_to_bool {
1602 template <class _T1, class _T2>
1603 _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
1604 static_assert(std::is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
1605 "the relational operator does not return a type which is implicitly convertible to bool");
1606 return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
1607 }
1608};
1609
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001610template <class... _Types>
1611inline _LIBCPP_INLINE_VISIBILITY
1612constexpr bool operator==(const variant<_Types...>& __lhs,
1613 const variant<_Types...>& __rhs) {
1614 using __variant_detail::__visitation::__variant;
1615 if (__lhs.index() != __rhs.index()) return false;
1616 if (__lhs.valueless_by_exception()) return true;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001617 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001618}
1619
1620template <class... _Types>
1621inline _LIBCPP_INLINE_VISIBILITY
1622constexpr bool operator!=(const variant<_Types...>& __lhs,
1623 const variant<_Types...>& __rhs) {
1624 using __variant_detail::__visitation::__variant;
1625 if (__lhs.index() != __rhs.index()) return true;
1626 if (__lhs.valueless_by_exception()) return false;
1627 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001628 __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001629}
1630
1631template <class... _Types>
1632inline _LIBCPP_INLINE_VISIBILITY
1633constexpr bool operator<(const variant<_Types...>& __lhs,
1634 const variant<_Types...>& __rhs) {
1635 using __variant_detail::__visitation::__variant;
1636 if (__rhs.valueless_by_exception()) return false;
1637 if (__lhs.valueless_by_exception()) return true;
1638 if (__lhs.index() < __rhs.index()) return true;
1639 if (__lhs.index() > __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001640 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001641}
1642
1643template <class... _Types>
1644inline _LIBCPP_INLINE_VISIBILITY
1645constexpr bool operator>(const variant<_Types...>& __lhs,
1646 const variant<_Types...>& __rhs) {
1647 using __variant_detail::__visitation::__variant;
1648 if (__lhs.valueless_by_exception()) return false;
1649 if (__rhs.valueless_by_exception()) return true;
1650 if (__lhs.index() > __rhs.index()) return true;
1651 if (__lhs.index() < __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001652 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001653}
1654
1655template <class... _Types>
1656inline _LIBCPP_INLINE_VISIBILITY
1657constexpr bool operator<=(const variant<_Types...>& __lhs,
1658 const variant<_Types...>& __rhs) {
1659 using __variant_detail::__visitation::__variant;
1660 if (__lhs.valueless_by_exception()) return true;
1661 if (__rhs.valueless_by_exception()) return false;
1662 if (__lhs.index() < __rhs.index()) return true;
1663 if (__lhs.index() > __rhs.index()) return false;
1664 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001665 __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001666}
1667
1668template <class... _Types>
1669inline _LIBCPP_INLINE_VISIBILITY
1670constexpr bool operator>=(const variant<_Types...>& __lhs,
1671 const variant<_Types...>& __rhs) {
1672 using __variant_detail::__visitation::__variant;
1673 if (__rhs.valueless_by_exception()) return true;
1674 if (__lhs.valueless_by_exception()) return false;
1675 if (__lhs.index() > __rhs.index()) return true;
1676 if (__lhs.index() < __rhs.index()) return false;
1677 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001678 __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001679}
1680
Michael Parkeac50dd2020-10-26 12:34:22 -04001681template <class _Vis, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001682inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001683_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Michael Parkeac50dd2020-10-26 12:34:22 -04001684constexpr decltype(auto) visit(_Vis&& __vis, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001685 using __variant_detail::__visitation::__variant;
Michael Parkeac50dd2020-10-26 12:34:22 -04001686 return __variant::__visit_value(_VSTD::forward<_Vis>(__vis),
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001687 _VSTD::forward<_Vs>(__vs)...);
1688}
1689
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001690struct _LIBCPP_TEMPLATE_VIS monostate {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001691
1692inline _LIBCPP_INLINE_VISIBILITY
1693constexpr bool operator<(monostate, monostate) noexcept { return false; }
1694
1695inline _LIBCPP_INLINE_VISIBILITY
1696constexpr bool operator>(monostate, monostate) noexcept { return false; }
1697
1698inline _LIBCPP_INLINE_VISIBILITY
1699constexpr bool operator<=(monostate, monostate) noexcept { return true; }
1700
1701inline _LIBCPP_INLINE_VISIBILITY
1702constexpr bool operator>=(monostate, monostate) noexcept { return true; }
1703
1704inline _LIBCPP_INLINE_VISIBILITY
1705constexpr bool operator==(monostate, monostate) noexcept { return true; }
1706
1707inline _LIBCPP_INLINE_VISIBILITY
1708constexpr bool operator!=(monostate, monostate) noexcept { return false; }
1709
1710template <class... _Types>
1711inline _LIBCPP_INLINE_VISIBILITY
1712auto swap(variant<_Types...>& __lhs,
1713 variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs)))
1714 -> decltype(__lhs.swap(__rhs)) {
1715 __lhs.swap(__rhs);
1716}
1717
1718template <class... _Types>
Eric Fiselier698a97b2017-01-21 00:02:12 +00001719struct _LIBCPP_TEMPLATE_VIS hash<
1720 __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001721 using argument_type = variant<_Types...>;
1722 using result_type = size_t;
1723
1724 inline _LIBCPP_INLINE_VISIBILITY
1725 result_type operator()(const argument_type& __v) const {
1726 using __variant_detail::__visitation::__variant;
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001727 size_t __res =
1728 __v.valueless_by_exception()
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001729 ? 299792458 // Random value chosen by the universe upon creation
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001730 : __variant::__visit_alt(
1731 [](const auto& __alt) {
Marshall Clowe61ba952018-02-12 15:41:25 +00001732 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier698a97b2017-01-21 00:02:12 +00001733 using __value_type = remove_const_t<
1734 typename __alt_type::__value_type>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001735 return hash<__value_type>{}(__alt.__value);
1736 },
1737 __v);
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001738 return __hash_combine(__res, hash<size_t>{}(__v.index()));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001739 }
1740};
1741
1742template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001743struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001744 using argument_type = monostate;
1745 using result_type = size_t;
1746
1747 inline _LIBCPP_INLINE_VISIBILITY
Marshall Clow49036892017-03-23 02:40:28 +00001748 result_type operator()(const argument_type&) const _NOEXCEPT {
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001749 return 66740831; // return a fundamentally attractive random value.
1750 }
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001751};
1752
1753#endif // _LIBCPP_STD_VER > 14
1754
1755_LIBCPP_END_NAMESPACE_STD
1756
Eric Fiselier8625d332017-11-19 04:57:22 +00001757_LIBCPP_POP_MACROS
1758
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001759#endif // _LIBCPP_VARIANT