blob: 08b64612d133cb1030201d865fd81f0cdaaeac4c [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>
Mark de Wever3b269752021-07-07 21:27:27 +0200205#include <__variant/monostate.h>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000206#include <__tuple>
207#include <array>
Arthur O'Dwyer7deec122021-03-24 18:19:12 -0400208#include <compare>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000209#include <exception>
210#include <functional>
211#include <initializer_list>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400212#include <limits>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000213#include <new>
214#include <tuple>
215#include <type_traits>
216#include <utility>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000217#include <version>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000218
219#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
220#pragma GCC system_header
221#endif
222
Eric Fiselier8625d332017-11-19 04:57:22 +0000223_LIBCPP_PUSH_MACROS
224#include <__undef_macros>
225
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000226namespace std { // explicitly not using versioning namespace
227
Louis Dionnecef92e62018-11-19 15:37:04 +0000228class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000229public:
Saleem Abdulrasool5ee83382016-12-31 17:34:26 +0000230 virtual const char* what() const _NOEXCEPT;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000231};
232
233} // namespace std
234
235_LIBCPP_BEGIN_NAMESPACE_STD
236
Louis Dionne7202cd62020-07-22 15:24:16 -0400237// TODO: GCC 5 lies about its support for C++17 (it says it supports it but it
238// really doesn't). That breaks variant, which uses some C++17 features.
239// Remove this once we drop support for GCC 5.
Louis Dionne129391d2020-07-22 15:59:09 -0400240#if _LIBCPP_STD_VER > 14 && !(defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW < 6000)
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000241
Eric Fiselier10642ea2016-12-03 01:58:07 +0000242_LIBCPP_NORETURN
243inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +0000244_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier10642ea2016-12-03 01:58:07 +0000245void __throw_bad_variant_access() {
246#ifndef _LIBCPP_NO_EXCEPTIONS
247 throw bad_variant_access();
248#else
249 _VSTD::abort();
250#endif
251}
252
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000253template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000254class _LIBCPP_TEMPLATE_VIS variant;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000255
256template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000257struct _LIBCPP_TEMPLATE_VIS variant_size;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000258
259template <class _Tp>
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000260_LIBCPP_INLINE_VAR constexpr size_t variant_size_v = variant_size<_Tp>::value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000261
262template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000263struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000264
265template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000266struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000267
268template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000269struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000270 : variant_size<_Tp> {};
271
272template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000273struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000274 : integral_constant<size_t, sizeof...(_Types)> {};
275
276template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000277struct _LIBCPP_TEMPLATE_VIS variant_alternative;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000278
279template <size_t _Ip, class _Tp>
280using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;
281
282template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000283struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000284 : add_const<variant_alternative_t<_Ip, _Tp>> {};
285
286template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000287struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000288 : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
289
290template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000291struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000292 : add_cv<variant_alternative_t<_Ip, _Tp>> {};
293
294template <size_t _Ip, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000295struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
Marshall Clow185577f2017-06-12 16:13:17 +0000296 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000297 using type = __type_pack_element<_Ip, _Types...>;
298};
299
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000300_LIBCPP_INLINE_VAR constexpr size_t variant_npos = static_cast<size_t>(-1);
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000301
302constexpr int __choose_index_type(unsigned int __num_elem) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500303 if (__num_elem < numeric_limits<unsigned char>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000304 return 0;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500305 if (__num_elem < numeric_limits<unsigned short>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000306 return 1;
307 return 2;
308}
309
310template <size_t _NumAlts>
311using __variant_index_t =
312#ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
313 unsigned int;
314#else
315 std::tuple_element_t<
316 __choose_index_type(_NumAlts),
317 std::tuple<unsigned char, unsigned short, unsigned int>
318 >;
319#endif
320
321template <class _IndexType>
322constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000323
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100324template <class... _Types>
325class _LIBCPP_TEMPLATE_VIS variant;
326
327template <class... _Types>
328_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&
329__as_variant(variant<_Types...>& __vs) noexcept {
330 return __vs;
331}
332
333template <class... _Types>
334_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&
335__as_variant(const variant<_Types...>& __vs) noexcept {
336 return __vs;
337}
338
339template <class... _Types>
340_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&&
341__as_variant(variant<_Types...>&& __vs) noexcept {
342 return _VSTD::move(__vs);
343}
344
345template <class... _Types>
346_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&&
347__as_variant(const variant<_Types...>&& __vs) noexcept {
348 return _VSTD::move(__vs);
349}
350
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000351namespace __find_detail {
352
353template <class _Tp, class... _Types>
354inline _LIBCPP_INLINE_VISIBILITY
355constexpr size_t __find_index() {
356 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
357 size_t __result = __not_found;
358 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
359 if (__matches[__i]) {
360 if (__result != __not_found) {
361 return __ambiguous;
362 }
363 __result = __i;
364 }
365 }
366 return __result;
367}
368
369template <size_t _Index>
370struct __find_unambiguous_index_sfinae_impl
371 : integral_constant<size_t, _Index> {};
372
373template <>
374struct __find_unambiguous_index_sfinae_impl<__not_found> {};
375
376template <>
377struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
378
379template <class _Tp, class... _Types>
380struct __find_unambiguous_index_sfinae
381 : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};
382
383} // namespace __find_detail
384
385namespace __variant_detail {
386
387struct __valueless_t {};
388
389enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
390
Eric Fiselier87994112020-11-17 17:34:23 -0500391template <typename _Tp,
392 template <typename> class _IsTriviallyAvailable,
393 template <typename> class _IsAvailable>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000394constexpr _Trait __trait =
395 _IsTriviallyAvailable<_Tp>::value
396 ? _Trait::_TriviallyAvailable
397 : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
398
399inline _LIBCPP_INLINE_VISIBILITY
400constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
401 _Trait __result = _Trait::_TriviallyAvailable;
402 for (_Trait __t : __traits) {
403 if (static_cast<int>(__t) > static_cast<int>(__result)) {
404 __result = __t;
405 }
406 }
407 return __result;
408}
409
Eric Fiselier87994112020-11-17 17:34:23 -0500410template <typename... _Types>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000411struct __traits {
412 static constexpr _Trait __copy_constructible_trait =
413 __common_trait({__trait<_Types,
414 is_trivially_copy_constructible,
415 is_copy_constructible>...});
416
417 static constexpr _Trait __move_constructible_trait =
418 __common_trait({__trait<_Types,
419 is_trivially_move_constructible,
420 is_move_constructible>...});
421
422 static constexpr _Trait __copy_assignable_trait = __common_trait(
423 {__copy_constructible_trait,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000424 __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
425
426 static constexpr _Trait __move_assignable_trait = __common_trait(
427 {__move_constructible_trait,
428 __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
429
430 static constexpr _Trait __destructible_trait = __common_trait(
431 {__trait<_Types, is_trivially_destructible, is_destructible>...});
432};
433
434namespace __access {
435
436struct __union {
437 template <class _Vp>
438 inline _LIBCPP_INLINE_VISIBILITY
439 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
440 return _VSTD::forward<_Vp>(__v).__head;
441 }
442
443 template <class _Vp, size_t _Ip>
444 inline _LIBCPP_INLINE_VISIBILITY
445 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
446 return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
447 }
448};
449
450struct __base {
451 template <size_t _Ip, class _Vp>
452 inline _LIBCPP_INLINE_VISIBILITY
453 static constexpr auto&& __get_alt(_Vp&& __v) {
454 return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
455 in_place_index<_Ip>);
456 }
457};
458
459struct __variant {
460 template <size_t _Ip, class _Vp>
461 inline _LIBCPP_INLINE_VISIBILITY
462 static constexpr auto&& __get_alt(_Vp&& __v) {
463 return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl);
464 }
465};
466
467} // namespace __access
468
469namespace __visitation {
470
471struct __base {
Eric Fiselier87994112020-11-17 17:34:23 -0500472 template <class _Visitor, class... _Vs>
473 inline _LIBCPP_INLINE_VISIBILITY
474 static constexpr decltype(auto)
475 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
476 constexpr auto __fdiagonal =
477 __make_fdiagonal<_Visitor&&,
478 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
479 return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor),
480 _VSTD::forward<_Vs>(__vs).__as_base()...);
481 }
482
483 template <class _Visitor, class... _Vs>
484 inline _LIBCPP_INLINE_VISIBILITY
485 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
486 _Vs&&... __vs) {
487 constexpr auto __fmatrix =
488 __make_fmatrix<_Visitor&&,
489 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
490 return __at(__fmatrix, __vs.index()...)(
491 _VSTD::forward<_Visitor>(__visitor),
492 _VSTD::forward<_Vs>(__vs).__as_base()...);
493 }
494
495private:
496 template <class _Tp>
497 inline _LIBCPP_INLINE_VISIBILITY
498 static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }
499
500 template <class _Tp, size_t _Np, typename... _Indices>
501 inline _LIBCPP_INLINE_VISIBILITY
502 static constexpr auto&& __at(const array<_Tp, _Np>& __elems,
503 size_t __index, _Indices... __indices) {
504 return __at(__elems[__index], __indices...);
505 }
506
507 template <class _Fp, class... _Fs>
508 static constexpr void __std_visit_visitor_return_type_check() {
509 static_assert(
510 __all<is_same_v<_Fp, _Fs>...>::value,
511 "`std::visit` requires the visitor to have a single return type.");
512 }
513
514 template <class... _Fs>
515 inline _LIBCPP_INLINE_VISIBILITY
516 static constexpr auto __make_farray(_Fs&&... __fs) {
517 __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
518 using __result = array<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
519 return __result{{_VSTD::forward<_Fs>(__fs)...}};
520 }
521
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500522 template <size_t... _Is>
Eric Fiselier87994112020-11-17 17:34:23 -0500523 struct __dispatcher {
524 template <class _Fp, class... _Vs>
Michael Park32334da2020-08-30 12:42:35 -0400525 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500526 static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500527 return _VSTD::__invoke_constexpr(
Eric Fiselier87994112020-11-17 17:34:23 -0500528 static_cast<_Fp>(__f),
529 __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
Michael Park32334da2020-08-30 12:42:35 -0400530 }
531 };
532
Eric Fiselier87994112020-11-17 17:34:23 -0500533 template <class _Fp, class... _Vs, size_t... _Is>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000534 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500535 static constexpr auto __make_dispatch(index_sequence<_Is...>) {
536 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000537 }
538
Eric Fiselier87994112020-11-17 17:34:23 -0500539 template <size_t _Ip, class _Fp, class... _Vs>
540 inline _LIBCPP_INLINE_VISIBILITY
541 static constexpr auto __make_fdiagonal_impl() {
542 return __make_dispatch<_Fp, _Vs...>(
543 index_sequence<(__identity<_Vs>{}, _Ip)...>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000544 }
Eric Fiselier87994112020-11-17 17:34:23 -0500545
546 template <class _Fp, class... _Vs, size_t... _Is>
547 inline _LIBCPP_INLINE_VISIBILITY
548 static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
549 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
550 }
551
552 template <class _Fp, class _Vp, class... _Vs>
553 inline _LIBCPP_INLINE_VISIBILITY
554 static constexpr auto __make_fdiagonal() {
555 constexpr size_t _Np = __uncvref_t<_Vp>::__size();
556 static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
557 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
558 }
559
560 template <class _Fp, class... _Vs, size_t... _Is>
561 inline _LIBCPP_INLINE_VISIBILITY
562 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
563 return __make_dispatch<_Fp, _Vs...>(__is);
564 }
565
566 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
567 inline _LIBCPP_INLINE_VISIBILITY
568 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,
569 index_sequence<_Js...>,
570 _Ls... __ls) {
571 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(
572 index_sequence<_Is..., _Js>{}, __ls...)...);
573 }
574
575 template <class _Fp, class... _Vs>
576 inline _LIBCPP_INLINE_VISIBILITY
577 static constexpr auto __make_fmatrix() {
578 return __make_fmatrix_impl<_Fp, _Vs...>(
579 index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000580 }
581};
582
583struct __variant {
Eric Fiselier87994112020-11-17 17:34:23 -0500584 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000585 inline _LIBCPP_INLINE_VISIBILITY
586 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500587 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000588 return __base::__visit_alt_at(__index,
Eric Fiselier87994112020-11-17 17:34:23 -0500589 _VSTD::forward<_Visitor>(__visitor),
590 _VSTD::forward<_Vs>(__vs).__impl...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000591 }
592
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
Eric Fiselier87994112020-11-17 17:34:23 -0500595 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
596 _Vs&&... __vs) {
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100597 return __base::__visit_alt(
598 _VSTD::forward<_Visitor>(__visitor),
599 _VSTD::__as_variant(_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
604 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500605 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
606 return __visit_alt_at(
607 __index,
608 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
609 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000610 }
611
Eric Fiselier87994112020-11-17 17:34:23 -0500612 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000613 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500614 static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,
615 _Vs&&... __vs) {
616 return __visit_alt(
617 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
618 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000619 }
Marek Kurdej2f5ec002021-03-25 18:09:11 +0100620
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500621#if _LIBCPP_STD_VER > 17
622 template <class _Rp, class _Visitor, class... _Vs>
623 inline _LIBCPP_INLINE_VISIBILITY
624 static constexpr _Rp __visit_value(_Visitor&& __visitor,
625 _Vs&&... __vs) {
626 return __visit_alt(
627 __make_value_visitor<_Rp>(_VSTD::forward<_Visitor>(__visitor)),
628 _VSTD::forward<_Vs>(__vs)...);
629 }
630#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000631
632private:
Eric Fiselier87994112020-11-17 17:34:23 -0500633 template <class _Visitor, class... _Values>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000634 static constexpr void __std_visit_exhaustive_visitor_check() {
Eric Fiselier87994112020-11-17 17:34:23 -0500635 static_assert(is_invocable_v<_Visitor, _Values...>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000636 "`std::visit` requires the visitor to be exhaustive.");
637 }
638
Eric Fiselier87994112020-11-17 17:34:23 -0500639 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000640 struct __value_visitor {
641 template <class... _Alts>
642 inline _LIBCPP_INLINE_VISIBILITY
643 constexpr decltype(auto) operator()(_Alts&&... __alts) const {
644 __std_visit_exhaustive_visitor_check<
Eric Fiselier87994112020-11-17 17:34:23 -0500645 _Visitor,
646 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500647 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000648 _VSTD::forward<_Alts>(__alts).__value...);
649 }
Eric Fiselier87994112020-11-17 17:34:23 -0500650 _Visitor&& __visitor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000651 };
652
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500653#if _LIBCPP_STD_VER > 17
654 template <class _Rp, class _Visitor>
655 struct __value_visitor_return_type {
656 template <class... _Alts>
657 inline _LIBCPP_INLINE_VISIBILITY
658 constexpr _Rp operator()(_Alts&&... __alts) const {
659 __std_visit_exhaustive_visitor_check<
660 _Visitor,
661 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
662 if constexpr (is_void_v<_Rp>) {
663 _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
664 _VSTD::forward<_Alts>(__alts).__value...);
665 }
666 else {
667 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
668 _VSTD::forward<_Alts>(__alts).__value...);
669 }
670 }
671
672 _Visitor&& __visitor;
673 };
674#endif
675
Eric Fiselier87994112020-11-17 17:34:23 -0500676 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000677 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500678 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
679 return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000680 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500681
682#if _LIBCPP_STD_VER > 17
683 template <class _Rp, class _Visitor>
684 inline _LIBCPP_INLINE_VISIBILITY
685 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
686 return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)};
687 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500688#endif
Nico Weber8aa36612021-01-25 15:10:41 -0500689};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000690
691} // namespace __visitation
692
693template <size_t _Index, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000694struct _LIBCPP_TEMPLATE_VIS __alt {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000695 using __value_type = _Tp;
696
697 template <class... _Args>
698 inline _LIBCPP_INLINE_VISIBILITY
699 explicit constexpr __alt(in_place_t, _Args&&... __args)
700 : __value(_VSTD::forward<_Args>(__args)...) {}
701
702 __value_type __value;
703};
704
705template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000706union _LIBCPP_TEMPLATE_VIS __union;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000707
708template <_Trait _DestructibleTrait, size_t _Index>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000709union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000710
711#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
712 template <size_t _Index, class _Tp, class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500713 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000714 _Index, \
715 _Tp, \
716 _Types...> { \
717 public: \
718 inline _LIBCPP_INLINE_VISIBILITY \
719 explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
720 \
721 template <class... _Args> \
722 inline _LIBCPP_INLINE_VISIBILITY \
723 explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
724 : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
725 \
726 template <size_t _Ip, class... _Args> \
727 inline _LIBCPP_INLINE_VISIBILITY \
728 explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
729 : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
730 \
731 __union(const __union&) = default; \
732 __union(__union&&) = default; \
733 \
734 destructor \
735 \
736 __union& operator=(const __union&) = default; \
737 __union& operator=(__union&&) = default; \
738 \
739 private: \
740 char __dummy; \
741 __alt<_Index, _Tp> __head; \
742 __union<destructible_trait, _Index + 1, _Types...> __tail; \
743 \
744 friend struct __access::__union; \
745 }
746
747_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
748_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {});
749_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
750
751#undef _LIBCPP_VARIANT_UNION
752
753template <_Trait _DestructibleTrait, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000754class _LIBCPP_TEMPLATE_VIS __base {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000755public:
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000756 using __index_t = __variant_index_t<sizeof...(_Types)>;
757
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000758 inline _LIBCPP_INLINE_VISIBILITY
759 explicit constexpr __base(__valueless_t tag) noexcept
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000760 : __data(tag), __index(__variant_npos<__index_t>) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000761
762 template <size_t _Ip, class... _Args>
763 inline _LIBCPP_INLINE_VISIBILITY
764 explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
Eric Fiselier2adf0872016-12-02 23:17:33 +0000765 :
766 __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
767 __index(_Ip) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000768
769 inline _LIBCPP_INLINE_VISIBILITY
770 constexpr bool valueless_by_exception() const noexcept {
771 return index() == variant_npos;
772 }
773
774 inline _LIBCPP_INLINE_VISIBILITY
775 constexpr size_t index() const noexcept {
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000776 return __index == __variant_npos<__index_t> ? variant_npos : __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000777 }
778
779protected:
780 inline _LIBCPP_INLINE_VISIBILITY
781 constexpr auto&& __as_base() & { return *this; }
782
783 inline _LIBCPP_INLINE_VISIBILITY
784 constexpr auto&& __as_base() && { return _VSTD::move(*this); }
785
786 inline _LIBCPP_INLINE_VISIBILITY
787 constexpr auto&& __as_base() const & { return *this; }
788
789 inline _LIBCPP_INLINE_VISIBILITY
790 constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
791
792 inline _LIBCPP_INLINE_VISIBILITY
793 static constexpr size_t __size() { return sizeof...(_Types); }
794
795 __union<_DestructibleTrait, 0, _Types...> __data;
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000796 __index_t __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000797
798 friend struct __access::__base;
799 friend struct __visitation::__base;
800};
801
802template <class _Traits, _Trait = _Traits::__destructible_trait>
Louis Dionneff05add2020-10-05 16:30:23 -0400803class _LIBCPP_TEMPLATE_VIS __dtor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000804
805#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \
806 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400807 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, \
808 destructible_trait> \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000809 : public __base<destructible_trait, _Types...> { \
810 using __base_type = __base<destructible_trait, _Types...>; \
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000811 using __index_t = typename __base_type::__index_t; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000812 \
813 public: \
814 using __base_type::__base_type; \
815 using __base_type::operator=; \
816 \
Louis Dionneff05add2020-10-05 16:30:23 -0400817 __dtor(const __dtor&) = default; \
818 __dtor(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000819 destructor \
Louis Dionneff05add2020-10-05 16:30:23 -0400820 __dtor& operator=(const __dtor&) = default; \
821 __dtor& operator=(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000822 \
823 protected: \
824 inline _LIBCPP_INLINE_VISIBILITY \
825 destroy \
826 }
827
828_LIBCPP_VARIANT_DESTRUCTOR(
829 _Trait::_TriviallyAvailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400830 ~__dtor() = default;,
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000831 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000832
833_LIBCPP_VARIANT_DESTRUCTOR(
834 _Trait::_Available,
Louis Dionneff05add2020-10-05 16:30:23 -0400835 ~__dtor() { __destroy(); },
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000836 void __destroy() noexcept {
837 if (!this->valueless_by_exception()) {
838 __visitation::__base::__visit_alt(
839 [](auto& __alt) noexcept {
Marshall Clowe61ba952018-02-12 15:41:25 +0000840 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000841 __alt.~__alt_type();
842 },
843 *this);
844 }
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000845 this->__index = __variant_npos<__index_t>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000846 });
847
848_LIBCPP_VARIANT_DESTRUCTOR(
849 _Trait::_Unavailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400850 ~__dtor() = delete;,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000851 void __destroy() noexcept = delete;);
852
853#undef _LIBCPP_VARIANT_DESTRUCTOR
854
855template <class _Traits>
Louis Dionneff05add2020-10-05 16:30:23 -0400856class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> {
857 using __base_type = __dtor<_Traits>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000858
859public:
860 using __base_type::__base_type;
861 using __base_type::operator=;
862
863protected:
864 template <size_t _Ip, class _Tp, class... _Args>
865 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000866 static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
Eric Fiselier87994112020-11-17 17:34:23 -0500867 ::new ((void*)_VSTD::addressof(__a))
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000868 __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
Eric Fiselier87994112020-11-17 17:34:23 -0500869 return __a.__value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000870 }
871
872 template <class _Rhs>
873 inline _LIBCPP_INLINE_VISIBILITY
Louis Dionneff05add2020-10-05 16:30:23 -0400874 static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000875 __lhs.__destroy();
876 if (!__rhs.valueless_by_exception()) {
877 __visitation::__base::__visit_alt_at(
878 __rhs.index(),
879 [](auto& __lhs_alt, auto&& __rhs_alt) {
880 __construct_alt(
881 __lhs_alt,
882 _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
883 },
884 __lhs, _VSTD::forward<_Rhs>(__rhs));
885 __lhs.__index = __rhs.index();
886 }
887 }
888};
889
890template <class _Traits, _Trait = _Traits::__move_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000891class _LIBCPP_TEMPLATE_VIS __move_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000892
893#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \
894 move_constructor) \
895 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400896 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \
897 move_constructible_trait> \
898 : public __ctor<__traits<_Types...>> { \
899 using __base_type = __ctor<__traits<_Types...>>; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000900 \
901 public: \
902 using __base_type::__base_type; \
903 using __base_type::operator=; \
904 \
905 __move_constructor(const __move_constructor&) = default; \
906 move_constructor \
907 ~__move_constructor() = default; \
908 __move_constructor& operator=(const __move_constructor&) = default; \
909 __move_constructor& operator=(__move_constructor&&) = default; \
910 }
911
912_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
913 _Trait::_TriviallyAvailable,
914 __move_constructor(__move_constructor&& __that) = default;);
915
916_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
917 _Trait::_Available,
918 __move_constructor(__move_constructor&& __that) noexcept(
919 __all<is_nothrow_move_constructible_v<_Types>...>::value)
920 : __move_constructor(__valueless_t{}) {
921 this->__generic_construct(*this, _VSTD::move(__that));
922 });
923
924_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
925 _Trait::_Unavailable,
926 __move_constructor(__move_constructor&&) = delete;);
927
928#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
929
930template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000931class _LIBCPP_TEMPLATE_VIS __copy_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000932
933#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
934 copy_constructor) \
935 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500936 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000937 copy_constructible_trait> \
938 : public __move_constructor<__traits<_Types...>> { \
939 using __base_type = __move_constructor<__traits<_Types...>>; \
940 \
941 public: \
942 using __base_type::__base_type; \
943 using __base_type::operator=; \
944 \
945 copy_constructor \
946 __copy_constructor(__copy_constructor&&) = default; \
947 ~__copy_constructor() = default; \
948 __copy_constructor& operator=(const __copy_constructor&) = default; \
949 __copy_constructor& operator=(__copy_constructor&&) = default; \
950 }
951
952_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
953 _Trait::_TriviallyAvailable,
954 __copy_constructor(const __copy_constructor& __that) = default;);
955
956_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
957 _Trait::_Available,
958 __copy_constructor(const __copy_constructor& __that)
959 : __copy_constructor(__valueless_t{}) {
960 this->__generic_construct(*this, __that);
961 });
962
963_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
964 _Trait::_Unavailable,
965 __copy_constructor(const __copy_constructor&) = delete;);
966
967#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
968
969template <class _Traits>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000970class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000971 using __base_type = __copy_constructor<_Traits>;
972
973public:
974 using __base_type::__base_type;
975 using __base_type::operator=;
976
977 template <size_t _Ip, class... _Args>
978 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000979 auto& __emplace(_Args&&... __args) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000980 this->__destroy();
Eric Fiselier62928442017-04-15 19:32:02 +0000981 auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
Eric Fiselier87994112020-11-17 17:34:23 -0500982 _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000983 this->__index = _Ip;
Eric Fiselier62928442017-04-15 19:32:02 +0000984 return __res;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000985 }
986
987protected:
Michael Park62118352017-06-07 10:22:43 +0000988 template <size_t _Ip, class _Tp, class _Arg>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000989 inline _LIBCPP_INLINE_VISIBILITY
Michael Park62118352017-06-07 10:22:43 +0000990 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000991 if (this->index() == _Ip) {
992 __a.__value = _VSTD::forward<_Arg>(__arg);
993 } else {
994 struct {
995 void operator()(true_type) const {
Michael Park62118352017-06-07 10:22:43 +0000996 __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000997 }
998 void operator()(false_type) const {
Michael Park62118352017-06-07 10:22:43 +0000999 __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001000 }
1001 __assignment* __this;
1002 _Arg&& __arg;
1003 } __impl{this, _VSTD::forward<_Arg>(__arg)};
Michael Park62118352017-06-07 10:22:43 +00001004 __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||
1005 !is_nothrow_move_constructible_v<_Tp>>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001006 }
1007 }
1008
1009 template <class _That>
1010 inline _LIBCPP_INLINE_VISIBILITY
1011 void __generic_assign(_That&& __that) {
1012 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1013 // do nothing.
1014 } else if (__that.valueless_by_exception()) {
1015 this->__destroy();
1016 } else {
1017 __visitation::__base::__visit_alt_at(
1018 __that.index(),
1019 [this](auto& __this_alt, auto&& __that_alt) {
1020 this->__assign_alt(
1021 __this_alt,
Michael Park62118352017-06-07 10:22:43 +00001022 _VSTD::forward<decltype(__that_alt)>(__that_alt).__value);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001023 },
1024 *this, _VSTD::forward<_That>(__that));
1025 }
1026 }
1027};
1028
1029template <class _Traits, _Trait = _Traits::__move_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001030class _LIBCPP_TEMPLATE_VIS __move_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001031
1032#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
1033 move_assignment) \
1034 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001035 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001036 move_assignable_trait> \
1037 : public __assignment<__traits<_Types...>> { \
1038 using __base_type = __assignment<__traits<_Types...>>; \
1039 \
1040 public: \
1041 using __base_type::__base_type; \
1042 using __base_type::operator=; \
1043 \
1044 __move_assignment(const __move_assignment&) = default; \
1045 __move_assignment(__move_assignment&&) = default; \
1046 ~__move_assignment() = default; \
1047 __move_assignment& operator=(const __move_assignment&) = default; \
1048 move_assignment \
1049 }
1050
1051_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1052 _Trait::_TriviallyAvailable,
1053 __move_assignment& operator=(__move_assignment&& __that) = default;);
1054
1055_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1056 _Trait::_Available,
1057 __move_assignment& operator=(__move_assignment&& __that) noexcept(
1058 __all<(is_nothrow_move_constructible_v<_Types> &&
1059 is_nothrow_move_assignable_v<_Types>)...>::value) {
1060 this->__generic_assign(_VSTD::move(__that));
1061 return *this;
1062 });
1063
1064_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1065 _Trait::_Unavailable,
1066 __move_assignment& operator=(__move_assignment&&) = delete;);
1067
1068#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
1069
1070template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001071class _LIBCPP_TEMPLATE_VIS __copy_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001072
1073#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
1074 copy_assignment) \
1075 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001076 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001077 copy_assignable_trait> \
1078 : public __move_assignment<__traits<_Types...>> { \
1079 using __base_type = __move_assignment<__traits<_Types...>>; \
1080 \
1081 public: \
1082 using __base_type::__base_type; \
1083 using __base_type::operator=; \
1084 \
1085 __copy_assignment(const __copy_assignment&) = default; \
1086 __copy_assignment(__copy_assignment&&) = default; \
1087 ~__copy_assignment() = default; \
1088 copy_assignment \
1089 __copy_assignment& operator=(__copy_assignment&&) = default; \
1090 }
1091
1092_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1093 _Trait::_TriviallyAvailable,
1094 __copy_assignment& operator=(const __copy_assignment& __that) = default;);
1095
1096_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1097 _Trait::_Available,
1098 __copy_assignment& operator=(const __copy_assignment& __that) {
1099 this->__generic_assign(__that);
1100 return *this;
1101 });
1102
1103_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1104 _Trait::_Unavailable,
1105 __copy_assignment& operator=(const __copy_assignment&) = delete;);
1106
1107#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1108
1109template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001110class _LIBCPP_TEMPLATE_VIS __impl
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001111 : public __copy_assignment<__traits<_Types...>> {
1112 using __base_type = __copy_assignment<__traits<_Types...>>;
1113
1114public:
1115 using __base_type::__base_type;
1116 using __base_type::operator=;
1117
1118 template <size_t _Ip, class _Arg>
1119 inline _LIBCPP_INLINE_VISIBILITY
1120 void __assign(_Arg&& __arg) {
1121 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
Michael Park62118352017-06-07 10:22:43 +00001122 _VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001123 }
1124
1125 inline _LIBCPP_INLINE_VISIBILITY
1126 void __swap(__impl& __that) {
1127 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1128 // do nothing.
1129 } else if (this->index() == __that.index()) {
1130 __visitation::__base::__visit_alt_at(
1131 this->index(),
1132 [](auto& __this_alt, auto& __that_alt) {
1133 using _VSTD::swap;
1134 swap(__this_alt.__value, __that_alt.__value);
1135 },
1136 *this,
1137 __that);
1138 } else {
1139 __impl* __lhs = this;
1140 __impl* __rhs = _VSTD::addressof(__that);
1141 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1142 _VSTD::swap(__lhs, __rhs);
1143 }
1144 __impl __tmp(_VSTD::move(*__rhs));
Michael Park5dee7342020-06-16 15:15:10 -07001145#ifndef _LIBCPP_NO_EXCEPTIONS
Michael Park6a9ef642020-07-08 10:46:02 -07001146 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
Michael Park31967aa2020-06-16 13:29:23 -07001147 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1148 } else {
1149 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1150 // and `__tmp` is nothrow move constructible then we move `__tmp` back
1151 // into `__rhs` and provide the strong exception safety guarantee.
1152 try {
1153 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1154 } catch (...) {
1155 if (__tmp.__move_nothrow()) {
1156 this->__generic_construct(*__rhs, _VSTD::move(__tmp));
1157 }
1158 throw;
1159 }
1160 }
Michael Park5dee7342020-06-16 15:15:10 -07001161#else
1162 // this isn't consolidated with the `if constexpr` branch above due to
1163 // `throw` being ill-formed with exceptions disabled even when discarded.
1164 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1165#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001166 this->__generic_construct(*__lhs, _VSTD::move(__tmp));
1167 }
1168 }
1169
1170private:
1171 inline _LIBCPP_INLINE_VISIBILITY
1172 bool __move_nothrow() const {
1173 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1174 return this->valueless_by_exception() || __results[this->index()];
1175 }
1176};
1177
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001178struct __no_narrowing_check {
1179 template <class _Dest, class _Source>
1180 using _Apply = __identity<_Dest>;
1181};
1182
1183struct __narrowing_check {
1184 template <class _Dest>
1185 static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>;
1186 template <class _Dest, class _Source>
Arthur O'Dwyer3285c342021-05-10 13:04:16 -04001187 using _Apply _LIBCPP_NODEBUG_TYPE = decltype(__test_impl<_Dest>({declval<_Source>()}));
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001188};
1189
1190template <class _Dest, class _Source>
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001191using __check_for_narrowing _LIBCPP_NODEBUG_TYPE =
1192 typename _If<
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001193#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
1194 false &&
1195#endif
1196 is_arithmetic<_Dest>::value,
1197 __narrowing_check,
1198 __no_narrowing_check
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001199 >::template _Apply<_Dest, _Source>;
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001200
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001201template <class _Tp, size_t _Idx>
1202struct __overload {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001203 template <class _Up>
Eric Fiselier80f5dfb2019-07-14 18:31:55 +00001204 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001205};
1206
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001207template <class _Tp, size_t>
1208struct __overload_bool {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001209 template <class _Up, class _Ap = __uncvref_t<_Up>>
1210 auto operator()(bool, _Up&&) const
1211 -> enable_if_t<is_same_v<_Ap, bool>, __identity<_Tp>>;
1212};
1213
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001214template <size_t _Idx>
1215struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};
1216template <size_t _Idx>
1217struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};
1218template <size_t _Idx>
1219struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};
1220template <size_t _Idx>
1221struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};
1222
1223template <class ..._Bases>
1224struct __all_overloads : _Bases... {
1225 void operator()() const;
1226 using _Bases::operator()...;
1227};
1228
1229template <class IdxSeq>
1230struct __make_overloads_imp;
1231
1232template <size_t ..._Idx>
1233struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1234 template <class ..._Types>
1235 using _Apply _LIBCPP_NODEBUG_TYPE = __all_overloads<__overload<_Types, _Idx>...>;
1236};
1237
1238template <class ..._Types>
1239using _MakeOverloads _LIBCPP_NODEBUG_TYPE = typename __make_overloads_imp<
1240 __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
Zhihao Yuan821efb82019-06-20 22:09:40 +00001241
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001242template <class _Tp, class... _Types>
Zhihao Yuan821efb82019-06-20 22:09:40 +00001243using __best_match_t =
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001244 typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001245
1246} // __variant_detail
1247
1248template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001249class _LIBCPP_TEMPLATE_VIS variant
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001250 : private __sfinae_ctor_base<
1251 __all<is_copy_constructible_v<_Types>...>::value,
1252 __all<is_move_constructible_v<_Types>...>::value>,
1253 private __sfinae_assign_base<
1254 __all<(is_copy_constructible_v<_Types> &&
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001255 is_copy_assignable_v<_Types>)...>::value,
1256 __all<(is_move_constructible_v<_Types> &&
1257 is_move_assignable_v<_Types>)...>::value> {
1258 static_assert(0 < sizeof...(_Types),
1259 "variant must consist of at least one alternative.");
1260
1261 static_assert(__all<!is_array_v<_Types>...>::value,
1262 "variant can not have an array type as an alternative.");
1263
1264 static_assert(__all<!is_reference_v<_Types>...>::value,
1265 "variant can not have a reference type as an alternative.");
1266
1267 static_assert(__all<!is_void_v<_Types>...>::value,
1268 "variant can not have a void type as an alternative.");
1269
1270 using __first_type = variant_alternative_t<0, variant>;
1271
1272public:
1273 template <bool _Dummy = true,
1274 enable_if_t<__dependent_type<is_default_constructible<__first_type>,
1275 _Dummy>::value,
1276 int> = 0>
1277 inline _LIBCPP_INLINE_VISIBILITY
1278 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
1279 : __impl(in_place_index<0>) {}
1280
1281 variant(const variant&) = default;
1282 variant(variant&&) = default;
1283
1284 template <
1285 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001286 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
1287 enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0,
1288 enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001289 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1290 size_t _Ip =
1291 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1292 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1293 inline _LIBCPP_INLINE_VISIBILITY
1294 constexpr variant(_Arg&& __arg) noexcept(
1295 is_nothrow_constructible_v<_Tp, _Arg>)
1296 : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
1297
1298 template <size_t _Ip, class... _Args,
Eric Fiselier5d2df752018-03-23 23:42:30 +00001299 class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1300 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1301 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001302 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001303 explicit constexpr variant(
1304 in_place_index_t<_Ip>,
1305 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001306 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1307
Eric Fiselier5d2df752018-03-23 23:42:30 +00001308 template <
1309 size_t _Ip,
1310 class _Up,
1311 class... _Args,
1312 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1313 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001314 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1315 int> = 0>
1316 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001317 explicit constexpr variant(
1318 in_place_index_t<_Ip>,
1319 initializer_list<_Up> __il,
1320 _Args&&... __args) noexcept(
1321 is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001322 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1323
1324 template <
1325 class _Tp,
1326 class... _Args,
1327 size_t _Ip =
1328 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1329 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1330 inline _LIBCPP_INLINE_VISIBILITY
1331 explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1332 is_nothrow_constructible_v<_Tp, _Args...>)
1333 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1334
1335 template <
1336 class _Tp,
1337 class _Up,
1338 class... _Args,
1339 size_t _Ip =
1340 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1341 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1342 int> = 0>
1343 inline _LIBCPP_INLINE_VISIBILITY
1344 explicit constexpr variant(
1345 in_place_type_t<_Tp>,
1346 initializer_list<_Up> __il,
1347 _Args&&... __args) noexcept(
1348 is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
1349 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1350
1351 ~variant() = default;
1352
1353 variant& operator=(const variant&) = default;
1354 variant& operator=(variant&&) = default;
1355
1356 template <
1357 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001358 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001359 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1360 size_t _Ip =
1361 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1362 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
1363 int> = 0>
1364 inline _LIBCPP_INLINE_VISIBILITY
1365 variant& operator=(_Arg&& __arg) noexcept(
1366 is_nothrow_assignable_v<_Tp&, _Arg> &&
1367 is_nothrow_constructible_v<_Tp, _Arg>) {
1368 __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg));
1369 return *this;
1370 }
1371
1372 template <
1373 size_t _Ip,
1374 class... _Args,
1375 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1376 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1377 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1378 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001379 _Tp& emplace(_Args&&... __args) {
1380 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001381 }
1382
1383 template <
1384 size_t _Ip,
1385 class _Up,
1386 class... _Args,
1387 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1388 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1389 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1390 int> = 0>
1391 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001392 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1393 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001394 }
1395
1396 template <
1397 class _Tp,
1398 class... _Args,
1399 size_t _Ip =
1400 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1401 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1402 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001403 _Tp& emplace(_Args&&... __args) {
1404 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001405 }
1406
1407 template <
1408 class _Tp,
1409 class _Up,
1410 class... _Args,
1411 size_t _Ip =
1412 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1413 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1414 int> = 0>
1415 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001416 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1417 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001418 }
1419
1420 inline _LIBCPP_INLINE_VISIBILITY
1421 constexpr bool valueless_by_exception() const noexcept {
1422 return __impl.valueless_by_exception();
1423 }
1424
1425 inline _LIBCPP_INLINE_VISIBILITY
1426 constexpr size_t index() const noexcept { return __impl.index(); }
1427
1428 template <
1429 bool _Dummy = true,
1430 enable_if_t<
1431 __all<(
1432 __dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1433 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1434 int> = 0>
1435 inline _LIBCPP_INLINE_VISIBILITY
1436 void swap(variant& __that) noexcept(
1437 __all<(is_nothrow_move_constructible_v<_Types> &&
1438 is_nothrow_swappable_v<_Types>)...>::value) {
1439 __impl.__swap(__that.__impl);
1440 }
1441
1442private:
1443 __variant_detail::__impl<_Types...> __impl;
1444
1445 friend struct __variant_detail::__access::__variant;
1446 friend struct __variant_detail::__visitation::__variant;
1447};
1448
1449template <size_t _Ip, class... _Types>
1450inline _LIBCPP_INLINE_VISIBILITY
1451constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1452 return __v.index() == _Ip;
1453}
1454
1455template <class _Tp, class... _Types>
1456inline _LIBCPP_INLINE_VISIBILITY
1457constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1458 return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1459}
1460
1461template <size_t _Ip, class _Vp>
1462inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001463_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Richard Smith66d1c552018-08-27 21:41:50 +00001464constexpr auto&& __generic_get(_Vp&& __v) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001465 using __variant_detail::__access::__variant;
1466 if (!__holds_alternative<_Ip>(__v)) {
Eric Fiselier10642ea2016-12-03 01:58:07 +00001467 __throw_bad_variant_access();
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001468 }
1469 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1470}
1471
1472template <size_t _Ip, class... _Types>
1473inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001474_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001475constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
1476 variant<_Types...>& __v) {
1477 static_assert(_Ip < sizeof...(_Types));
1478 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1479 return __generic_get<_Ip>(__v);
1480}
1481
1482template <size_t _Ip, class... _Types>
1483inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001484_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001485constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
1486 variant<_Types...>&& __v) {
1487 static_assert(_Ip < sizeof...(_Types));
1488 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1489 return __generic_get<_Ip>(_VSTD::move(__v));
1490}
1491
1492template <size_t _Ip, class... _Types>
1493inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001494_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001495constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
1496 const variant<_Types...>& __v) {
1497 static_assert(_Ip < sizeof...(_Types));
1498 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1499 return __generic_get<_Ip>(__v);
1500}
1501
1502template <size_t _Ip, class... _Types>
1503inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001504_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001505constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
1506 const variant<_Types...>&& __v) {
1507 static_assert(_Ip < sizeof...(_Types));
1508 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1509 return __generic_get<_Ip>(_VSTD::move(__v));
1510}
1511
1512template <class _Tp, class... _Types>
1513inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001514_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001515constexpr _Tp& get(variant<_Types...>& __v) {
1516 static_assert(!is_void_v<_Tp>);
1517 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1518}
1519
1520template <class _Tp, class... _Types>
1521inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001522_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001523constexpr _Tp&& get(variant<_Types...>&& __v) {
1524 static_assert(!is_void_v<_Tp>);
1525 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1526 _VSTD::move(__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 const _Tp& get(const variant<_Types...>& __v) {
1533 static_assert(!is_void_v<_Tp>);
1534 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1535}
1536
1537template <class _Tp, class... _Types>
1538inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001539_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001540constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1541 static_assert(!is_void_v<_Tp>);
1542 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1543 _VSTD::move(__v));
1544}
1545
1546template <size_t _Ip, class _Vp>
1547inline _LIBCPP_INLINE_VISIBILITY
1548constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1549 using __variant_detail::__access::__variant;
1550 return __v && __holds_alternative<_Ip>(*__v)
1551 ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value)
1552 : nullptr;
1553}
1554
1555template <size_t _Ip, class... _Types>
1556inline _LIBCPP_INLINE_VISIBILITY
1557constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1558get_if(variant<_Types...>* __v) noexcept {
1559 static_assert(_Ip < sizeof...(_Types));
1560 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1561 return __generic_get_if<_Ip>(__v);
1562}
1563
1564template <size_t _Ip, class... _Types>
1565inline _LIBCPP_INLINE_VISIBILITY
1566constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1567get_if(const 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 <class _Tp, class... _Types>
1574inline _LIBCPP_INLINE_VISIBILITY
1575constexpr add_pointer_t<_Tp>
1576get_if(variant<_Types...>* __v) noexcept {
1577 static_assert(!is_void_v<_Tp>);
1578 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1579}
1580
1581template <class _Tp, class... _Types>
1582inline _LIBCPP_INLINE_VISIBILITY
1583constexpr add_pointer_t<const _Tp>
1584get_if(const variant<_Types...>* __v) noexcept {
1585 static_assert(!is_void_v<_Tp>);
1586 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1587}
1588
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001589template <class _Operator>
1590struct __convert_to_bool {
1591 template <class _T1, class _T2>
1592 _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001593 static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001594 "the relational operator does not return a type which is implicitly convertible to bool");
1595 return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
1596 }
1597};
1598
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001599template <class... _Types>
1600inline _LIBCPP_INLINE_VISIBILITY
1601constexpr bool operator==(const variant<_Types...>& __lhs,
1602 const variant<_Types...>& __rhs) {
1603 using __variant_detail::__visitation::__variant;
1604 if (__lhs.index() != __rhs.index()) return false;
1605 if (__lhs.valueless_by_exception()) return true;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001606 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001607}
1608
1609template <class... _Types>
1610inline _LIBCPP_INLINE_VISIBILITY
1611constexpr bool operator!=(const variant<_Types...>& __lhs,
1612 const variant<_Types...>& __rhs) {
1613 using __variant_detail::__visitation::__variant;
1614 if (__lhs.index() != __rhs.index()) return true;
1615 if (__lhs.valueless_by_exception()) return false;
1616 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001617 __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001618}
1619
1620template <class... _Types>
1621inline _LIBCPP_INLINE_VISIBILITY
1622constexpr bool operator<(const variant<_Types...>& __lhs,
1623 const variant<_Types...>& __rhs) {
1624 using __variant_detail::__visitation::__variant;
1625 if (__rhs.valueless_by_exception()) return false;
1626 if (__lhs.valueless_by_exception()) return true;
1627 if (__lhs.index() < __rhs.index()) return true;
1628 if (__lhs.index() > __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001629 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001630}
1631
1632template <class... _Types>
1633inline _LIBCPP_INLINE_VISIBILITY
1634constexpr bool operator>(const variant<_Types...>& __lhs,
1635 const variant<_Types...>& __rhs) {
1636 using __variant_detail::__visitation::__variant;
1637 if (__lhs.valueless_by_exception()) return false;
1638 if (__rhs.valueless_by_exception()) return true;
1639 if (__lhs.index() > __rhs.index()) return true;
1640 if (__lhs.index() < __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001641 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001642}
1643
1644template <class... _Types>
1645inline _LIBCPP_INLINE_VISIBILITY
1646constexpr bool operator<=(const variant<_Types...>& __lhs,
1647 const variant<_Types...>& __rhs) {
1648 using __variant_detail::__visitation::__variant;
1649 if (__lhs.valueless_by_exception()) return true;
1650 if (__rhs.valueless_by_exception()) return false;
1651 if (__lhs.index() < __rhs.index()) return true;
1652 if (__lhs.index() > __rhs.index()) return false;
1653 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001654 __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001655}
1656
1657template <class... _Types>
1658inline _LIBCPP_INLINE_VISIBILITY
1659constexpr bool operator>=(const variant<_Types...>& __lhs,
1660 const variant<_Types...>& __rhs) {
1661 using __variant_detail::__visitation::__variant;
1662 if (__rhs.valueless_by_exception()) return true;
1663 if (__lhs.valueless_by_exception()) return false;
1664 if (__lhs.index() > __rhs.index()) return true;
1665 if (__lhs.index() < __rhs.index()) return false;
1666 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001667 __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001668}
1669
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001670template <class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001671inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001672 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void
1673 __throw_if_valueless(_Vs&&... __vs) {
1674 const bool __valueless =
1675 (... || _VSTD::__as_variant(__vs).valueless_by_exception());
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001676 if (__valueless) {
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001677 __throw_bad_variant_access();
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001678 }
1679}
1680
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001681template <
1682 class _Visitor, class... _Vs,
Arthur O'Dwyer3285c342021-05-10 13:04:16 -04001683 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001684inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001685 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr
1686 decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001687 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001688 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Eric Fiselier87994112020-11-17 17:34:23 -05001689 return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001690 _VSTD::forward<_Vs>(__vs)...);
1691}
1692
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001693#if _LIBCPP_STD_VER > 17
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001694template <
1695 class _Rp, class _Visitor, class... _Vs,
Arthur O'Dwyer3285c342021-05-10 13:04:16 -04001696 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001697inline _LIBCPP_INLINE_VISIBILITY
Marek Kurdej2f5ec002021-03-25 18:09:11 +01001698 _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp
1699 visit(_Visitor&& __visitor, _Vs&&... __vs) {
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001700 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001701 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001702 return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
1703 _VSTD::forward<_Vs>(__vs)...);
1704}
1705#endif
1706
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001707template <class... _Types>
1708inline _LIBCPP_INLINE_VISIBILITY
1709auto swap(variant<_Types...>& __lhs,
1710 variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs)))
1711 -> decltype(__lhs.swap(__rhs)) {
1712 __lhs.swap(__rhs);
1713}
1714
1715template <class... _Types>
Eric Fiselier698a97b2017-01-21 00:02:12 +00001716struct _LIBCPP_TEMPLATE_VIS hash<
1717 __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001718 using argument_type = variant<_Types...>;
1719 using result_type = size_t;
1720
1721 inline _LIBCPP_INLINE_VISIBILITY
1722 result_type operator()(const argument_type& __v) const {
1723 using __variant_detail::__visitation::__variant;
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001724 size_t __res =
1725 __v.valueless_by_exception()
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001726 ? 299792458 // Random value chosen by the universe upon creation
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001727 : __variant::__visit_alt(
1728 [](const auto& __alt) {
Marshall Clowe61ba952018-02-12 15:41:25 +00001729 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier698a97b2017-01-21 00:02:12 +00001730 using __value_type = remove_const_t<
1731 typename __alt_type::__value_type>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001732 return hash<__value_type>{}(__alt.__value);
1733 },
1734 __v);
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001735 return __hash_combine(__res, hash<size_t>{}(__v.index()));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001736 }
1737};
1738
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001739#endif // _LIBCPP_STD_VER > 14
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001740
1741_LIBCPP_END_NAMESPACE_STD
1742
Eric Fiselier8625d332017-11-19 04:57:22 +00001743_LIBCPP_POP_MACROS
1744
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04001745#endif // _LIBCPP_VARIANT