blob: 2145700e5a68aec6fc1a5da3d00410cdf84f9876 [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>
Christopher Di Bella41f26e82021-06-05 02:47:47 +0000204#include <__utility/forward.h>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000205#include <__tuple>
206#include <array>
Arthur O'Dwyer7deec122021-03-24 18:19:12 -0400207#include <compare>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000208#include <exception>
209#include <functional>
210#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 Dionne7202cd62020-07-22 15:24:16 -0400236// TODO: GCC 5 lies about its support for C++17 (it says it supports it but it
237// really doesn't). That breaks variant, which uses some C++17 features.
238// Remove this once we drop support for GCC 5.
Louis Dionne129391d2020-07-22 15:59:09 -0400239#if _LIBCPP_STD_VER > 14 && !(defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW < 6000)
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000240
Eric Fiselier10642ea2016-12-03 01:58:07 +0000241_LIBCPP_NORETURN
242inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +0000243_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier10642ea2016-12-03 01:58:07 +0000244void __throw_bad_variant_access() {
245#ifndef _LIBCPP_NO_EXCEPTIONS
246 throw bad_variant_access();
247#else
248 _VSTD::abort();
249#endif
250}
251
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000252template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000253class _LIBCPP_TEMPLATE_VIS variant;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000254
255template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000256struct _LIBCPP_TEMPLATE_VIS variant_size;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000257
258template <class _Tp>
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000259_LIBCPP_INLINE_VAR constexpr size_t variant_size_v = variant_size<_Tp>::value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000260
261template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000262struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000263
264template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000265struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000266
267template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000268struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000269 : variant_size<_Tp> {};
270
271template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000272struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000273 : integral_constant<size_t, sizeof...(_Types)> {};
274
275template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000276struct _LIBCPP_TEMPLATE_VIS variant_alternative;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000277
278template <size_t _Ip, class _Tp>
279using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;
280
281template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000282struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000283 : add_const<variant_alternative_t<_Ip, _Tp>> {};
284
285template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000286struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000287 : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
288
289template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000290struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000291 : add_cv<variant_alternative_t<_Ip, _Tp>> {};
292
293template <size_t _Ip, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000294struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
Marshall Clow185577f2017-06-12 16:13:17 +0000295 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000296 using type = __type_pack_element<_Ip, _Types...>;
297};
298
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000299_LIBCPP_INLINE_VAR constexpr size_t variant_npos = static_cast<size_t>(-1);
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000300
301constexpr int __choose_index_type(unsigned int __num_elem) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500302 if (__num_elem < numeric_limits<unsigned char>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000303 return 0;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500304 if (__num_elem < numeric_limits<unsigned short>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000305 return 1;
306 return 2;
307}
308
309template <size_t _NumAlts>
310using __variant_index_t =
311#ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
312 unsigned int;
313#else
314 std::tuple_element_t<
315 __choose_index_type(_NumAlts),
316 std::tuple<unsigned char, unsigned short, unsigned int>
317 >;
318#endif
319
320template <class _IndexType>
321constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000322
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100323template <class... _Types>
324class _LIBCPP_TEMPLATE_VIS variant;
325
326template <class... _Types>
327_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&
328__as_variant(variant<_Types...>& __vs) noexcept {
329 return __vs;
330}
331
332template <class... _Types>
333_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&
334__as_variant(const variant<_Types...>& __vs) noexcept {
335 return __vs;
336}
337
338template <class... _Types>
339_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&&
340__as_variant(variant<_Types...>&& __vs) noexcept {
341 return _VSTD::move(__vs);
342}
343
344template <class... _Types>
345_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&&
346__as_variant(const variant<_Types...>&& __vs) noexcept {
347 return _VSTD::move(__vs);
348}
349
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000350namespace __find_detail {
351
352template <class _Tp, class... _Types>
353inline _LIBCPP_INLINE_VISIBILITY
354constexpr size_t __find_index() {
355 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
356 size_t __result = __not_found;
357 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
358 if (__matches[__i]) {
359 if (__result != __not_found) {
360 return __ambiguous;
361 }
362 __result = __i;
363 }
364 }
365 return __result;
366}
367
368template <size_t _Index>
369struct __find_unambiguous_index_sfinae_impl
370 : integral_constant<size_t, _Index> {};
371
372template <>
373struct __find_unambiguous_index_sfinae_impl<__not_found> {};
374
375template <>
376struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
377
378template <class _Tp, class... _Types>
379struct __find_unambiguous_index_sfinae
380 : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};
381
382} // namespace __find_detail
383
384namespace __variant_detail {
385
386struct __valueless_t {};
387
388enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
389
Eric Fiselier87994112020-11-17 17:34:23 -0500390template <typename _Tp,
391 template <typename> class _IsTriviallyAvailable,
392 template <typename> class _IsAvailable>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000393constexpr _Trait __trait =
394 _IsTriviallyAvailable<_Tp>::value
395 ? _Trait::_TriviallyAvailable
396 : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
397
398inline _LIBCPP_INLINE_VISIBILITY
399constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
400 _Trait __result = _Trait::_TriviallyAvailable;
401 for (_Trait __t : __traits) {
402 if (static_cast<int>(__t) > static_cast<int>(__result)) {
403 __result = __t;
404 }
405 }
406 return __result;
407}
408
Eric Fiselier87994112020-11-17 17:34:23 -0500409template <typename... _Types>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000410struct __traits {
411 static constexpr _Trait __copy_constructible_trait =
412 __common_trait({__trait<_Types,
413 is_trivially_copy_constructible,
414 is_copy_constructible>...});
415
416 static constexpr _Trait __move_constructible_trait =
417 __common_trait({__trait<_Types,
418 is_trivially_move_constructible,
419 is_move_constructible>...});
420
421 static constexpr _Trait __copy_assignable_trait = __common_trait(
422 {__copy_constructible_trait,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000423 __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
424
425 static constexpr _Trait __move_assignable_trait = __common_trait(
426 {__move_constructible_trait,
427 __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
428
429 static constexpr _Trait __destructible_trait = __common_trait(
430 {__trait<_Types, is_trivially_destructible, is_destructible>...});
431};
432
433namespace __access {
434
435struct __union {
436 template <class _Vp>
437 inline _LIBCPP_INLINE_VISIBILITY
438 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
439 return _VSTD::forward<_Vp>(__v).__head;
440 }
441
442 template <class _Vp, size_t _Ip>
443 inline _LIBCPP_INLINE_VISIBILITY
444 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
445 return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
446 }
447};
448
449struct __base {
450 template <size_t _Ip, class _Vp>
451 inline _LIBCPP_INLINE_VISIBILITY
452 static constexpr auto&& __get_alt(_Vp&& __v) {
453 return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
454 in_place_index<_Ip>);
455 }
456};
457
458struct __variant {
459 template <size_t _Ip, class _Vp>
460 inline _LIBCPP_INLINE_VISIBILITY
461 static constexpr auto&& __get_alt(_Vp&& __v) {
462 return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl);
463 }
464};
465
466} // namespace __access
467
468namespace __visitation {
469
470struct __base {
Eric Fiselier87994112020-11-17 17:34:23 -0500471 template <class _Visitor, class... _Vs>
472 inline _LIBCPP_INLINE_VISIBILITY
473 static constexpr decltype(auto)
474 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
475 constexpr auto __fdiagonal =
476 __make_fdiagonal<_Visitor&&,
477 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
478 return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor),
479 _VSTD::forward<_Vs>(__vs).__as_base()...);
480 }
481
482 template <class _Visitor, class... _Vs>
483 inline _LIBCPP_INLINE_VISIBILITY
484 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
485 _Vs&&... __vs) {
486 constexpr auto __fmatrix =
487 __make_fmatrix<_Visitor&&,
488 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
489 return __at(__fmatrix, __vs.index()...)(
490 _VSTD::forward<_Visitor>(__visitor),
491 _VSTD::forward<_Vs>(__vs).__as_base()...);
492 }
493
494private:
495 template <class _Tp>
496 inline _LIBCPP_INLINE_VISIBILITY
497 static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }
498
499 template <class _Tp, size_t _Np, typename... _Indices>
500 inline _LIBCPP_INLINE_VISIBILITY
501 static constexpr auto&& __at(const array<_Tp, _Np>& __elems,
502 size_t __index, _Indices... __indices) {
503 return __at(__elems[__index], __indices...);
504 }
505
506 template <class _Fp, class... _Fs>
507 static constexpr void __std_visit_visitor_return_type_check() {
508 static_assert(
509 __all<is_same_v<_Fp, _Fs>...>::value,
510 "`std::visit` requires the visitor to have a single return type.");
511 }
512
513 template <class... _Fs>
514 inline _LIBCPP_INLINE_VISIBILITY
515 static constexpr auto __make_farray(_Fs&&... __fs) {
516 __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
517 using __result = array<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
518 return __result{{_VSTD::forward<_Fs>(__fs)...}};
519 }
520
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500521 template <size_t... _Is>
Eric Fiselier87994112020-11-17 17:34:23 -0500522 struct __dispatcher {
523 template <class _Fp, class... _Vs>
Michael Park32334da2020-08-30 12:42:35 -0400524 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500525 static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500526 return _VSTD::__invoke_constexpr(
Eric Fiselier87994112020-11-17 17:34:23 -0500527 static_cast<_Fp>(__f),
528 __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
Michael Park32334da2020-08-30 12:42:35 -0400529 }
530 };
531
Eric Fiselier87994112020-11-17 17:34:23 -0500532 template <class _Fp, class... _Vs, size_t... _Is>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000533 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500534 static constexpr auto __make_dispatch(index_sequence<_Is...>) {
535 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000536 }
537
Eric Fiselier87994112020-11-17 17:34:23 -0500538 template <size_t _Ip, class _Fp, class... _Vs>
539 inline _LIBCPP_INLINE_VISIBILITY
540 static constexpr auto __make_fdiagonal_impl() {
541 return __make_dispatch<_Fp, _Vs...>(
542 index_sequence<(__identity<_Vs>{}, _Ip)...>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000543 }
Eric Fiselier87994112020-11-17 17:34:23 -0500544
545 template <class _Fp, class... _Vs, size_t... _Is>
546 inline _LIBCPP_INLINE_VISIBILITY
547 static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
548 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
549 }
550
551 template <class _Fp, class _Vp, class... _Vs>
552 inline _LIBCPP_INLINE_VISIBILITY
553 static constexpr auto __make_fdiagonal() {
554 constexpr size_t _Np = __uncvref_t<_Vp>::__size();
555 static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
556 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
557 }
558
559 template <class _Fp, class... _Vs, size_t... _Is>
560 inline _LIBCPP_INLINE_VISIBILITY
561 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
562 return __make_dispatch<_Fp, _Vs...>(__is);
563 }
564
565 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
566 inline _LIBCPP_INLINE_VISIBILITY
567 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,
568 index_sequence<_Js...>,
569 _Ls... __ls) {
570 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(
571 index_sequence<_Is..., _Js>{}, __ls...)...);
572 }
573
574 template <class _Fp, class... _Vs>
575 inline _LIBCPP_INLINE_VISIBILITY
576 static constexpr auto __make_fmatrix() {
577 return __make_fmatrix_impl<_Fp, _Vs...>(
578 index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000579 }
580};
581
582struct __variant {
Eric Fiselier87994112020-11-17 17:34:23 -0500583 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000584 inline _LIBCPP_INLINE_VISIBILITY
585 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500586 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000587 return __base::__visit_alt_at(__index,
Eric Fiselier87994112020-11-17 17:34:23 -0500588 _VSTD::forward<_Visitor>(__visitor),
589 _VSTD::forward<_Vs>(__vs).__impl...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000590 }
591
Eric Fiselier87994112020-11-17 17:34:23 -0500592 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000593 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500594 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
595 _Vs&&... __vs) {
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100596 return __base::__visit_alt(
597 _VSTD::forward<_Visitor>(__visitor),
598 _VSTD::__as_variant(_VSTD::forward<_Vs>(__vs)).__impl...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000599 }
600
Eric Fiselier87994112020-11-17 17:34:23 -0500601 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000602 inline _LIBCPP_INLINE_VISIBILITY
603 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500604 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
605 return __visit_alt_at(
606 __index,
607 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
608 _VSTD::forward<_Vs>(__vs)...);
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
Eric Fiselier87994112020-11-17 17:34:23 -0500613 static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,
614 _Vs&&... __vs) {
615 return __visit_alt(
616 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
617 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000618 }
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100619
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500620#if _LIBCPP_STD_VER > 17
621 template <class _Rp, class _Visitor, class... _Vs>
622 inline _LIBCPP_INLINE_VISIBILITY
623 static constexpr _Rp __visit_value(_Visitor&& __visitor,
624 _Vs&&... __vs) {
625 return __visit_alt(
626 __make_value_visitor<_Rp>(_VSTD::forward<_Visitor>(__visitor)),
627 _VSTD::forward<_Vs>(__vs)...);
628 }
629#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000630
631private:
Eric Fiselier87994112020-11-17 17:34:23 -0500632 template <class _Visitor, class... _Values>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000633 static constexpr void __std_visit_exhaustive_visitor_check() {
Eric Fiselier87994112020-11-17 17:34:23 -0500634 static_assert(is_invocable_v<_Visitor, _Values...>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000635 "`std::visit` requires the visitor to be exhaustive.");
636 }
637
Eric Fiselier87994112020-11-17 17:34:23 -0500638 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000639 struct __value_visitor {
640 template <class... _Alts>
641 inline _LIBCPP_INLINE_VISIBILITY
642 constexpr decltype(auto) operator()(_Alts&&... __alts) const {
643 __std_visit_exhaustive_visitor_check<
Eric Fiselier87994112020-11-17 17:34:23 -0500644 _Visitor,
645 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500646 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000647 _VSTD::forward<_Alts>(__alts).__value...);
648 }
Eric Fiselier87994112020-11-17 17:34:23 -0500649 _Visitor&& __visitor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000650 };
651
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500652#if _LIBCPP_STD_VER > 17
653 template <class _Rp, class _Visitor>
654 struct __value_visitor_return_type {
655 template <class... _Alts>
656 inline _LIBCPP_INLINE_VISIBILITY
657 constexpr _Rp operator()(_Alts&&... __alts) const {
658 __std_visit_exhaustive_visitor_check<
659 _Visitor,
660 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
661 if constexpr (is_void_v<_Rp>) {
662 _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
663 _VSTD::forward<_Alts>(__alts).__value...);
664 }
665 else {
666 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
667 _VSTD::forward<_Alts>(__alts).__value...);
668 }
669 }
670
671 _Visitor&& __visitor;
672 };
673#endif
674
Eric Fiselier87994112020-11-17 17:34:23 -0500675 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000676 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500677 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
678 return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000679 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500680
681#if _LIBCPP_STD_VER > 17
682 template <class _Rp, class _Visitor>
683 inline _LIBCPP_INLINE_VISIBILITY
684 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
685 return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)};
686 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500687#endif
Nico Weber8aa36612021-01-25 15:10:41 -0500688};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000689
690} // namespace __visitation
691
692template <size_t _Index, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000693struct _LIBCPP_TEMPLATE_VIS __alt {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000694 using __value_type = _Tp;
695
696 template <class... _Args>
697 inline _LIBCPP_INLINE_VISIBILITY
698 explicit constexpr __alt(in_place_t, _Args&&... __args)
699 : __value(_VSTD::forward<_Args>(__args)...) {}
700
701 __value_type __value;
702};
703
704template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000705union _LIBCPP_TEMPLATE_VIS __union;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000706
707template <_Trait _DestructibleTrait, size_t _Index>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000708union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000709
710#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
711 template <size_t _Index, class _Tp, class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500712 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000713 _Index, \
714 _Tp, \
715 _Types...> { \
716 public: \
717 inline _LIBCPP_INLINE_VISIBILITY \
718 explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
719 \
720 template <class... _Args> \
721 inline _LIBCPP_INLINE_VISIBILITY \
722 explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
723 : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
724 \
725 template <size_t _Ip, class... _Args> \
726 inline _LIBCPP_INLINE_VISIBILITY \
727 explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
728 : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
729 \
730 __union(const __union&) = default; \
731 __union(__union&&) = default; \
732 \
733 destructor \
734 \
735 __union& operator=(const __union&) = default; \
736 __union& operator=(__union&&) = default; \
737 \
738 private: \
739 char __dummy; \
740 __alt<_Index, _Tp> __head; \
741 __union<destructible_trait, _Index + 1, _Types...> __tail; \
742 \
743 friend struct __access::__union; \
744 }
745
746_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
747_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {});
748_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
749
750#undef _LIBCPP_VARIANT_UNION
751
752template <_Trait _DestructibleTrait, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000753class _LIBCPP_TEMPLATE_VIS __base {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000754public:
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000755 using __index_t = __variant_index_t<sizeof...(_Types)>;
756
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000757 inline _LIBCPP_INLINE_VISIBILITY
758 explicit constexpr __base(__valueless_t tag) noexcept
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000759 : __data(tag), __index(__variant_npos<__index_t>) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000760
761 template <size_t _Ip, class... _Args>
762 inline _LIBCPP_INLINE_VISIBILITY
763 explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
Eric Fiselier2adf0872016-12-02 23:17:33 +0000764 :
765 __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
766 __index(_Ip) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000767
768 inline _LIBCPP_INLINE_VISIBILITY
769 constexpr bool valueless_by_exception() const noexcept {
770 return index() == variant_npos;
771 }
772
773 inline _LIBCPP_INLINE_VISIBILITY
774 constexpr size_t index() const noexcept {
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000775 return __index == __variant_npos<__index_t> ? variant_npos : __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000776 }
777
778protected:
779 inline _LIBCPP_INLINE_VISIBILITY
780 constexpr auto&& __as_base() & { return *this; }
781
782 inline _LIBCPP_INLINE_VISIBILITY
783 constexpr auto&& __as_base() && { return _VSTD::move(*this); }
784
785 inline _LIBCPP_INLINE_VISIBILITY
786 constexpr auto&& __as_base() const & { return *this; }
787
788 inline _LIBCPP_INLINE_VISIBILITY
789 constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
790
791 inline _LIBCPP_INLINE_VISIBILITY
792 static constexpr size_t __size() { return sizeof...(_Types); }
793
794 __union<_DestructibleTrait, 0, _Types...> __data;
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000795 __index_t __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000796
797 friend struct __access::__base;
798 friend struct __visitation::__base;
799};
800
801template <class _Traits, _Trait = _Traits::__destructible_trait>
Louis Dionneff05add2020-10-05 16:30:23 -0400802class _LIBCPP_TEMPLATE_VIS __dtor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000803
804#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \
805 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400806 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, \
807 destructible_trait> \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000808 : public __base<destructible_trait, _Types...> { \
809 using __base_type = __base<destructible_trait, _Types...>; \
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000810 using __index_t = typename __base_type::__index_t; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000811 \
812 public: \
813 using __base_type::__base_type; \
814 using __base_type::operator=; \
815 \
Louis Dionneff05add2020-10-05 16:30:23 -0400816 __dtor(const __dtor&) = default; \
817 __dtor(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000818 destructor \
Louis Dionneff05add2020-10-05 16:30:23 -0400819 __dtor& operator=(const __dtor&) = default; \
820 __dtor& operator=(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000821 \
822 protected: \
823 inline _LIBCPP_INLINE_VISIBILITY \
824 destroy \
825 }
826
827_LIBCPP_VARIANT_DESTRUCTOR(
828 _Trait::_TriviallyAvailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400829 ~__dtor() = default;,
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000830 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000831
832_LIBCPP_VARIANT_DESTRUCTOR(
833 _Trait::_Available,
Louis Dionneff05add2020-10-05 16:30:23 -0400834 ~__dtor() { __destroy(); },
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000835 void __destroy() noexcept {
836 if (!this->valueless_by_exception()) {
837 __visitation::__base::__visit_alt(
838 [](auto& __alt) noexcept {
Marshall Clowe61ba952018-02-12 15:41:25 +0000839 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000840 __alt.~__alt_type();
841 },
842 *this);
843 }
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000844 this->__index = __variant_npos<__index_t>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000845 });
846
847_LIBCPP_VARIANT_DESTRUCTOR(
848 _Trait::_Unavailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400849 ~__dtor() = delete;,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000850 void __destroy() noexcept = delete;);
851
852#undef _LIBCPP_VARIANT_DESTRUCTOR
853
854template <class _Traits>
Louis Dionneff05add2020-10-05 16:30:23 -0400855class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> {
856 using __base_type = __dtor<_Traits>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000857
858public:
859 using __base_type::__base_type;
860 using __base_type::operator=;
861
862protected:
863 template <size_t _Ip, class _Tp, class... _Args>
864 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000865 static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
Eric Fiselier87994112020-11-17 17:34:23 -0500866 ::new ((void*)_VSTD::addressof(__a))
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000867 __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
Eric Fiselier87994112020-11-17 17:34:23 -0500868 return __a.__value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000869 }
870
871 template <class _Rhs>
872 inline _LIBCPP_INLINE_VISIBILITY
Louis Dionneff05add2020-10-05 16:30:23 -0400873 static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000874 __lhs.__destroy();
875 if (!__rhs.valueless_by_exception()) {
876 __visitation::__base::__visit_alt_at(
877 __rhs.index(),
878 [](auto& __lhs_alt, auto&& __rhs_alt) {
879 __construct_alt(
880 __lhs_alt,
881 _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
882 },
883 __lhs, _VSTD::forward<_Rhs>(__rhs));
884 __lhs.__index = __rhs.index();
885 }
886 }
887};
888
889template <class _Traits, _Trait = _Traits::__move_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000890class _LIBCPP_TEMPLATE_VIS __move_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000891
892#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \
893 move_constructor) \
894 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400895 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \
896 move_constructible_trait> \
897 : public __ctor<__traits<_Types...>> { \
898 using __base_type = __ctor<__traits<_Types...>>; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000899 \
900 public: \
901 using __base_type::__base_type; \
902 using __base_type::operator=; \
903 \
904 __move_constructor(const __move_constructor&) = default; \
905 move_constructor \
906 ~__move_constructor() = default; \
907 __move_constructor& operator=(const __move_constructor&) = default; \
908 __move_constructor& operator=(__move_constructor&&) = default; \
909 }
910
911_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
912 _Trait::_TriviallyAvailable,
913 __move_constructor(__move_constructor&& __that) = default;);
914
915_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
916 _Trait::_Available,
917 __move_constructor(__move_constructor&& __that) noexcept(
918 __all<is_nothrow_move_constructible_v<_Types>...>::value)
919 : __move_constructor(__valueless_t{}) {
920 this->__generic_construct(*this, _VSTD::move(__that));
921 });
922
923_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
924 _Trait::_Unavailable,
925 __move_constructor(__move_constructor&&) = delete;);
926
927#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
928
929template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000930class _LIBCPP_TEMPLATE_VIS __copy_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000931
932#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
933 copy_constructor) \
934 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500935 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000936 copy_constructible_trait> \
937 : public __move_constructor<__traits<_Types...>> { \
938 using __base_type = __move_constructor<__traits<_Types...>>; \
939 \
940 public: \
941 using __base_type::__base_type; \
942 using __base_type::operator=; \
943 \
944 copy_constructor \
945 __copy_constructor(__copy_constructor&&) = default; \
946 ~__copy_constructor() = default; \
947 __copy_constructor& operator=(const __copy_constructor&) = default; \
948 __copy_constructor& operator=(__copy_constructor&&) = default; \
949 }
950
951_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
952 _Trait::_TriviallyAvailable,
953 __copy_constructor(const __copy_constructor& __that) = default;);
954
955_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
956 _Trait::_Available,
957 __copy_constructor(const __copy_constructor& __that)
958 : __copy_constructor(__valueless_t{}) {
959 this->__generic_construct(*this, __that);
960 });
961
962_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
963 _Trait::_Unavailable,
964 __copy_constructor(const __copy_constructor&) = delete;);
965
966#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
967
968template <class _Traits>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000969class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000970 using __base_type = __copy_constructor<_Traits>;
971
972public:
973 using __base_type::__base_type;
974 using __base_type::operator=;
975
976 template <size_t _Ip, class... _Args>
977 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000978 auto& __emplace(_Args&&... __args) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000979 this->__destroy();
Eric Fiselier62928442017-04-15 19:32:02 +0000980 auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
Eric Fiselier87994112020-11-17 17:34:23 -0500981 _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000982 this->__index = _Ip;
Eric Fiselier62928442017-04-15 19:32:02 +0000983 return __res;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000984 }
985
986protected:
Michael Park62118352017-06-07 10:22:43 +0000987 template <size_t _Ip, class _Tp, class _Arg>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000988 inline _LIBCPP_INLINE_VISIBILITY
Michael Park62118352017-06-07 10:22:43 +0000989 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000990 if (this->index() == _Ip) {
991 __a.__value = _VSTD::forward<_Arg>(__arg);
992 } else {
993 struct {
994 void operator()(true_type) const {
Michael Park62118352017-06-07 10:22:43 +0000995 __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000996 }
997 void operator()(false_type) const {
Michael Park62118352017-06-07 10:22:43 +0000998 __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000999 }
1000 __assignment* __this;
1001 _Arg&& __arg;
1002 } __impl{this, _VSTD::forward<_Arg>(__arg)};
Michael Park62118352017-06-07 10:22:43 +00001003 __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||
1004 !is_nothrow_move_constructible_v<_Tp>>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001005 }
1006 }
1007
1008 template <class _That>
1009 inline _LIBCPP_INLINE_VISIBILITY
1010 void __generic_assign(_That&& __that) {
1011 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1012 // do nothing.
1013 } else if (__that.valueless_by_exception()) {
1014 this->__destroy();
1015 } else {
1016 __visitation::__base::__visit_alt_at(
1017 __that.index(),
1018 [this](auto& __this_alt, auto&& __that_alt) {
1019 this->__assign_alt(
1020 __this_alt,
Michael Park62118352017-06-07 10:22:43 +00001021 _VSTD::forward<decltype(__that_alt)>(__that_alt).__value);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001022 },
1023 *this, _VSTD::forward<_That>(__that));
1024 }
1025 }
1026};
1027
1028template <class _Traits, _Trait = _Traits::__move_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001029class _LIBCPP_TEMPLATE_VIS __move_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001030
1031#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
1032 move_assignment) \
1033 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001034 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001035 move_assignable_trait> \
1036 : public __assignment<__traits<_Types...>> { \
1037 using __base_type = __assignment<__traits<_Types...>>; \
1038 \
1039 public: \
1040 using __base_type::__base_type; \
1041 using __base_type::operator=; \
1042 \
1043 __move_assignment(const __move_assignment&) = default; \
1044 __move_assignment(__move_assignment&&) = default; \
1045 ~__move_assignment() = default; \
1046 __move_assignment& operator=(const __move_assignment&) = default; \
1047 move_assignment \
1048 }
1049
1050_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1051 _Trait::_TriviallyAvailable,
1052 __move_assignment& operator=(__move_assignment&& __that) = default;);
1053
1054_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1055 _Trait::_Available,
1056 __move_assignment& operator=(__move_assignment&& __that) noexcept(
1057 __all<(is_nothrow_move_constructible_v<_Types> &&
1058 is_nothrow_move_assignable_v<_Types>)...>::value) {
1059 this->__generic_assign(_VSTD::move(__that));
1060 return *this;
1061 });
1062
1063_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1064 _Trait::_Unavailable,
1065 __move_assignment& operator=(__move_assignment&&) = delete;);
1066
1067#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
1068
1069template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001070class _LIBCPP_TEMPLATE_VIS __copy_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001071
1072#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
1073 copy_assignment) \
1074 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001075 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001076 copy_assignable_trait> \
1077 : public __move_assignment<__traits<_Types...>> { \
1078 using __base_type = __move_assignment<__traits<_Types...>>; \
1079 \
1080 public: \
1081 using __base_type::__base_type; \
1082 using __base_type::operator=; \
1083 \
1084 __copy_assignment(const __copy_assignment&) = default; \
1085 __copy_assignment(__copy_assignment&&) = default; \
1086 ~__copy_assignment() = default; \
1087 copy_assignment \
1088 __copy_assignment& operator=(__copy_assignment&&) = default; \
1089 }
1090
1091_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1092 _Trait::_TriviallyAvailable,
1093 __copy_assignment& operator=(const __copy_assignment& __that) = default;);
1094
1095_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1096 _Trait::_Available,
1097 __copy_assignment& operator=(const __copy_assignment& __that) {
1098 this->__generic_assign(__that);
1099 return *this;
1100 });
1101
1102_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1103 _Trait::_Unavailable,
1104 __copy_assignment& operator=(const __copy_assignment&) = delete;);
1105
1106#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1107
1108template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001109class _LIBCPP_TEMPLATE_VIS __impl
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001110 : public __copy_assignment<__traits<_Types...>> {
1111 using __base_type = __copy_assignment<__traits<_Types...>>;
1112
1113public:
1114 using __base_type::__base_type;
1115 using __base_type::operator=;
1116
1117 template <size_t _Ip, class _Arg>
1118 inline _LIBCPP_INLINE_VISIBILITY
1119 void __assign(_Arg&& __arg) {
1120 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
Michael Park62118352017-06-07 10:22:43 +00001121 _VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001122 }
1123
1124 inline _LIBCPP_INLINE_VISIBILITY
1125 void __swap(__impl& __that) {
1126 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1127 // do nothing.
1128 } else if (this->index() == __that.index()) {
1129 __visitation::__base::__visit_alt_at(
1130 this->index(),
1131 [](auto& __this_alt, auto& __that_alt) {
1132 using _VSTD::swap;
1133 swap(__this_alt.__value, __that_alt.__value);
1134 },
1135 *this,
1136 __that);
1137 } else {
1138 __impl* __lhs = this;
1139 __impl* __rhs = _VSTD::addressof(__that);
1140 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1141 _VSTD::swap(__lhs, __rhs);
1142 }
1143 __impl __tmp(_VSTD::move(*__rhs));
Michael Park5dee7342020-06-16 15:15:10 -07001144#ifndef _LIBCPP_NO_EXCEPTIONS
Michael Park6a9ef642020-07-08 10:46:02 -07001145 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
Michael Park31967aa2020-06-16 13:29:23 -07001146 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1147 } else {
1148 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1149 // and `__tmp` is nothrow move constructible then we move `__tmp` back
1150 // into `__rhs` and provide the strong exception safety guarantee.
1151 try {
1152 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1153 } catch (...) {
1154 if (__tmp.__move_nothrow()) {
1155 this->__generic_construct(*__rhs, _VSTD::move(__tmp));
1156 }
1157 throw;
1158 }
1159 }
Michael Park5dee7342020-06-16 15:15:10 -07001160#else
1161 // this isn't consolidated with the `if constexpr` branch above due to
1162 // `throw` being ill-formed with exceptions disabled even when discarded.
1163 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1164#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001165 this->__generic_construct(*__lhs, _VSTD::move(__tmp));
1166 }
1167 }
1168
1169private:
1170 inline _LIBCPP_INLINE_VISIBILITY
1171 bool __move_nothrow() const {
1172 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1173 return this->valueless_by_exception() || __results[this->index()];
1174 }
1175};
1176
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001177struct __no_narrowing_check {
1178 template <class _Dest, class _Source>
1179 using _Apply = __identity<_Dest>;
1180};
1181
1182struct __narrowing_check {
1183 template <class _Dest>
1184 static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>;
1185 template <class _Dest, class _Source>
Arthur O'Dwyer3285c342021-05-10 13:04:16 -04001186 using _Apply _LIBCPP_NODEBUG_TYPE = decltype(__test_impl<_Dest>({declval<_Source>()}));
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001187};
1188
1189template <class _Dest, class _Source>
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001190using __check_for_narrowing _LIBCPP_NODEBUG_TYPE =
1191 typename _If<
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001192#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
1193 false &&
1194#endif
1195 is_arithmetic<_Dest>::value,
1196 __narrowing_check,
1197 __no_narrowing_check
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001198 >::template _Apply<_Dest, _Source>;
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001199
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001200template <class _Tp, size_t _Idx>
1201struct __overload {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001202 template <class _Up>
Eric Fiselier80f5dfb2019-07-14 18:31:55 +00001203 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001204};
1205
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001206template <class _Tp, size_t>
1207struct __overload_bool {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001208 template <class _Up, class _Ap = __uncvref_t<_Up>>
1209 auto operator()(bool, _Up&&) const
1210 -> enable_if_t<is_same_v<_Ap, bool>, __identity<_Tp>>;
1211};
1212
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001213template <size_t _Idx>
1214struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};
1215template <size_t _Idx>
1216struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};
1217template <size_t _Idx>
1218struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};
1219template <size_t _Idx>
1220struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};
1221
1222template <class ..._Bases>
1223struct __all_overloads : _Bases... {
1224 void operator()() const;
1225 using _Bases::operator()...;
1226};
1227
1228template <class IdxSeq>
1229struct __make_overloads_imp;
1230
1231template <size_t ..._Idx>
1232struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1233 template <class ..._Types>
1234 using _Apply _LIBCPP_NODEBUG_TYPE = __all_overloads<__overload<_Types, _Idx>...>;
1235};
1236
1237template <class ..._Types>
1238using _MakeOverloads _LIBCPP_NODEBUG_TYPE = typename __make_overloads_imp<
1239 __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
Zhihao Yuan821efb82019-06-20 22:09:40 +00001240
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001241template <class _Tp, class... _Types>
Zhihao Yuan821efb82019-06-20 22:09:40 +00001242using __best_match_t =
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001243 typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001244
1245} // __variant_detail
1246
1247template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001248class _LIBCPP_TEMPLATE_VIS variant
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001249 : private __sfinae_ctor_base<
1250 __all<is_copy_constructible_v<_Types>...>::value,
1251 __all<is_move_constructible_v<_Types>...>::value>,
1252 private __sfinae_assign_base<
1253 __all<(is_copy_constructible_v<_Types> &&
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001254 is_copy_assignable_v<_Types>)...>::value,
1255 __all<(is_move_constructible_v<_Types> &&
1256 is_move_assignable_v<_Types>)...>::value> {
1257 static_assert(0 < sizeof...(_Types),
1258 "variant must consist of at least one alternative.");
1259
1260 static_assert(__all<!is_array_v<_Types>...>::value,
1261 "variant can not have an array type as an alternative.");
1262
1263 static_assert(__all<!is_reference_v<_Types>...>::value,
1264 "variant can not have a reference type as an alternative.");
1265
1266 static_assert(__all<!is_void_v<_Types>...>::value,
1267 "variant can not have a void type as an alternative.");
1268
1269 using __first_type = variant_alternative_t<0, variant>;
1270
1271public:
1272 template <bool _Dummy = true,
1273 enable_if_t<__dependent_type<is_default_constructible<__first_type>,
1274 _Dummy>::value,
1275 int> = 0>
1276 inline _LIBCPP_INLINE_VISIBILITY
1277 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
1278 : __impl(in_place_index<0>) {}
1279
1280 variant(const variant&) = default;
1281 variant(variant&&) = default;
1282
1283 template <
1284 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001285 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
1286 enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0,
1287 enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001288 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1289 size_t _Ip =
1290 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1291 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1292 inline _LIBCPP_INLINE_VISIBILITY
1293 constexpr variant(_Arg&& __arg) noexcept(
1294 is_nothrow_constructible_v<_Tp, _Arg>)
1295 : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
1296
1297 template <size_t _Ip, class... _Args,
Eric Fiselier5d2df752018-03-23 23:42:30 +00001298 class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1299 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1300 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001301 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001302 explicit constexpr variant(
1303 in_place_index_t<_Ip>,
1304 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001305 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1306
Eric Fiselier5d2df752018-03-23 23:42:30 +00001307 template <
1308 size_t _Ip,
1309 class _Up,
1310 class... _Args,
1311 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1312 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001313 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1314 int> = 0>
1315 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001316 explicit constexpr variant(
1317 in_place_index_t<_Ip>,
1318 initializer_list<_Up> __il,
1319 _Args&&... __args) noexcept(
1320 is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001321 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1322
1323 template <
1324 class _Tp,
1325 class... _Args,
1326 size_t _Ip =
1327 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1328 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1329 inline _LIBCPP_INLINE_VISIBILITY
1330 explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1331 is_nothrow_constructible_v<_Tp, _Args...>)
1332 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1333
1334 template <
1335 class _Tp,
1336 class _Up,
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, initializer_list<_Up>&, _Args...>,
1341 int> = 0>
1342 inline _LIBCPP_INLINE_VISIBILITY
1343 explicit constexpr variant(
1344 in_place_type_t<_Tp>,
1345 initializer_list<_Up> __il,
1346 _Args&&... __args) noexcept(
1347 is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
1348 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1349
1350 ~variant() = default;
1351
1352 variant& operator=(const variant&) = default;
1353 variant& operator=(variant&&) = default;
1354
1355 template <
1356 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001357 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001358 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1359 size_t _Ip =
1360 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1361 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
1362 int> = 0>
1363 inline _LIBCPP_INLINE_VISIBILITY
1364 variant& operator=(_Arg&& __arg) noexcept(
1365 is_nothrow_assignable_v<_Tp&, _Arg> &&
1366 is_nothrow_constructible_v<_Tp, _Arg>) {
1367 __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg));
1368 return *this;
1369 }
1370
1371 template <
1372 size_t _Ip,
1373 class... _Args,
1374 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1375 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1376 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1377 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001378 _Tp& emplace(_Args&&... __args) {
1379 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001380 }
1381
1382 template <
1383 size_t _Ip,
1384 class _Up,
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, initializer_list<_Up>&, _Args...>,
1389 int> = 0>
1390 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001391 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1392 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001393 }
1394
1395 template <
1396 class _Tp,
1397 class... _Args,
1398 size_t _Ip =
1399 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1400 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1401 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001402 _Tp& emplace(_Args&&... __args) {
1403 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001404 }
1405
1406 template <
1407 class _Tp,
1408 class _Up,
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, initializer_list<_Up>&, _Args...>,
1413 int> = 0>
1414 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001415 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1416 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001417 }
1418
1419 inline _LIBCPP_INLINE_VISIBILITY
1420 constexpr bool valueless_by_exception() const noexcept {
1421 return __impl.valueless_by_exception();
1422 }
1423
1424 inline _LIBCPP_INLINE_VISIBILITY
1425 constexpr size_t index() const noexcept { return __impl.index(); }
1426
1427 template <
1428 bool _Dummy = true,
1429 enable_if_t<
1430 __all<(
1431 __dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1432 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1433 int> = 0>
1434 inline _LIBCPP_INLINE_VISIBILITY
1435 void swap(variant& __that) noexcept(
1436 __all<(is_nothrow_move_constructible_v<_Types> &&
1437 is_nothrow_swappable_v<_Types>)...>::value) {
1438 __impl.__swap(__that.__impl);
1439 }
1440
1441private:
1442 __variant_detail::__impl<_Types...> __impl;
1443
1444 friend struct __variant_detail::__access::__variant;
1445 friend struct __variant_detail::__visitation::__variant;
1446};
1447
1448template <size_t _Ip, class... _Types>
1449inline _LIBCPP_INLINE_VISIBILITY
1450constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1451 return __v.index() == _Ip;
1452}
1453
1454template <class _Tp, class... _Types>
1455inline _LIBCPP_INLINE_VISIBILITY
1456constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1457 return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1458}
1459
1460template <size_t _Ip, class _Vp>
1461inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001462_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Richard Smith66d1c552018-08-27 21:41:50 +00001463constexpr auto&& __generic_get(_Vp&& __v) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001464 using __variant_detail::__access::__variant;
1465 if (!__holds_alternative<_Ip>(__v)) {
Eric Fiselier10642ea2016-12-03 01:58:07 +00001466 __throw_bad_variant_access();
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001467 }
1468 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1469}
1470
1471template <size_t _Ip, class... _Types>
1472inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001473_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001474constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
1475 variant<_Types...>& __v) {
1476 static_assert(_Ip < sizeof...(_Types));
1477 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1478 return __generic_get<_Ip>(__v);
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>(_VSTD::move(__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 const variant_alternative_t<_Ip, variant<_Types...>>& get(
1495 const 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>(__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>(_VSTD::move(__v));
1509}
1510
1511template <class _Tp, 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 _Tp& get(variant<_Types...>& __v) {
1515 static_assert(!is_void_v<_Tp>);
1516 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1517}
1518
1519template <class _Tp, class... _Types>
1520inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001521_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001522constexpr _Tp&& get(variant<_Types...>&& __v) {
1523 static_assert(!is_void_v<_Tp>);
1524 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1525 _VSTD::move(__v));
1526}
1527
1528template <class _Tp, class... _Types>
1529inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001530_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001531constexpr const _Tp& get(const variant<_Types...>& __v) {
1532 static_assert(!is_void_v<_Tp>);
1533 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1534}
1535
1536template <class _Tp, class... _Types>
1537inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001538_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001539constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1540 static_assert(!is_void_v<_Tp>);
1541 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1542 _VSTD::move(__v));
1543}
1544
1545template <size_t _Ip, class _Vp>
1546inline _LIBCPP_INLINE_VISIBILITY
1547constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1548 using __variant_detail::__access::__variant;
1549 return __v && __holds_alternative<_Ip>(*__v)
1550 ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value)
1551 : nullptr;
1552}
1553
1554template <size_t _Ip, class... _Types>
1555inline _LIBCPP_INLINE_VISIBILITY
1556constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1557get_if(variant<_Types...>* __v) noexcept {
1558 static_assert(_Ip < sizeof...(_Types));
1559 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1560 return __generic_get_if<_Ip>(__v);
1561}
1562
1563template <size_t _Ip, class... _Types>
1564inline _LIBCPP_INLINE_VISIBILITY
1565constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1566get_if(const variant<_Types...>* __v) noexcept {
1567 static_assert(_Ip < sizeof...(_Types));
1568 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1569 return __generic_get_if<_Ip>(__v);
1570}
1571
1572template <class _Tp, class... _Types>
1573inline _LIBCPP_INLINE_VISIBILITY
1574constexpr add_pointer_t<_Tp>
1575get_if(variant<_Types...>* __v) noexcept {
1576 static_assert(!is_void_v<_Tp>);
1577 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1578}
1579
1580template <class _Tp, class... _Types>
1581inline _LIBCPP_INLINE_VISIBILITY
1582constexpr add_pointer_t<const _Tp>
1583get_if(const variant<_Types...>* __v) noexcept {
1584 static_assert(!is_void_v<_Tp>);
1585 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1586}
1587
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001588template <class _Operator>
1589struct __convert_to_bool {
1590 template <class _T1, class _T2>
1591 _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001592 static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001593 "the relational operator does not return a type which is implicitly convertible to bool");
1594 return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
1595 }
1596};
1597
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001598template <class... _Types>
1599inline _LIBCPP_INLINE_VISIBILITY
1600constexpr bool operator==(const variant<_Types...>& __lhs,
1601 const variant<_Types...>& __rhs) {
1602 using __variant_detail::__visitation::__variant;
1603 if (__lhs.index() != __rhs.index()) return false;
1604 if (__lhs.valueless_by_exception()) return true;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001605 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001606}
1607
1608template <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 true;
1614 if (__lhs.valueless_by_exception()) return false;
1615 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001616 __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001617}
1618
1619template <class... _Types>
1620inline _LIBCPP_INLINE_VISIBILITY
1621constexpr bool operator<(const variant<_Types...>& __lhs,
1622 const variant<_Types...>& __rhs) {
1623 using __variant_detail::__visitation::__variant;
1624 if (__rhs.valueless_by_exception()) return false;
1625 if (__lhs.valueless_by_exception()) return true;
1626 if (__lhs.index() < __rhs.index()) return true;
1627 if (__lhs.index() > __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001628 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __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 (__lhs.valueless_by_exception()) return false;
1637 if (__rhs.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<greater<>>{}, __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 true;
1649 if (__rhs.valueless_by_exception()) return false;
1650 if (__lhs.index() < __rhs.index()) return true;
1651 if (__lhs.index() > __rhs.index()) return false;
1652 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001653 __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001654}
1655
1656template <class... _Types>
1657inline _LIBCPP_INLINE_VISIBILITY
1658constexpr bool operator>=(const variant<_Types...>& __lhs,
1659 const variant<_Types...>& __rhs) {
1660 using __variant_detail::__visitation::__variant;
1661 if (__rhs.valueless_by_exception()) return true;
1662 if (__lhs.valueless_by_exception()) return false;
1663 if (__lhs.index() > __rhs.index()) return true;
1664 if (__lhs.index() < __rhs.index()) return false;
1665 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001666 __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001667}
1668
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001669template <class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001670inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001671 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void
1672 __throw_if_valueless(_Vs&&... __vs) {
1673 const bool __valueless =
1674 (... || _VSTD::__as_variant(__vs).valueless_by_exception());
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001675 if (__valueless) {
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001676 __throw_bad_variant_access();
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001677 }
1678}
1679
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001680template <
1681 class _Visitor, class... _Vs,
Arthur O'Dwyer3285c342021-05-10 13:04:16 -04001682 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001683inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001684 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr
1685 decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001686 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001687 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Eric Fiselier87994112020-11-17 17:34:23 -05001688 return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001689 _VSTD::forward<_Vs>(__vs)...);
1690}
1691
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001692#if _LIBCPP_STD_VER > 17
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001693template <
1694 class _Rp, class _Visitor, class... _Vs,
Arthur O'Dwyer3285c342021-05-10 13:04:16 -04001695 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001696inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001697 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp
1698 visit(_Visitor&& __visitor, _Vs&&... __vs) {
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001699 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001700 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001701 return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
1702 _VSTD::forward<_Vs>(__vs)...);
1703}
1704#endif
1705
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001706struct _LIBCPP_TEMPLATE_VIS monostate {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001707
1708inline _LIBCPP_INLINE_VISIBILITY
1709constexpr bool operator<(monostate, monostate) noexcept { return false; }
1710
1711inline _LIBCPP_INLINE_VISIBILITY
1712constexpr bool operator>(monostate, monostate) noexcept { return false; }
1713
1714inline _LIBCPP_INLINE_VISIBILITY
1715constexpr bool operator<=(monostate, monostate) noexcept { return true; }
1716
1717inline _LIBCPP_INLINE_VISIBILITY
1718constexpr bool operator>=(monostate, monostate) noexcept { return true; }
1719
1720inline _LIBCPP_INLINE_VISIBILITY
1721constexpr bool operator==(monostate, monostate) noexcept { return true; }
1722
1723inline _LIBCPP_INLINE_VISIBILITY
1724constexpr bool operator!=(monostate, monostate) noexcept { return false; }
1725
1726template <class... _Types>
1727inline _LIBCPP_INLINE_VISIBILITY
1728auto swap(variant<_Types...>& __lhs,
1729 variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs)))
1730 -> decltype(__lhs.swap(__rhs)) {
1731 __lhs.swap(__rhs);
1732}
1733
1734template <class... _Types>
Eric Fiselier698a97b2017-01-21 00:02:12 +00001735struct _LIBCPP_TEMPLATE_VIS hash<
1736 __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001737 using argument_type = variant<_Types...>;
1738 using result_type = size_t;
1739
1740 inline _LIBCPP_INLINE_VISIBILITY
1741 result_type operator()(const argument_type& __v) const {
1742 using __variant_detail::__visitation::__variant;
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001743 size_t __res =
1744 __v.valueless_by_exception()
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001745 ? 299792458 // Random value chosen by the universe upon creation
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001746 : __variant::__visit_alt(
1747 [](const auto& __alt) {
Marshall Clowe61ba952018-02-12 15:41:25 +00001748 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier698a97b2017-01-21 00:02:12 +00001749 using __value_type = remove_const_t<
1750 typename __alt_type::__value_type>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001751 return hash<__value_type>{}(__alt.__value);
1752 },
1753 __v);
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001754 return __hash_combine(__res, hash<size_t>{}(__v.index()));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001755 }
1756};
1757
1758template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001759struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001760 using argument_type = monostate;
1761 using result_type = size_t;
1762
1763 inline _LIBCPP_INLINE_VISIBILITY
Marshall Clow49036892017-03-23 02:40:28 +00001764 result_type operator()(const argument_type&) const _NOEXCEPT {
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001765 return 66740831; // return a fundamentally attractive random value.
1766 }
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001767};
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