blob: ea120d49f079f64862cf22e52cdc380dffc0e7af [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
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500172 template <class R, class Visitor, class... Variants>
173 constexpr R visit(Visitor&&, Variants&&...); // since C++20
174
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000175 // 20.7.7, class monostate
176 struct monostate;
177
178 // 20.7.8, monostate relational operators
179 constexpr bool operator<(monostate, monostate) noexcept;
180 constexpr bool operator>(monostate, monostate) noexcept;
181 constexpr bool operator<=(monostate, monostate) noexcept;
182 constexpr bool operator>=(monostate, monostate) noexcept;
183 constexpr bool operator==(monostate, monostate) noexcept;
184 constexpr bool operator!=(monostate, monostate) noexcept;
185
186 // 20.7.9, specialized algorithms
187 template <class... Types>
188 void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
189
190 // 20.7.10, class bad_variant_access
191 class bad_variant_access;
192
193 // 20.7.11, hash support
194 template <class T> struct hash;
195 template <class... Types> struct hash<variant<Types...>>;
196 template <> struct hash<monostate>;
197
198} // namespace std
199
200*/
201
Louis Dionne73912b22020-11-04 15:01:25 -0500202#include <__availability>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400203#include <__config>
zoecarver6eb71a92021-05-27 09:23:19 -0700204#include <__functional/hash.h>
205#include <__tuple>
Christopher Di Bella41f26e82021-06-05 02:47:47 +0000206#include <__utility/forward.h>
Mark de Wever3b269752021-07-07 21:27:27 +0200207#include <__variant/monostate.h>
Arthur O'Dwyer7deec122021-03-24 18:19:12 -0400208#include <compare>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000209#include <exception>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000210#include <initializer_list>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400211#include <limits>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000212#include <new>
213#include <tuple>
214#include <type_traits>
215#include <utility>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000216#include <version>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000217
218#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
219#pragma GCC system_header
220#endif
221
Eric Fiselier8625d332017-11-19 04:57:22 +0000222_LIBCPP_PUSH_MACROS
223#include <__undef_macros>
224
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000225namespace std { // explicitly not using versioning namespace
226
Louis Dionnecef92e62018-11-19 15:37:04 +0000227class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000228public:
Saleem Abdulrasool5ee83382016-12-31 17:34:26 +0000229 virtual const char* what() const _NOEXCEPT;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000230};
231
232} // namespace std
233
234_LIBCPP_BEGIN_NAMESPACE_STD
235
Louis Dionne3e0c4332021-08-31 10:49:06 -0400236#if _LIBCPP_STD_VER > 14
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000237
zoecarver647e31c2021-07-07 15:25:53 -0700238// Light N-dimensional array of function pointers. Used in place of std::array to avoid
239// adding a dependency.
240template<class _Tp, size_t _Size>
241struct __farray {
242 static_assert(_Size > 0, "N-dimensional array should never be empty in std::visit");
243 _Tp __buf_[_Size] = {};
244
245 _LIBCPP_INLINE_VISIBILITY constexpr
246 const _Tp &operator[](size_t __n) const noexcept {
247 return __buf_[__n];
248 }
249};
250
Eric Fiselier10642ea2016-12-03 01:58:07 +0000251_LIBCPP_NORETURN
252inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +0000253_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier10642ea2016-12-03 01:58:07 +0000254void __throw_bad_variant_access() {
255#ifndef _LIBCPP_NO_EXCEPTIONS
256 throw bad_variant_access();
257#else
258 _VSTD::abort();
259#endif
260}
261
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000262template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000263class _LIBCPP_TEMPLATE_VIS variant;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000264
265template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000266struct _LIBCPP_TEMPLATE_VIS variant_size;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000267
268template <class _Tp>
Louis Dionne559be102021-09-22 09:35:32 -0400269inline constexpr size_t variant_size_v = variant_size<_Tp>::value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000270
271template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000272struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000273
274template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000275struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000276
277template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000278struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000279 : variant_size<_Tp> {};
280
281template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000282struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000283 : integral_constant<size_t, sizeof...(_Types)> {};
284
285template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000286struct _LIBCPP_TEMPLATE_VIS variant_alternative;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000287
288template <size_t _Ip, class _Tp>
289using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;
290
291template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000292struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000293 : add_const<variant_alternative_t<_Ip, _Tp>> {};
294
295template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000296struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000297 : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
298
299template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000300struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000301 : add_cv<variant_alternative_t<_Ip, _Tp>> {};
302
303template <size_t _Ip, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000304struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
Marshall Clow185577f2017-06-12 16:13:17 +0000305 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000306 using type = __type_pack_element<_Ip, _Types...>;
307};
308
Louis Dionne559be102021-09-22 09:35:32 -0400309inline constexpr size_t variant_npos = static_cast<size_t>(-1);
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000310
311constexpr int __choose_index_type(unsigned int __num_elem) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500312 if (__num_elem < numeric_limits<unsigned char>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000313 return 0;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500314 if (__num_elem < numeric_limits<unsigned short>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000315 return 1;
316 return 2;
317}
318
319template <size_t _NumAlts>
320using __variant_index_t =
321#ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
322 unsigned int;
323#else
324 std::tuple_element_t<
325 __choose_index_type(_NumAlts),
326 std::tuple<unsigned char, unsigned short, unsigned int>
327 >;
328#endif
329
330template <class _IndexType>
331constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000332
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100333template <class... _Types>
334class _LIBCPP_TEMPLATE_VIS variant;
335
336template <class... _Types>
337_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&
338__as_variant(variant<_Types...>& __vs) noexcept {
339 return __vs;
340}
341
342template <class... _Types>
343_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&
344__as_variant(const variant<_Types...>& __vs) noexcept {
345 return __vs;
346}
347
348template <class... _Types>
349_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&&
350__as_variant(variant<_Types...>&& __vs) noexcept {
351 return _VSTD::move(__vs);
352}
353
354template <class... _Types>
355_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&&
356__as_variant(const variant<_Types...>&& __vs) noexcept {
357 return _VSTD::move(__vs);
358}
359
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000360namespace __find_detail {
361
362template <class _Tp, class... _Types>
363inline _LIBCPP_INLINE_VISIBILITY
364constexpr size_t __find_index() {
365 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
366 size_t __result = __not_found;
367 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
368 if (__matches[__i]) {
369 if (__result != __not_found) {
370 return __ambiguous;
371 }
372 __result = __i;
373 }
374 }
375 return __result;
376}
377
378template <size_t _Index>
379struct __find_unambiguous_index_sfinae_impl
380 : integral_constant<size_t, _Index> {};
381
382template <>
383struct __find_unambiguous_index_sfinae_impl<__not_found> {};
384
385template <>
386struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
387
388template <class _Tp, class... _Types>
389struct __find_unambiguous_index_sfinae
390 : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};
391
392} // namespace __find_detail
393
394namespace __variant_detail {
395
396struct __valueless_t {};
397
398enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
399
Eric Fiselier87994112020-11-17 17:34:23 -0500400template <typename _Tp,
401 template <typename> class _IsTriviallyAvailable,
402 template <typename> class _IsAvailable>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000403constexpr _Trait __trait =
404 _IsTriviallyAvailable<_Tp>::value
405 ? _Trait::_TriviallyAvailable
406 : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
407
408inline _LIBCPP_INLINE_VISIBILITY
409constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
410 _Trait __result = _Trait::_TriviallyAvailable;
411 for (_Trait __t : __traits) {
412 if (static_cast<int>(__t) > static_cast<int>(__result)) {
413 __result = __t;
414 }
415 }
416 return __result;
417}
418
Eric Fiselier87994112020-11-17 17:34:23 -0500419template <typename... _Types>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000420struct __traits {
421 static constexpr _Trait __copy_constructible_trait =
422 __common_trait({__trait<_Types,
423 is_trivially_copy_constructible,
424 is_copy_constructible>...});
425
426 static constexpr _Trait __move_constructible_trait =
427 __common_trait({__trait<_Types,
428 is_trivially_move_constructible,
429 is_move_constructible>...});
430
431 static constexpr _Trait __copy_assignable_trait = __common_trait(
432 {__copy_constructible_trait,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000433 __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
434
435 static constexpr _Trait __move_assignable_trait = __common_trait(
436 {__move_constructible_trait,
437 __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
438
439 static constexpr _Trait __destructible_trait = __common_trait(
440 {__trait<_Types, is_trivially_destructible, is_destructible>...});
441};
442
443namespace __access {
444
445struct __union {
446 template <class _Vp>
447 inline _LIBCPP_INLINE_VISIBILITY
448 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
449 return _VSTD::forward<_Vp>(__v).__head;
450 }
451
452 template <class _Vp, size_t _Ip>
453 inline _LIBCPP_INLINE_VISIBILITY
454 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
455 return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
456 }
457};
458
459struct __base {
460 template <size_t _Ip, class _Vp>
461 inline _LIBCPP_INLINE_VISIBILITY
462 static constexpr auto&& __get_alt(_Vp&& __v) {
463 return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
464 in_place_index<_Ip>);
465 }
466};
467
468struct __variant {
469 template <size_t _Ip, class _Vp>
470 inline _LIBCPP_INLINE_VISIBILITY
471 static constexpr auto&& __get_alt(_Vp&& __v) {
472 return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl);
473 }
474};
475
476} // namespace __access
477
478namespace __visitation {
479
480struct __base {
Eric Fiselier87994112020-11-17 17:34:23 -0500481 template <class _Visitor, class... _Vs>
482 inline _LIBCPP_INLINE_VISIBILITY
483 static constexpr decltype(auto)
484 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
485 constexpr auto __fdiagonal =
486 __make_fdiagonal<_Visitor&&,
487 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
488 return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor),
489 _VSTD::forward<_Vs>(__vs).__as_base()...);
490 }
491
492 template <class _Visitor, class... _Vs>
493 inline _LIBCPP_INLINE_VISIBILITY
494 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
495 _Vs&&... __vs) {
496 constexpr auto __fmatrix =
497 __make_fmatrix<_Visitor&&,
498 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
499 return __at(__fmatrix, __vs.index()...)(
500 _VSTD::forward<_Visitor>(__visitor),
501 _VSTD::forward<_Vs>(__vs).__as_base()...);
502 }
503
504private:
505 template <class _Tp>
506 inline _LIBCPP_INLINE_VISIBILITY
507 static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }
508
509 template <class _Tp, size_t _Np, typename... _Indices>
510 inline _LIBCPP_INLINE_VISIBILITY
zoecarver647e31c2021-07-07 15:25:53 -0700511 static constexpr auto&& __at(const __farray<_Tp, _Np>& __elems,
Eric Fiselier87994112020-11-17 17:34:23 -0500512 size_t __index, _Indices... __indices) {
513 return __at(__elems[__index], __indices...);
514 }
515
516 template <class _Fp, class... _Fs>
517 static constexpr void __std_visit_visitor_return_type_check() {
518 static_assert(
519 __all<is_same_v<_Fp, _Fs>...>::value,
520 "`std::visit` requires the visitor to have a single return type.");
521 }
522
523 template <class... _Fs>
524 inline _LIBCPP_INLINE_VISIBILITY
525 static constexpr auto __make_farray(_Fs&&... __fs) {
526 __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
zoecarver647e31c2021-07-07 15:25:53 -0700527 using __result = __farray<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
Eric Fiselier87994112020-11-17 17:34:23 -0500528 return __result{{_VSTD::forward<_Fs>(__fs)...}};
529 }
530
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500531 template <size_t... _Is>
Eric Fiselier87994112020-11-17 17:34:23 -0500532 struct __dispatcher {
533 template <class _Fp, class... _Vs>
Michael Park32334da2020-08-30 12:42:35 -0400534 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500535 static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500536 return _VSTD::__invoke_constexpr(
Eric Fiselier87994112020-11-17 17:34:23 -0500537 static_cast<_Fp>(__f),
538 __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
Michael Park32334da2020-08-30 12:42:35 -0400539 }
540 };
541
Eric Fiselier87994112020-11-17 17:34:23 -0500542 template <class _Fp, class... _Vs, size_t... _Is>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000543 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500544 static constexpr auto __make_dispatch(index_sequence<_Is...>) {
545 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000546 }
547
Eric Fiselier87994112020-11-17 17:34:23 -0500548 template <size_t _Ip, class _Fp, class... _Vs>
549 inline _LIBCPP_INLINE_VISIBILITY
550 static constexpr auto __make_fdiagonal_impl() {
551 return __make_dispatch<_Fp, _Vs...>(
Yuanfang Chen0a31a2e2021-09-21 15:05:12 -0700552 index_sequence<((void)__identity<_Vs>{}, _Ip)...>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000553 }
Eric Fiselier87994112020-11-17 17:34:23 -0500554
555 template <class _Fp, class... _Vs, size_t... _Is>
556 inline _LIBCPP_INLINE_VISIBILITY
557 static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
558 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
559 }
560
561 template <class _Fp, class _Vp, class... _Vs>
562 inline _LIBCPP_INLINE_VISIBILITY
563 static constexpr auto __make_fdiagonal() {
564 constexpr size_t _Np = __uncvref_t<_Vp>::__size();
565 static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
566 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
567 }
568
569 template <class _Fp, class... _Vs, size_t... _Is>
570 inline _LIBCPP_INLINE_VISIBILITY
571 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
572 return __make_dispatch<_Fp, _Vs...>(__is);
573 }
574
575 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
576 inline _LIBCPP_INLINE_VISIBILITY
577 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,
578 index_sequence<_Js...>,
579 _Ls... __ls) {
580 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(
581 index_sequence<_Is..., _Js>{}, __ls...)...);
582 }
583
584 template <class _Fp, class... _Vs>
585 inline _LIBCPP_INLINE_VISIBILITY
586 static constexpr auto __make_fmatrix() {
587 return __make_fmatrix_impl<_Fp, _Vs...>(
588 index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000589 }
590};
591
592struct __variant {
Eric Fiselier87994112020-11-17 17:34:23 -0500593 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000594 inline _LIBCPP_INLINE_VISIBILITY
595 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500596 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000597 return __base::__visit_alt_at(__index,
Eric Fiselier87994112020-11-17 17:34:23 -0500598 _VSTD::forward<_Visitor>(__visitor),
599 _VSTD::forward<_Vs>(__vs).__impl...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000600 }
601
Eric Fiselier87994112020-11-17 17:34:23 -0500602 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000603 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500604 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
605 _Vs&&... __vs) {
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100606 return __base::__visit_alt(
607 _VSTD::forward<_Visitor>(__visitor),
608 _VSTD::__as_variant(_VSTD::forward<_Vs>(__vs)).__impl...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000609 }
610
Eric Fiselier87994112020-11-17 17:34:23 -0500611 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000612 inline _LIBCPP_INLINE_VISIBILITY
613 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500614 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
615 return __visit_alt_at(
616 __index,
617 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
618 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000619 }
620
Eric Fiselier87994112020-11-17 17:34:23 -0500621 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000622 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500623 static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,
624 _Vs&&... __vs) {
625 return __visit_alt(
626 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
627 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000628 }
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100629
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500630#if _LIBCPP_STD_VER > 17
631 template <class _Rp, class _Visitor, class... _Vs>
632 inline _LIBCPP_INLINE_VISIBILITY
633 static constexpr _Rp __visit_value(_Visitor&& __visitor,
634 _Vs&&... __vs) {
635 return __visit_alt(
636 __make_value_visitor<_Rp>(_VSTD::forward<_Visitor>(__visitor)),
637 _VSTD::forward<_Vs>(__vs)...);
638 }
639#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000640
641private:
Eric Fiselier87994112020-11-17 17:34:23 -0500642 template <class _Visitor, class... _Values>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000643 static constexpr void __std_visit_exhaustive_visitor_check() {
Eric Fiselier87994112020-11-17 17:34:23 -0500644 static_assert(is_invocable_v<_Visitor, _Values...>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000645 "`std::visit` requires the visitor to be exhaustive.");
646 }
647
Eric Fiselier87994112020-11-17 17:34:23 -0500648 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000649 struct __value_visitor {
650 template <class... _Alts>
651 inline _LIBCPP_INLINE_VISIBILITY
652 constexpr decltype(auto) operator()(_Alts&&... __alts) const {
653 __std_visit_exhaustive_visitor_check<
Eric Fiselier87994112020-11-17 17:34:23 -0500654 _Visitor,
655 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500656 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000657 _VSTD::forward<_Alts>(__alts).__value...);
658 }
Eric Fiselier87994112020-11-17 17:34:23 -0500659 _Visitor&& __visitor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000660 };
661
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500662#if _LIBCPP_STD_VER > 17
663 template <class _Rp, class _Visitor>
664 struct __value_visitor_return_type {
665 template <class... _Alts>
666 inline _LIBCPP_INLINE_VISIBILITY
667 constexpr _Rp operator()(_Alts&&... __alts) const {
668 __std_visit_exhaustive_visitor_check<
669 _Visitor,
670 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
671 if constexpr (is_void_v<_Rp>) {
672 _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
673 _VSTD::forward<_Alts>(__alts).__value...);
674 }
675 else {
676 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
677 _VSTD::forward<_Alts>(__alts).__value...);
678 }
679 }
680
681 _Visitor&& __visitor;
682 };
683#endif
684
Eric Fiselier87994112020-11-17 17:34:23 -0500685 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000686 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500687 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
688 return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000689 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500690
691#if _LIBCPP_STD_VER > 17
692 template <class _Rp, class _Visitor>
693 inline _LIBCPP_INLINE_VISIBILITY
694 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
695 return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)};
696 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500697#endif
Nico Weber8aa36612021-01-25 15:10:41 -0500698};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000699
700} // namespace __visitation
701
702template <size_t _Index, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000703struct _LIBCPP_TEMPLATE_VIS __alt {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000704 using __value_type = _Tp;
705
706 template <class... _Args>
707 inline _LIBCPP_INLINE_VISIBILITY
708 explicit constexpr __alt(in_place_t, _Args&&... __args)
709 : __value(_VSTD::forward<_Args>(__args)...) {}
710
711 __value_type __value;
712};
713
714template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000715union _LIBCPP_TEMPLATE_VIS __union;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000716
717template <_Trait _DestructibleTrait, size_t _Index>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000718union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000719
720#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
721 template <size_t _Index, class _Tp, class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500722 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000723 _Index, \
724 _Tp, \
725 _Types...> { \
726 public: \
727 inline _LIBCPP_INLINE_VISIBILITY \
728 explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
729 \
730 template <class... _Args> \
731 inline _LIBCPP_INLINE_VISIBILITY \
732 explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
733 : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
734 \
735 template <size_t _Ip, class... _Args> \
736 inline _LIBCPP_INLINE_VISIBILITY \
737 explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
738 : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
739 \
740 __union(const __union&) = default; \
741 __union(__union&&) = default; \
742 \
743 destructor \
744 \
745 __union& operator=(const __union&) = default; \
746 __union& operator=(__union&&) = default; \
747 \
748 private: \
749 char __dummy; \
750 __alt<_Index, _Tp> __head; \
751 __union<destructible_trait, _Index + 1, _Types...> __tail; \
752 \
753 friend struct __access::__union; \
754 }
755
756_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
757_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {});
758_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
759
760#undef _LIBCPP_VARIANT_UNION
761
762template <_Trait _DestructibleTrait, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000763class _LIBCPP_TEMPLATE_VIS __base {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000764public:
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000765 using __index_t = __variant_index_t<sizeof...(_Types)>;
766
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000767 inline _LIBCPP_INLINE_VISIBILITY
768 explicit constexpr __base(__valueless_t tag) noexcept
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000769 : __data(tag), __index(__variant_npos<__index_t>) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000770
771 template <size_t _Ip, class... _Args>
772 inline _LIBCPP_INLINE_VISIBILITY
773 explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
Eric Fiselier2adf0872016-12-02 23:17:33 +0000774 :
775 __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
776 __index(_Ip) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000777
778 inline _LIBCPP_INLINE_VISIBILITY
779 constexpr bool valueless_by_exception() const noexcept {
780 return index() == variant_npos;
781 }
782
783 inline _LIBCPP_INLINE_VISIBILITY
784 constexpr size_t index() const noexcept {
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000785 return __index == __variant_npos<__index_t> ? variant_npos : __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000786 }
787
788protected:
789 inline _LIBCPP_INLINE_VISIBILITY
790 constexpr auto&& __as_base() & { return *this; }
791
792 inline _LIBCPP_INLINE_VISIBILITY
793 constexpr auto&& __as_base() && { return _VSTD::move(*this); }
794
795 inline _LIBCPP_INLINE_VISIBILITY
796 constexpr auto&& __as_base() const & { return *this; }
797
798 inline _LIBCPP_INLINE_VISIBILITY
799 constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
800
801 inline _LIBCPP_INLINE_VISIBILITY
802 static constexpr size_t __size() { return sizeof...(_Types); }
803
804 __union<_DestructibleTrait, 0, _Types...> __data;
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000805 __index_t __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000806
807 friend struct __access::__base;
808 friend struct __visitation::__base;
809};
810
811template <class _Traits, _Trait = _Traits::__destructible_trait>
Louis Dionneff05add2020-10-05 16:30:23 -0400812class _LIBCPP_TEMPLATE_VIS __dtor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000813
814#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \
815 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400816 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, \
817 destructible_trait> \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000818 : public __base<destructible_trait, _Types...> { \
819 using __base_type = __base<destructible_trait, _Types...>; \
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000820 using __index_t = typename __base_type::__index_t; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000821 \
822 public: \
823 using __base_type::__base_type; \
824 using __base_type::operator=; \
825 \
Louis Dionneff05add2020-10-05 16:30:23 -0400826 __dtor(const __dtor&) = default; \
827 __dtor(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000828 destructor \
Louis Dionneff05add2020-10-05 16:30:23 -0400829 __dtor& operator=(const __dtor&) = default; \
830 __dtor& operator=(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000831 \
832 protected: \
833 inline _LIBCPP_INLINE_VISIBILITY \
834 destroy \
835 }
836
837_LIBCPP_VARIANT_DESTRUCTOR(
838 _Trait::_TriviallyAvailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400839 ~__dtor() = default;,
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000840 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000841
842_LIBCPP_VARIANT_DESTRUCTOR(
843 _Trait::_Available,
Louis Dionneff05add2020-10-05 16:30:23 -0400844 ~__dtor() { __destroy(); },
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000845 void __destroy() noexcept {
846 if (!this->valueless_by_exception()) {
847 __visitation::__base::__visit_alt(
848 [](auto& __alt) noexcept {
Marshall Clowe61ba952018-02-12 15:41:25 +0000849 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000850 __alt.~__alt_type();
851 },
852 *this);
853 }
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000854 this->__index = __variant_npos<__index_t>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000855 });
856
857_LIBCPP_VARIANT_DESTRUCTOR(
858 _Trait::_Unavailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400859 ~__dtor() = delete;,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000860 void __destroy() noexcept = delete;);
861
862#undef _LIBCPP_VARIANT_DESTRUCTOR
863
864template <class _Traits>
Louis Dionneff05add2020-10-05 16:30:23 -0400865class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> {
866 using __base_type = __dtor<_Traits>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000867
868public:
869 using __base_type::__base_type;
870 using __base_type::operator=;
871
872protected:
873 template <size_t _Ip, class _Tp, class... _Args>
874 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000875 static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
Eric Fiselier87994112020-11-17 17:34:23 -0500876 ::new ((void*)_VSTD::addressof(__a))
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000877 __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
Eric Fiselier87994112020-11-17 17:34:23 -0500878 return __a.__value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000879 }
880
881 template <class _Rhs>
882 inline _LIBCPP_INLINE_VISIBILITY
Louis Dionneff05add2020-10-05 16:30:23 -0400883 static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000884 __lhs.__destroy();
885 if (!__rhs.valueless_by_exception()) {
886 __visitation::__base::__visit_alt_at(
887 __rhs.index(),
888 [](auto& __lhs_alt, auto&& __rhs_alt) {
889 __construct_alt(
890 __lhs_alt,
891 _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
892 },
893 __lhs, _VSTD::forward<_Rhs>(__rhs));
894 __lhs.__index = __rhs.index();
895 }
896 }
897};
898
899template <class _Traits, _Trait = _Traits::__move_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000900class _LIBCPP_TEMPLATE_VIS __move_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000901
902#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \
903 move_constructor) \
904 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400905 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \
906 move_constructible_trait> \
907 : public __ctor<__traits<_Types...>> { \
908 using __base_type = __ctor<__traits<_Types...>>; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000909 \
910 public: \
911 using __base_type::__base_type; \
912 using __base_type::operator=; \
913 \
914 __move_constructor(const __move_constructor&) = default; \
915 move_constructor \
916 ~__move_constructor() = default; \
917 __move_constructor& operator=(const __move_constructor&) = default; \
918 __move_constructor& operator=(__move_constructor&&) = default; \
919 }
920
921_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
922 _Trait::_TriviallyAvailable,
923 __move_constructor(__move_constructor&& __that) = default;);
924
925_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
926 _Trait::_Available,
927 __move_constructor(__move_constructor&& __that) noexcept(
928 __all<is_nothrow_move_constructible_v<_Types>...>::value)
929 : __move_constructor(__valueless_t{}) {
930 this->__generic_construct(*this, _VSTD::move(__that));
931 });
932
933_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
934 _Trait::_Unavailable,
935 __move_constructor(__move_constructor&&) = delete;);
936
937#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
938
939template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000940class _LIBCPP_TEMPLATE_VIS __copy_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000941
942#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
943 copy_constructor) \
944 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500945 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000946 copy_constructible_trait> \
947 : public __move_constructor<__traits<_Types...>> { \
948 using __base_type = __move_constructor<__traits<_Types...>>; \
949 \
950 public: \
951 using __base_type::__base_type; \
952 using __base_type::operator=; \
953 \
954 copy_constructor \
955 __copy_constructor(__copy_constructor&&) = default; \
956 ~__copy_constructor() = default; \
957 __copy_constructor& operator=(const __copy_constructor&) = default; \
958 __copy_constructor& operator=(__copy_constructor&&) = default; \
959 }
960
961_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
962 _Trait::_TriviallyAvailable,
963 __copy_constructor(const __copy_constructor& __that) = default;);
964
965_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
966 _Trait::_Available,
967 __copy_constructor(const __copy_constructor& __that)
968 : __copy_constructor(__valueless_t{}) {
969 this->__generic_construct(*this, __that);
970 });
971
972_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
973 _Trait::_Unavailable,
974 __copy_constructor(const __copy_constructor&) = delete;);
975
976#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
977
978template <class _Traits>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000979class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000980 using __base_type = __copy_constructor<_Traits>;
981
982public:
983 using __base_type::__base_type;
984 using __base_type::operator=;
985
986 template <size_t _Ip, class... _Args>
987 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000988 auto& __emplace(_Args&&... __args) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000989 this->__destroy();
Eric Fiselier62928442017-04-15 19:32:02 +0000990 auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
Eric Fiselier87994112020-11-17 17:34:23 -0500991 _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000992 this->__index = _Ip;
Eric Fiselier62928442017-04-15 19:32:02 +0000993 return __res;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000994 }
995
996protected:
Michael Park62118352017-06-07 10:22:43 +0000997 template <size_t _Ip, class _Tp, class _Arg>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000998 inline _LIBCPP_INLINE_VISIBILITY
Michael Park62118352017-06-07 10:22:43 +0000999 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001000 if (this->index() == _Ip) {
1001 __a.__value = _VSTD::forward<_Arg>(__arg);
1002 } else {
1003 struct {
1004 void operator()(true_type) const {
Michael Park62118352017-06-07 10:22:43 +00001005 __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001006 }
1007 void operator()(false_type) const {
Michael Park62118352017-06-07 10:22:43 +00001008 __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001009 }
1010 __assignment* __this;
1011 _Arg&& __arg;
1012 } __impl{this, _VSTD::forward<_Arg>(__arg)};
Michael Park62118352017-06-07 10:22:43 +00001013 __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||
1014 !is_nothrow_move_constructible_v<_Tp>>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001015 }
1016 }
1017
1018 template <class _That>
1019 inline _LIBCPP_INLINE_VISIBILITY
1020 void __generic_assign(_That&& __that) {
1021 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1022 // do nothing.
1023 } else if (__that.valueless_by_exception()) {
1024 this->__destroy();
1025 } else {
1026 __visitation::__base::__visit_alt_at(
1027 __that.index(),
1028 [this](auto& __this_alt, auto&& __that_alt) {
1029 this->__assign_alt(
1030 __this_alt,
Michael Park62118352017-06-07 10:22:43 +00001031 _VSTD::forward<decltype(__that_alt)>(__that_alt).__value);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001032 },
1033 *this, _VSTD::forward<_That>(__that));
1034 }
1035 }
1036};
1037
1038template <class _Traits, _Trait = _Traits::__move_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001039class _LIBCPP_TEMPLATE_VIS __move_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001040
1041#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
1042 move_assignment) \
1043 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001044 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001045 move_assignable_trait> \
1046 : public __assignment<__traits<_Types...>> { \
1047 using __base_type = __assignment<__traits<_Types...>>; \
1048 \
1049 public: \
1050 using __base_type::__base_type; \
1051 using __base_type::operator=; \
1052 \
1053 __move_assignment(const __move_assignment&) = default; \
1054 __move_assignment(__move_assignment&&) = default; \
1055 ~__move_assignment() = default; \
1056 __move_assignment& operator=(const __move_assignment&) = default; \
1057 move_assignment \
1058 }
1059
1060_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1061 _Trait::_TriviallyAvailable,
1062 __move_assignment& operator=(__move_assignment&& __that) = default;);
1063
1064_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1065 _Trait::_Available,
1066 __move_assignment& operator=(__move_assignment&& __that) noexcept(
1067 __all<(is_nothrow_move_constructible_v<_Types> &&
1068 is_nothrow_move_assignable_v<_Types>)...>::value) {
1069 this->__generic_assign(_VSTD::move(__that));
1070 return *this;
1071 });
1072
1073_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1074 _Trait::_Unavailable,
1075 __move_assignment& operator=(__move_assignment&&) = delete;);
1076
1077#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
1078
1079template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001080class _LIBCPP_TEMPLATE_VIS __copy_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001081
1082#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
1083 copy_assignment) \
1084 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001085 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001086 copy_assignable_trait> \
1087 : public __move_assignment<__traits<_Types...>> { \
1088 using __base_type = __move_assignment<__traits<_Types...>>; \
1089 \
1090 public: \
1091 using __base_type::__base_type; \
1092 using __base_type::operator=; \
1093 \
1094 __copy_assignment(const __copy_assignment&) = default; \
1095 __copy_assignment(__copy_assignment&&) = default; \
1096 ~__copy_assignment() = default; \
1097 copy_assignment \
1098 __copy_assignment& operator=(__copy_assignment&&) = default; \
1099 }
1100
1101_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1102 _Trait::_TriviallyAvailable,
1103 __copy_assignment& operator=(const __copy_assignment& __that) = default;);
1104
1105_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1106 _Trait::_Available,
1107 __copy_assignment& operator=(const __copy_assignment& __that) {
1108 this->__generic_assign(__that);
1109 return *this;
1110 });
1111
1112_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1113 _Trait::_Unavailable,
1114 __copy_assignment& operator=(const __copy_assignment&) = delete;);
1115
1116#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1117
1118template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001119class _LIBCPP_TEMPLATE_VIS __impl
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001120 : public __copy_assignment<__traits<_Types...>> {
1121 using __base_type = __copy_assignment<__traits<_Types...>>;
1122
1123public:
1124 using __base_type::__base_type;
1125 using __base_type::operator=;
1126
1127 template <size_t _Ip, class _Arg>
1128 inline _LIBCPP_INLINE_VISIBILITY
1129 void __assign(_Arg&& __arg) {
1130 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
Michael Park62118352017-06-07 10:22:43 +00001131 _VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001132 }
1133
1134 inline _LIBCPP_INLINE_VISIBILITY
1135 void __swap(__impl& __that) {
1136 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1137 // do nothing.
1138 } else if (this->index() == __that.index()) {
1139 __visitation::__base::__visit_alt_at(
1140 this->index(),
1141 [](auto& __this_alt, auto& __that_alt) {
1142 using _VSTD::swap;
1143 swap(__this_alt.__value, __that_alt.__value);
1144 },
1145 *this,
1146 __that);
1147 } else {
1148 __impl* __lhs = this;
1149 __impl* __rhs = _VSTD::addressof(__that);
1150 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1151 _VSTD::swap(__lhs, __rhs);
1152 }
1153 __impl __tmp(_VSTD::move(*__rhs));
Michael Park5dee7342020-06-16 15:15:10 -07001154#ifndef _LIBCPP_NO_EXCEPTIONS
Michael Park6a9ef642020-07-08 10:46:02 -07001155 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
Michael Park31967aa2020-06-16 13:29:23 -07001156 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1157 } else {
1158 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1159 // and `__tmp` is nothrow move constructible then we move `__tmp` back
1160 // into `__rhs` and provide the strong exception safety guarantee.
1161 try {
1162 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1163 } catch (...) {
1164 if (__tmp.__move_nothrow()) {
1165 this->__generic_construct(*__rhs, _VSTD::move(__tmp));
1166 }
1167 throw;
1168 }
1169 }
Michael Park5dee7342020-06-16 15:15:10 -07001170#else
1171 // this isn't consolidated with the `if constexpr` branch above due to
1172 // `throw` being ill-formed with exceptions disabled even when discarded.
1173 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1174#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001175 this->__generic_construct(*__lhs, _VSTD::move(__tmp));
1176 }
1177 }
1178
1179private:
1180 inline _LIBCPP_INLINE_VISIBILITY
1181 bool __move_nothrow() const {
1182 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1183 return this->valueless_by_exception() || __results[this->index()];
1184 }
1185};
1186
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001187struct __no_narrowing_check {
1188 template <class _Dest, class _Source>
1189 using _Apply = __identity<_Dest>;
1190};
1191
1192struct __narrowing_check {
1193 template <class _Dest>
1194 static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>;
1195 template <class _Dest, class _Source>
Louis Dionnea6c4ace2021-08-31 10:32:11 -04001196 using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({declval<_Source>()}));
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001197};
1198
1199template <class _Dest, class _Source>
Louis Dionnea6c4ace2021-08-31 10:32:11 -04001200using __check_for_narrowing _LIBCPP_NODEBUG =
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001201 typename _If<
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001202#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
1203 false &&
1204#endif
1205 is_arithmetic<_Dest>::value,
1206 __narrowing_check,
1207 __no_narrowing_check
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001208 >::template _Apply<_Dest, _Source>;
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001209
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001210template <class _Tp, size_t _Idx>
1211struct __overload {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001212 template <class _Up>
Eric Fiselier80f5dfb2019-07-14 18:31:55 +00001213 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001214};
1215
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001216template <class _Tp, size_t>
1217struct __overload_bool {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001218 template <class _Up, class _Ap = __uncvref_t<_Up>>
1219 auto operator()(bool, _Up&&) const
1220 -> enable_if_t<is_same_v<_Ap, bool>, __identity<_Tp>>;
1221};
1222
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001223template <size_t _Idx>
1224struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};
1225template <size_t _Idx>
1226struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};
1227template <size_t _Idx>
1228struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};
1229template <size_t _Idx>
1230struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};
1231
1232template <class ..._Bases>
1233struct __all_overloads : _Bases... {
1234 void operator()() const;
1235 using _Bases::operator()...;
1236};
1237
1238template <class IdxSeq>
1239struct __make_overloads_imp;
1240
1241template <size_t ..._Idx>
1242struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1243 template <class ..._Types>
Louis Dionnea6c4ace2021-08-31 10:32:11 -04001244 using _Apply _LIBCPP_NODEBUG = __all_overloads<__overload<_Types, _Idx>...>;
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001245};
1246
1247template <class ..._Types>
Louis Dionnea6c4ace2021-08-31 10:32:11 -04001248using _MakeOverloads _LIBCPP_NODEBUG = typename __make_overloads_imp<
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001249 __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
Zhihao Yuan821efb82019-06-20 22:09:40 +00001250
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001251template <class _Tp, class... _Types>
Zhihao Yuan821efb82019-06-20 22:09:40 +00001252using __best_match_t =
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001253 typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001254
1255} // __variant_detail
1256
1257template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001258class _LIBCPP_TEMPLATE_VIS variant
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001259 : private __sfinae_ctor_base<
1260 __all<is_copy_constructible_v<_Types>...>::value,
1261 __all<is_move_constructible_v<_Types>...>::value>,
1262 private __sfinae_assign_base<
1263 __all<(is_copy_constructible_v<_Types> &&
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001264 is_copy_assignable_v<_Types>)...>::value,
1265 __all<(is_move_constructible_v<_Types> &&
1266 is_move_assignable_v<_Types>)...>::value> {
1267 static_assert(0 < sizeof...(_Types),
1268 "variant must consist of at least one alternative.");
1269
1270 static_assert(__all<!is_array_v<_Types>...>::value,
1271 "variant can not have an array type as an alternative.");
1272
1273 static_assert(__all<!is_reference_v<_Types>...>::value,
1274 "variant can not have a reference type as an alternative.");
1275
1276 static_assert(__all<!is_void_v<_Types>...>::value,
1277 "variant can not have a void type as an alternative.");
1278
1279 using __first_type = variant_alternative_t<0, variant>;
1280
1281public:
1282 template <bool _Dummy = true,
1283 enable_if_t<__dependent_type<is_default_constructible<__first_type>,
1284 _Dummy>::value,
1285 int> = 0>
1286 inline _LIBCPP_INLINE_VISIBILITY
1287 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
1288 : __impl(in_place_index<0>) {}
1289
1290 variant(const variant&) = default;
1291 variant(variant&&) = default;
1292
1293 template <
1294 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001295 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
1296 enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0,
1297 enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001298 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1299 size_t _Ip =
1300 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1301 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1302 inline _LIBCPP_INLINE_VISIBILITY
1303 constexpr variant(_Arg&& __arg) noexcept(
1304 is_nothrow_constructible_v<_Tp, _Arg>)
1305 : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
1306
1307 template <size_t _Ip, class... _Args,
Eric Fiselier5d2df752018-03-23 23:42:30 +00001308 class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1309 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1310 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001311 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001312 explicit constexpr variant(
1313 in_place_index_t<_Ip>,
1314 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001315 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1316
Eric Fiselier5d2df752018-03-23 23:42:30 +00001317 template <
1318 size_t _Ip,
1319 class _Up,
1320 class... _Args,
1321 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1322 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001323 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1324 int> = 0>
1325 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001326 explicit constexpr variant(
1327 in_place_index_t<_Ip>,
1328 initializer_list<_Up> __il,
1329 _Args&&... __args) noexcept(
1330 is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001331 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1332
1333 template <
1334 class _Tp,
1335 class... _Args,
1336 size_t _Ip =
1337 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1338 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1339 inline _LIBCPP_INLINE_VISIBILITY
1340 explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1341 is_nothrow_constructible_v<_Tp, _Args...>)
1342 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1343
1344 template <
1345 class _Tp,
1346 class _Up,
1347 class... _Args,
1348 size_t _Ip =
1349 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1350 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1351 int> = 0>
1352 inline _LIBCPP_INLINE_VISIBILITY
1353 explicit constexpr variant(
1354 in_place_type_t<_Tp>,
1355 initializer_list<_Up> __il,
1356 _Args&&... __args) noexcept(
1357 is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
1358 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1359
1360 ~variant() = default;
1361
1362 variant& operator=(const variant&) = default;
1363 variant& operator=(variant&&) = default;
1364
1365 template <
1366 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001367 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001368 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1369 size_t _Ip =
1370 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1371 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
1372 int> = 0>
1373 inline _LIBCPP_INLINE_VISIBILITY
1374 variant& operator=(_Arg&& __arg) noexcept(
1375 is_nothrow_assignable_v<_Tp&, _Arg> &&
1376 is_nothrow_constructible_v<_Tp, _Arg>) {
1377 __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg));
1378 return *this;
1379 }
1380
1381 template <
1382 size_t _Ip,
1383 class... _Args,
1384 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1385 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1386 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1387 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001388 _Tp& emplace(_Args&&... __args) {
1389 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001390 }
1391
1392 template <
1393 size_t _Ip,
1394 class _Up,
1395 class... _Args,
1396 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1397 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1398 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1399 int> = 0>
1400 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001401 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1402 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001403 }
1404
1405 template <
1406 class _Tp,
1407 class... _Args,
1408 size_t _Ip =
1409 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1410 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1411 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001412 _Tp& emplace(_Args&&... __args) {
1413 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001414 }
1415
1416 template <
1417 class _Tp,
1418 class _Up,
1419 class... _Args,
1420 size_t _Ip =
1421 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1422 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1423 int> = 0>
1424 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001425 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1426 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001427 }
1428
1429 inline _LIBCPP_INLINE_VISIBILITY
1430 constexpr bool valueless_by_exception() const noexcept {
1431 return __impl.valueless_by_exception();
1432 }
1433
1434 inline _LIBCPP_INLINE_VISIBILITY
1435 constexpr size_t index() const noexcept { return __impl.index(); }
1436
1437 template <
1438 bool _Dummy = true,
1439 enable_if_t<
1440 __all<(
1441 __dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1442 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1443 int> = 0>
1444 inline _LIBCPP_INLINE_VISIBILITY
1445 void swap(variant& __that) noexcept(
1446 __all<(is_nothrow_move_constructible_v<_Types> &&
1447 is_nothrow_swappable_v<_Types>)...>::value) {
1448 __impl.__swap(__that.__impl);
1449 }
1450
1451private:
1452 __variant_detail::__impl<_Types...> __impl;
1453
1454 friend struct __variant_detail::__access::__variant;
1455 friend struct __variant_detail::__visitation::__variant;
1456};
1457
1458template <size_t _Ip, class... _Types>
1459inline _LIBCPP_INLINE_VISIBILITY
1460constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1461 return __v.index() == _Ip;
1462}
1463
1464template <class _Tp, class... _Types>
1465inline _LIBCPP_INLINE_VISIBILITY
1466constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1467 return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1468}
1469
1470template <size_t _Ip, class _Vp>
1471inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001472_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Richard Smith66d1c552018-08-27 21:41:50 +00001473constexpr auto&& __generic_get(_Vp&& __v) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001474 using __variant_detail::__access::__variant;
1475 if (!__holds_alternative<_Ip>(__v)) {
Eric Fiselier10642ea2016-12-03 01:58:07 +00001476 __throw_bad_variant_access();
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001477 }
1478 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1479}
1480
1481template <size_t _Ip, class... _Types>
1482inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001483_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001484constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
1485 variant<_Types...>& __v) {
1486 static_assert(_Ip < sizeof...(_Types));
1487 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1488 return __generic_get<_Ip>(__v);
1489}
1490
1491template <size_t _Ip, class... _Types>
1492inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001493_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001494constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
1495 variant<_Types...>&& __v) {
1496 static_assert(_Ip < sizeof...(_Types));
1497 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1498 return __generic_get<_Ip>(_VSTD::move(__v));
1499}
1500
1501template <size_t _Ip, class... _Types>
1502inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001503_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001504constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
1505 const variant<_Types...>& __v) {
1506 static_assert(_Ip < sizeof...(_Types));
1507 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1508 return __generic_get<_Ip>(__v);
1509}
1510
1511template <size_t _Ip, class... _Types>
1512inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001513_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001514constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
1515 const variant<_Types...>&& __v) {
1516 static_assert(_Ip < sizeof...(_Types));
1517 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1518 return __generic_get<_Ip>(_VSTD::move(__v));
1519}
1520
1521template <class _Tp, class... _Types>
1522inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001523_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001524constexpr _Tp& get(variant<_Types...>& __v) {
1525 static_assert(!is_void_v<_Tp>);
1526 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1527}
1528
1529template <class _Tp, class... _Types>
1530inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001531_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001532constexpr _Tp&& get(variant<_Types...>&& __v) {
1533 static_assert(!is_void_v<_Tp>);
1534 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1535 _VSTD::move(__v));
1536}
1537
1538template <class _Tp, class... _Types>
1539inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001540_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001541constexpr const _Tp& get(const variant<_Types...>& __v) {
1542 static_assert(!is_void_v<_Tp>);
1543 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1544}
1545
1546template <class _Tp, class... _Types>
1547inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001548_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001549constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1550 static_assert(!is_void_v<_Tp>);
1551 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1552 _VSTD::move(__v));
1553}
1554
1555template <size_t _Ip, class _Vp>
1556inline _LIBCPP_INLINE_VISIBILITY
1557constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1558 using __variant_detail::__access::__variant;
1559 return __v && __holds_alternative<_Ip>(*__v)
1560 ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value)
1561 : nullptr;
1562}
1563
1564template <size_t _Ip, class... _Types>
1565inline _LIBCPP_INLINE_VISIBILITY
1566constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1567get_if(variant<_Types...>* __v) noexcept {
1568 static_assert(_Ip < sizeof...(_Types));
1569 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1570 return __generic_get_if<_Ip>(__v);
1571}
1572
1573template <size_t _Ip, class... _Types>
1574inline _LIBCPP_INLINE_VISIBILITY
1575constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1576get_if(const variant<_Types...>* __v) noexcept {
1577 static_assert(_Ip < sizeof...(_Types));
1578 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1579 return __generic_get_if<_Ip>(__v);
1580}
1581
1582template <class _Tp, class... _Types>
1583inline _LIBCPP_INLINE_VISIBILITY
1584constexpr add_pointer_t<_Tp>
1585get_if(variant<_Types...>* __v) noexcept {
1586 static_assert(!is_void_v<_Tp>);
1587 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1588}
1589
1590template <class _Tp, class... _Types>
1591inline _LIBCPP_INLINE_VISIBILITY
1592constexpr add_pointer_t<const _Tp>
1593get_if(const variant<_Types...>* __v) noexcept {
1594 static_assert(!is_void_v<_Tp>);
1595 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1596}
1597
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001598template <class _Operator>
1599struct __convert_to_bool {
1600 template <class _T1, class _T2>
1601 _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001602 static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001603 "the relational operator does not return a type which is implicitly convertible to bool");
1604 return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
1605 }
1606};
1607
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001608template <class... _Types>
1609inline _LIBCPP_INLINE_VISIBILITY
1610constexpr bool operator==(const variant<_Types...>& __lhs,
1611 const variant<_Types...>& __rhs) {
1612 using __variant_detail::__visitation::__variant;
1613 if (__lhs.index() != __rhs.index()) return false;
1614 if (__lhs.valueless_by_exception()) return true;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001615 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001616}
1617
1618template <class... _Types>
1619inline _LIBCPP_INLINE_VISIBILITY
1620constexpr bool operator!=(const variant<_Types...>& __lhs,
1621 const variant<_Types...>& __rhs) {
1622 using __variant_detail::__visitation::__variant;
1623 if (__lhs.index() != __rhs.index()) return true;
1624 if (__lhs.valueless_by_exception()) return false;
1625 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001626 __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001627}
1628
1629template <class... _Types>
1630inline _LIBCPP_INLINE_VISIBILITY
1631constexpr bool operator<(const variant<_Types...>& __lhs,
1632 const variant<_Types...>& __rhs) {
1633 using __variant_detail::__visitation::__variant;
1634 if (__rhs.valueless_by_exception()) return false;
1635 if (__lhs.valueless_by_exception()) return true;
1636 if (__lhs.index() < __rhs.index()) return true;
1637 if (__lhs.index() > __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001638 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001639}
1640
1641template <class... _Types>
1642inline _LIBCPP_INLINE_VISIBILITY
1643constexpr bool operator>(const variant<_Types...>& __lhs,
1644 const variant<_Types...>& __rhs) {
1645 using __variant_detail::__visitation::__variant;
1646 if (__lhs.valueless_by_exception()) return false;
1647 if (__rhs.valueless_by_exception()) return true;
1648 if (__lhs.index() > __rhs.index()) return true;
1649 if (__lhs.index() < __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001650 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001651}
1652
1653template <class... _Types>
1654inline _LIBCPP_INLINE_VISIBILITY
1655constexpr bool operator<=(const variant<_Types...>& __lhs,
1656 const variant<_Types...>& __rhs) {
1657 using __variant_detail::__visitation::__variant;
1658 if (__lhs.valueless_by_exception()) return true;
1659 if (__rhs.valueless_by_exception()) return false;
1660 if (__lhs.index() < __rhs.index()) return true;
1661 if (__lhs.index() > __rhs.index()) return false;
1662 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001663 __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001664}
1665
1666template <class... _Types>
1667inline _LIBCPP_INLINE_VISIBILITY
1668constexpr bool operator>=(const variant<_Types...>& __lhs,
1669 const variant<_Types...>& __rhs) {
1670 using __variant_detail::__visitation::__variant;
1671 if (__rhs.valueless_by_exception()) return true;
1672 if (__lhs.valueless_by_exception()) return false;
1673 if (__lhs.index() > __rhs.index()) return true;
1674 if (__lhs.index() < __rhs.index()) return false;
1675 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001676 __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001677}
1678
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001679template <class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001680inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001681 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void
1682 __throw_if_valueless(_Vs&&... __vs) {
1683 const bool __valueless =
1684 (... || _VSTD::__as_variant(__vs).valueless_by_exception());
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001685 if (__valueless) {
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001686 __throw_bad_variant_access();
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001687 }
1688}
1689
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001690template <
1691 class _Visitor, class... _Vs,
Arthur O'Dwyer3285c342021-05-10 13:04:16 -04001692 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001693inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001694 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr
1695 decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001696 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001697 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Eric Fiselier87994112020-11-17 17:34:23 -05001698 return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001699 _VSTD::forward<_Vs>(__vs)...);
1700}
1701
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001702#if _LIBCPP_STD_VER > 17
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001703template <
1704 class _Rp, class _Visitor, class... _Vs,
Arthur O'Dwyer3285c342021-05-10 13:04:16 -04001705 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001706inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001707 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp
1708 visit(_Visitor&& __visitor, _Vs&&... __vs) {
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001709 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001710 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001711 return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
1712 _VSTD::forward<_Vs>(__vs)...);
1713}
1714#endif
1715
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001716template <class... _Types>
1717inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnef1a01932021-08-16 12:41:58 -04001718auto swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1719 noexcept(noexcept(__lhs.swap(__rhs)))
1720 -> decltype( __lhs.swap(__rhs))
1721 { return __lhs.swap(__rhs); }
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001722
1723template <class... _Types>
Eric Fiselier698a97b2017-01-21 00:02:12 +00001724struct _LIBCPP_TEMPLATE_VIS hash<
1725 __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001726 using argument_type = variant<_Types...>;
1727 using result_type = size_t;
1728
1729 inline _LIBCPP_INLINE_VISIBILITY
1730 result_type operator()(const argument_type& __v) const {
1731 using __variant_detail::__visitation::__variant;
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001732 size_t __res =
1733 __v.valueless_by_exception()
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001734 ? 299792458 // Random value chosen by the universe upon creation
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001735 : __variant::__visit_alt(
1736 [](const auto& __alt) {
Marshall Clowe61ba952018-02-12 15:41:25 +00001737 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier698a97b2017-01-21 00:02:12 +00001738 using __value_type = remove_const_t<
1739 typename __alt_type::__value_type>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001740 return hash<__value_type>{}(__alt.__value);
1741 },
1742 __v);
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001743 return __hash_combine(__res, hash<size_t>{}(__v.index()));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001744 }
1745};
1746
zoecarver6eb71a92021-05-27 09:23:19 -07001747// __unchecked_get is the same as std::get, except, it is UB to use it with the wrong
1748// type whereas std::get will throw or returning nullptr. This makes it faster than
1749// std::get.
1750template <size_t _Ip, class _Vp>
1751inline _LIBCPP_INLINE_VISIBILITY
1752constexpr auto&& __unchecked_get(_Vp&& __v) noexcept {
1753 using __variant_detail::__access::__variant;
1754 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1755}
1756
1757template <class _Tp, class... _Types>
1758inline _LIBCPP_INLINE_VISIBILITY
1759constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept {
1760 return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1761}
1762
1763template <class _Tp, class... _Types>
1764inline _LIBCPP_INLINE_VISIBILITY
1765constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
1766 return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1767}
1768
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001769#endif // _LIBCPP_STD_VER > 14
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001770
1771_LIBCPP_END_NAMESPACE_STD
1772
Eric Fiselier8625d332017-11-19 04:57:22 +00001773_LIBCPP_POP_MACROS
1774
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001775#endif // _LIBCPP_VARIANT