blob: 770dd335bae21e94d49bdb40b1427b7cb361e354 [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
202#include <__config>
Louis Dionne73912b22020-11-04 15:01:25 -0500203#include <__availability>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000204#include <__tuple>
205#include <array>
206#include <exception>
207#include <functional>
208#include <initializer_list>
209#include <new>
210#include <tuple>
211#include <type_traits>
212#include <utility>
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000213#include <limits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000214#include <version>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000215
216#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
217#pragma GCC system_header
218#endif
219
Eric Fiselier8625d332017-11-19 04:57:22 +0000220_LIBCPP_PUSH_MACROS
221#include <__undef_macros>
222
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000223namespace std { // explicitly not using versioning namespace
224
Louis Dionnecef92e62018-11-19 15:37:04 +0000225class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000226public:
Saleem Abdulrasool5ee83382016-12-31 17:34:26 +0000227 virtual const char* what() const _NOEXCEPT;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000228};
229
230} // namespace std
231
232_LIBCPP_BEGIN_NAMESPACE_STD
233
Louis Dionne7202cd62020-07-22 15:24:16 -0400234// TODO: GCC 5 lies about its support for C++17 (it says it supports it but it
235// really doesn't). That breaks variant, which uses some C++17 features.
236// Remove this once we drop support for GCC 5.
Louis Dionne129391d2020-07-22 15:59:09 -0400237#if _LIBCPP_STD_VER > 14 && !(defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW < 6000)
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000238
Eric Fiselier10642ea2016-12-03 01:58:07 +0000239_LIBCPP_NORETURN
240inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +0000241_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier10642ea2016-12-03 01:58:07 +0000242void __throw_bad_variant_access() {
243#ifndef _LIBCPP_NO_EXCEPTIONS
244 throw bad_variant_access();
245#else
246 _VSTD::abort();
247#endif
248}
249
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000250template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000251class _LIBCPP_TEMPLATE_VIS variant;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000252
253template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000254struct _LIBCPP_TEMPLATE_VIS variant_size;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000255
256template <class _Tp>
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000257_LIBCPP_INLINE_VAR constexpr size_t variant_size_v = variant_size<_Tp>::value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000258
259template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000260struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000261
262template <class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000263struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _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<const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000267 : variant_size<_Tp> {};
268
269template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000270struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000271 : integral_constant<size_t, sizeof...(_Types)> {};
272
273template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000274struct _LIBCPP_TEMPLATE_VIS variant_alternative;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000275
276template <size_t _Ip, class _Tp>
277using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;
278
279template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000280struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000281 : add_const<variant_alternative_t<_Ip, _Tp>> {};
282
283template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000284struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000285 : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
286
287template <size_t _Ip, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000288struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000289 : add_cv<variant_alternative_t<_Ip, _Tp>> {};
290
291template <size_t _Ip, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000292struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
Marshall Clow185577f2017-06-12 16:13:17 +0000293 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000294 using type = __type_pack_element<_Ip, _Types...>;
295};
296
Marshall Clowf1bf62f2018-01-02 17:17:01 +0000297_LIBCPP_INLINE_VAR constexpr size_t variant_npos = static_cast<size_t>(-1);
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000298
299constexpr int __choose_index_type(unsigned int __num_elem) {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500300 if (__num_elem < numeric_limits<unsigned char>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000301 return 0;
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500302 if (__num_elem < numeric_limits<unsigned short>::max())
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000303 return 1;
304 return 2;
305}
306
307template <size_t _NumAlts>
308using __variant_index_t =
309#ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
310 unsigned int;
311#else
312 std::tuple_element_t<
313 __choose_index_type(_NumAlts),
314 std::tuple<unsigned char, unsigned short, unsigned int>
315 >;
316#endif
317
318template <class _IndexType>
319constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000320
321namespace __find_detail {
322
323template <class _Tp, class... _Types>
324inline _LIBCPP_INLINE_VISIBILITY
325constexpr size_t __find_index() {
326 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
327 size_t __result = __not_found;
328 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
329 if (__matches[__i]) {
330 if (__result != __not_found) {
331 return __ambiguous;
332 }
333 __result = __i;
334 }
335 }
336 return __result;
337}
338
339template <size_t _Index>
340struct __find_unambiguous_index_sfinae_impl
341 : integral_constant<size_t, _Index> {};
342
343template <>
344struct __find_unambiguous_index_sfinae_impl<__not_found> {};
345
346template <>
347struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
348
349template <class _Tp, class... _Types>
350struct __find_unambiguous_index_sfinae
351 : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};
352
353} // namespace __find_detail
354
355namespace __variant_detail {
356
357struct __valueless_t {};
358
359enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
360
Eric Fiselier87994112020-11-17 17:34:23 -0500361template <typename _Tp,
362 template <typename> class _IsTriviallyAvailable,
363 template <typename> class _IsAvailable>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000364constexpr _Trait __trait =
365 _IsTriviallyAvailable<_Tp>::value
366 ? _Trait::_TriviallyAvailable
367 : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
368
369inline _LIBCPP_INLINE_VISIBILITY
370constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
371 _Trait __result = _Trait::_TriviallyAvailable;
372 for (_Trait __t : __traits) {
373 if (static_cast<int>(__t) > static_cast<int>(__result)) {
374 __result = __t;
375 }
376 }
377 return __result;
378}
379
Eric Fiselier87994112020-11-17 17:34:23 -0500380template <typename... _Types>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000381struct __traits {
382 static constexpr _Trait __copy_constructible_trait =
383 __common_trait({__trait<_Types,
384 is_trivially_copy_constructible,
385 is_copy_constructible>...});
386
387 static constexpr _Trait __move_constructible_trait =
388 __common_trait({__trait<_Types,
389 is_trivially_move_constructible,
390 is_move_constructible>...});
391
392 static constexpr _Trait __copy_assignable_trait = __common_trait(
393 {__copy_constructible_trait,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000394 __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
395
396 static constexpr _Trait __move_assignable_trait = __common_trait(
397 {__move_constructible_trait,
398 __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
399
400 static constexpr _Trait __destructible_trait = __common_trait(
401 {__trait<_Types, is_trivially_destructible, is_destructible>...});
402};
403
404namespace __access {
405
406struct __union {
407 template <class _Vp>
408 inline _LIBCPP_INLINE_VISIBILITY
409 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
410 return _VSTD::forward<_Vp>(__v).__head;
411 }
412
413 template <class _Vp, size_t _Ip>
414 inline _LIBCPP_INLINE_VISIBILITY
415 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
416 return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
417 }
418};
419
420struct __base {
421 template <size_t _Ip, class _Vp>
422 inline _LIBCPP_INLINE_VISIBILITY
423 static constexpr auto&& __get_alt(_Vp&& __v) {
424 return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
425 in_place_index<_Ip>);
426 }
427};
428
429struct __variant {
430 template <size_t _Ip, class _Vp>
431 inline _LIBCPP_INLINE_VISIBILITY
432 static constexpr auto&& __get_alt(_Vp&& __v) {
433 return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl);
434 }
435};
436
437} // namespace __access
438
439namespace __visitation {
440
441struct __base {
Eric Fiselier87994112020-11-17 17:34:23 -0500442 template <class _Visitor, class... _Vs>
443 inline _LIBCPP_INLINE_VISIBILITY
444 static constexpr decltype(auto)
445 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
446 constexpr auto __fdiagonal =
447 __make_fdiagonal<_Visitor&&,
448 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
449 return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor),
450 _VSTD::forward<_Vs>(__vs).__as_base()...);
451 }
452
453 template <class _Visitor, class... _Vs>
454 inline _LIBCPP_INLINE_VISIBILITY
455 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
456 _Vs&&... __vs) {
457 constexpr auto __fmatrix =
458 __make_fmatrix<_Visitor&&,
459 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
460 return __at(__fmatrix, __vs.index()...)(
461 _VSTD::forward<_Visitor>(__visitor),
462 _VSTD::forward<_Vs>(__vs).__as_base()...);
463 }
464
465private:
466 template <class _Tp>
467 inline _LIBCPP_INLINE_VISIBILITY
468 static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }
469
470 template <class _Tp, size_t _Np, typename... _Indices>
471 inline _LIBCPP_INLINE_VISIBILITY
472 static constexpr auto&& __at(const array<_Tp, _Np>& __elems,
473 size_t __index, _Indices... __indices) {
474 return __at(__elems[__index], __indices...);
475 }
476
477 template <class _Fp, class... _Fs>
478 static constexpr void __std_visit_visitor_return_type_check() {
479 static_assert(
480 __all<is_same_v<_Fp, _Fs>...>::value,
481 "`std::visit` requires the visitor to have a single return type.");
482 }
483
484 template <class... _Fs>
485 inline _LIBCPP_INLINE_VISIBILITY
486 static constexpr auto __make_farray(_Fs&&... __fs) {
487 __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
488 using __result = array<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
489 return __result{{_VSTD::forward<_Fs>(__fs)...}};
490 }
491
Arthur O'Dwyer07b22492020-11-27 11:02:06 -0500492 template <size_t... _Is>
Eric Fiselier87994112020-11-17 17:34:23 -0500493 struct __dispatcher {
494 template <class _Fp, class... _Vs>
Michael Park32334da2020-08-30 12:42:35 -0400495 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500496 static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500497 return _VSTD::__invoke_constexpr(
Eric Fiselier87994112020-11-17 17:34:23 -0500498 static_cast<_Fp>(__f),
499 __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
Michael Park32334da2020-08-30 12:42:35 -0400500 }
501 };
502
Eric Fiselier87994112020-11-17 17:34:23 -0500503 template <class _Fp, class... _Vs, size_t... _Is>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000504 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500505 static constexpr auto __make_dispatch(index_sequence<_Is...>) {
506 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000507 }
508
Eric Fiselier87994112020-11-17 17:34:23 -0500509 template <size_t _Ip, class _Fp, class... _Vs>
510 inline _LIBCPP_INLINE_VISIBILITY
511 static constexpr auto __make_fdiagonal_impl() {
512 return __make_dispatch<_Fp, _Vs...>(
513 index_sequence<(__identity<_Vs>{}, _Ip)...>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000514 }
Eric Fiselier87994112020-11-17 17:34:23 -0500515
516 template <class _Fp, class... _Vs, size_t... _Is>
517 inline _LIBCPP_INLINE_VISIBILITY
518 static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
519 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
520 }
521
522 template <class _Fp, class _Vp, class... _Vs>
523 inline _LIBCPP_INLINE_VISIBILITY
524 static constexpr auto __make_fdiagonal() {
525 constexpr size_t _Np = __uncvref_t<_Vp>::__size();
526 static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
527 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
528 }
529
530 template <class _Fp, class... _Vs, size_t... _Is>
531 inline _LIBCPP_INLINE_VISIBILITY
532 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
533 return __make_dispatch<_Fp, _Vs...>(__is);
534 }
535
536 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
537 inline _LIBCPP_INLINE_VISIBILITY
538 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,
539 index_sequence<_Js...>,
540 _Ls... __ls) {
541 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(
542 index_sequence<_Is..., _Js>{}, __ls...)...);
543 }
544
545 template <class _Fp, class... _Vs>
546 inline _LIBCPP_INLINE_VISIBILITY
547 static constexpr auto __make_fmatrix() {
548 return __make_fmatrix_impl<_Fp, _Vs...>(
549 index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000550 }
551};
552
553struct __variant {
Eric Fiselier87994112020-11-17 17:34:23 -0500554 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000555 inline _LIBCPP_INLINE_VISIBILITY
556 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500557 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000558 return __base::__visit_alt_at(__index,
Eric Fiselier87994112020-11-17 17:34:23 -0500559 _VSTD::forward<_Visitor>(__visitor),
560 _VSTD::forward<_Vs>(__vs).__impl...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000561 }
562
Eric Fiselier87994112020-11-17 17:34:23 -0500563 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000564 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500565 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
566 _Vs&&... __vs) {
567 return __base::__visit_alt(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000568 _VSTD::forward<_Vs>(__vs).__impl...);
569 }
570
Eric Fiselier87994112020-11-17 17:34:23 -0500571 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000572 inline _LIBCPP_INLINE_VISIBILITY
573 static constexpr decltype(auto)
Eric Fiselier87994112020-11-17 17:34:23 -0500574 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
575 return __visit_alt_at(
576 __index,
577 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
578 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000579 }
580
Eric Fiselier87994112020-11-17 17:34:23 -0500581 template <class _Visitor, class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000582 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500583 static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,
584 _Vs&&... __vs) {
585 return __visit_alt(
586 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
587 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000588 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500589#if _LIBCPP_STD_VER > 17
590 template <class _Rp, class _Visitor, class... _Vs>
591 inline _LIBCPP_INLINE_VISIBILITY
592 static constexpr _Rp __visit_value(_Visitor&& __visitor,
593 _Vs&&... __vs) {
594 return __visit_alt(
595 __make_value_visitor<_Rp>(_VSTD::forward<_Visitor>(__visitor)),
596 _VSTD::forward<_Vs>(__vs)...);
597 }
598#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000599
600private:
Eric Fiselier87994112020-11-17 17:34:23 -0500601 template <class _Visitor, class... _Values>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000602 static constexpr void __std_visit_exhaustive_visitor_check() {
Eric Fiselier87994112020-11-17 17:34:23 -0500603 static_assert(is_invocable_v<_Visitor, _Values...>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000604 "`std::visit` requires the visitor to be exhaustive.");
605 }
606
Eric Fiselier87994112020-11-17 17:34:23 -0500607 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000608 struct __value_visitor {
609 template <class... _Alts>
610 inline _LIBCPP_INLINE_VISIBILITY
611 constexpr decltype(auto) operator()(_Alts&&... __alts) const {
612 __std_visit_exhaustive_visitor_check<
Eric Fiselier87994112020-11-17 17:34:23 -0500613 _Visitor,
614 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
Arthur O'Dwyerf0bff152020-11-24 09:59:26 -0500615 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000616 _VSTD::forward<_Alts>(__alts).__value...);
617 }
Eric Fiselier87994112020-11-17 17:34:23 -0500618 _Visitor&& __visitor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000619 };
620
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500621#if _LIBCPP_STD_VER > 17
622 template <class _Rp, class _Visitor>
623 struct __value_visitor_return_type {
624 template <class... _Alts>
625 inline _LIBCPP_INLINE_VISIBILITY
626 constexpr _Rp operator()(_Alts&&... __alts) const {
627 __std_visit_exhaustive_visitor_check<
628 _Visitor,
629 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
630 if constexpr (is_void_v<_Rp>) {
631 _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
632 _VSTD::forward<_Alts>(__alts).__value...);
633 }
634 else {
635 return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor),
636 _VSTD::forward<_Alts>(__alts).__value...);
637 }
638 }
639
640 _Visitor&& __visitor;
641 };
642#endif
643
Eric Fiselier87994112020-11-17 17:34:23 -0500644 template <class _Visitor>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000645 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier87994112020-11-17 17:34:23 -0500646 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
647 return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000648 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500649
650#if _LIBCPP_STD_VER > 17
651 template <class _Rp, class _Visitor>
652 inline _LIBCPP_INLINE_VISIBILITY
653 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
654 return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)};
655 }
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -0500656#endif
Nico Weber8aa36612021-01-25 15:10:41 -0500657};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000658
659} // namespace __visitation
660
661template <size_t _Index, class _Tp>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000662struct _LIBCPP_TEMPLATE_VIS __alt {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000663 using __value_type = _Tp;
664
665 template <class... _Args>
666 inline _LIBCPP_INLINE_VISIBILITY
667 explicit constexpr __alt(in_place_t, _Args&&... __args)
668 : __value(_VSTD::forward<_Args>(__args)...) {}
669
670 __value_type __value;
671};
672
673template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000674union _LIBCPP_TEMPLATE_VIS __union;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000675
676template <_Trait _DestructibleTrait, size_t _Index>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000677union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000678
679#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
680 template <size_t _Index, class _Tp, class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500681 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000682 _Index, \
683 _Tp, \
684 _Types...> { \
685 public: \
686 inline _LIBCPP_INLINE_VISIBILITY \
687 explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
688 \
689 template <class... _Args> \
690 inline _LIBCPP_INLINE_VISIBILITY \
691 explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
692 : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
693 \
694 template <size_t _Ip, class... _Args> \
695 inline _LIBCPP_INLINE_VISIBILITY \
696 explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
697 : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
698 \
699 __union(const __union&) = default; \
700 __union(__union&&) = default; \
701 \
702 destructor \
703 \
704 __union& operator=(const __union&) = default; \
705 __union& operator=(__union&&) = default; \
706 \
707 private: \
708 char __dummy; \
709 __alt<_Index, _Tp> __head; \
710 __union<destructible_trait, _Index + 1, _Types...> __tail; \
711 \
712 friend struct __access::__union; \
713 }
714
715_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
716_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {});
717_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
718
719#undef _LIBCPP_VARIANT_UNION
720
721template <_Trait _DestructibleTrait, class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000722class _LIBCPP_TEMPLATE_VIS __base {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000723public:
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000724 using __index_t = __variant_index_t<sizeof...(_Types)>;
725
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000726 inline _LIBCPP_INLINE_VISIBILITY
727 explicit constexpr __base(__valueless_t tag) noexcept
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000728 : __data(tag), __index(__variant_npos<__index_t>) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000729
730 template <size_t _Ip, class... _Args>
731 inline _LIBCPP_INLINE_VISIBILITY
732 explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
Eric Fiselier2adf0872016-12-02 23:17:33 +0000733 :
734 __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
735 __index(_Ip) {}
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000736
737 inline _LIBCPP_INLINE_VISIBILITY
738 constexpr bool valueless_by_exception() const noexcept {
739 return index() == variant_npos;
740 }
741
742 inline _LIBCPP_INLINE_VISIBILITY
743 constexpr size_t index() const noexcept {
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000744 return __index == __variant_npos<__index_t> ? variant_npos : __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000745 }
746
747protected:
748 inline _LIBCPP_INLINE_VISIBILITY
749 constexpr auto&& __as_base() & { return *this; }
750
751 inline _LIBCPP_INLINE_VISIBILITY
752 constexpr auto&& __as_base() && { return _VSTD::move(*this); }
753
754 inline _LIBCPP_INLINE_VISIBILITY
755 constexpr auto&& __as_base() const & { return *this; }
756
757 inline _LIBCPP_INLINE_VISIBILITY
758 constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
759
760 inline _LIBCPP_INLINE_VISIBILITY
761 static constexpr size_t __size() { return sizeof...(_Types); }
762
763 __union<_DestructibleTrait, 0, _Types...> __data;
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000764 __index_t __index;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000765
766 friend struct __access::__base;
767 friend struct __visitation::__base;
768};
769
770template <class _Traits, _Trait = _Traits::__destructible_trait>
Louis Dionneff05add2020-10-05 16:30:23 -0400771class _LIBCPP_TEMPLATE_VIS __dtor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000772
773#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \
774 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400775 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, \
776 destructible_trait> \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000777 : public __base<destructible_trait, _Types...> { \
778 using __base_type = __base<destructible_trait, _Types...>; \
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000779 using __index_t = typename __base_type::__index_t; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000780 \
781 public: \
782 using __base_type::__base_type; \
783 using __base_type::operator=; \
784 \
Louis Dionneff05add2020-10-05 16:30:23 -0400785 __dtor(const __dtor&) = default; \
786 __dtor(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000787 destructor \
Louis Dionneff05add2020-10-05 16:30:23 -0400788 __dtor& operator=(const __dtor&) = default; \
789 __dtor& operator=(__dtor&&) = default; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000790 \
791 protected: \
792 inline _LIBCPP_INLINE_VISIBILITY \
793 destroy \
794 }
795
796_LIBCPP_VARIANT_DESTRUCTOR(
797 _Trait::_TriviallyAvailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400798 ~__dtor() = default;,
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000799 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000800
801_LIBCPP_VARIANT_DESTRUCTOR(
802 _Trait::_Available,
Louis Dionneff05add2020-10-05 16:30:23 -0400803 ~__dtor() { __destroy(); },
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000804 void __destroy() noexcept {
805 if (!this->valueless_by_exception()) {
806 __visitation::__base::__visit_alt(
807 [](auto& __alt) noexcept {
Marshall Clowe61ba952018-02-12 15:41:25 +0000808 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000809 __alt.~__alt_type();
810 },
811 *this);
812 }
Eric Fiseliercaccc7b2017-11-19 04:19:44 +0000813 this->__index = __variant_npos<__index_t>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000814 });
815
816_LIBCPP_VARIANT_DESTRUCTOR(
817 _Trait::_Unavailable,
Louis Dionneff05add2020-10-05 16:30:23 -0400818 ~__dtor() = delete;,
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000819 void __destroy() noexcept = delete;);
820
821#undef _LIBCPP_VARIANT_DESTRUCTOR
822
823template <class _Traits>
Louis Dionneff05add2020-10-05 16:30:23 -0400824class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> {
825 using __base_type = __dtor<_Traits>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000826
827public:
828 using __base_type::__base_type;
829 using __base_type::operator=;
830
831protected:
832 template <size_t _Ip, class _Tp, class... _Args>
833 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000834 static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
Eric Fiselier87994112020-11-17 17:34:23 -0500835 ::new ((void*)_VSTD::addressof(__a))
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000836 __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
Eric Fiselier87994112020-11-17 17:34:23 -0500837 return __a.__value;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000838 }
839
840 template <class _Rhs>
841 inline _LIBCPP_INLINE_VISIBILITY
Louis Dionneff05add2020-10-05 16:30:23 -0400842 static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000843 __lhs.__destroy();
844 if (!__rhs.valueless_by_exception()) {
845 __visitation::__base::__visit_alt_at(
846 __rhs.index(),
847 [](auto& __lhs_alt, auto&& __rhs_alt) {
848 __construct_alt(
849 __lhs_alt,
850 _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
851 },
852 __lhs, _VSTD::forward<_Rhs>(__rhs));
853 __lhs.__index = __rhs.index();
854 }
855 }
856};
857
858template <class _Traits, _Trait = _Traits::__move_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000859class _LIBCPP_TEMPLATE_VIS __move_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000860
861#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \
862 move_constructor) \
863 template <class... _Types> \
Louis Dionneff05add2020-10-05 16:30:23 -0400864 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \
865 move_constructible_trait> \
866 : public __ctor<__traits<_Types...>> { \
867 using __base_type = __ctor<__traits<_Types...>>; \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000868 \
869 public: \
870 using __base_type::__base_type; \
871 using __base_type::operator=; \
872 \
873 __move_constructor(const __move_constructor&) = default; \
874 move_constructor \
875 ~__move_constructor() = default; \
876 __move_constructor& operator=(const __move_constructor&) = default; \
877 __move_constructor& operator=(__move_constructor&&) = default; \
878 }
879
880_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
881 _Trait::_TriviallyAvailable,
882 __move_constructor(__move_constructor&& __that) = default;);
883
884_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
885 _Trait::_Available,
886 __move_constructor(__move_constructor&& __that) noexcept(
887 __all<is_nothrow_move_constructible_v<_Types>...>::value)
888 : __move_constructor(__valueless_t{}) {
889 this->__generic_construct(*this, _VSTD::move(__that));
890 });
891
892_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
893 _Trait::_Unavailable,
894 __move_constructor(__move_constructor&&) = delete;);
895
896#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
897
898template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000899class _LIBCPP_TEMPLATE_VIS __copy_constructor;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000900
901#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
902 copy_constructor) \
903 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -0500904 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000905 copy_constructible_trait> \
906 : public __move_constructor<__traits<_Types...>> { \
907 using __base_type = __move_constructor<__traits<_Types...>>; \
908 \
909 public: \
910 using __base_type::__base_type; \
911 using __base_type::operator=; \
912 \
913 copy_constructor \
914 __copy_constructor(__copy_constructor&&) = default; \
915 ~__copy_constructor() = default; \
916 __copy_constructor& operator=(const __copy_constructor&) = default; \
917 __copy_constructor& operator=(__copy_constructor&&) = default; \
918 }
919
920_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
921 _Trait::_TriviallyAvailable,
922 __copy_constructor(const __copy_constructor& __that) = default;);
923
924_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
925 _Trait::_Available,
926 __copy_constructor(const __copy_constructor& __that)
927 : __copy_constructor(__valueless_t{}) {
928 this->__generic_construct(*this, __that);
929 });
930
931_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
932 _Trait::_Unavailable,
933 __copy_constructor(const __copy_constructor&) = delete;);
934
935#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
936
937template <class _Traits>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000938class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000939 using __base_type = __copy_constructor<_Traits>;
940
941public:
942 using __base_type::__base_type;
943 using __base_type::operator=;
944
945 template <size_t _Ip, class... _Args>
946 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +0000947 auto& __emplace(_Args&&... __args) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000948 this->__destroy();
Eric Fiselier62928442017-04-15 19:32:02 +0000949 auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
Eric Fiselier87994112020-11-17 17:34:23 -0500950 _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000951 this->__index = _Ip;
Eric Fiselier62928442017-04-15 19:32:02 +0000952 return __res;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000953 }
954
955protected:
Michael Park62118352017-06-07 10:22:43 +0000956 template <size_t _Ip, class _Tp, class _Arg>
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000957 inline _LIBCPP_INLINE_VISIBILITY
Michael Park62118352017-06-07 10:22:43 +0000958 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000959 if (this->index() == _Ip) {
960 __a.__value = _VSTD::forward<_Arg>(__arg);
961 } else {
962 struct {
963 void operator()(true_type) const {
Michael Park62118352017-06-07 10:22:43 +0000964 __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000965 }
966 void operator()(false_type) const {
Michael Park62118352017-06-07 10:22:43 +0000967 __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000968 }
969 __assignment* __this;
970 _Arg&& __arg;
971 } __impl{this, _VSTD::forward<_Arg>(__arg)};
Michael Park62118352017-06-07 10:22:43 +0000972 __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||
973 !is_nothrow_move_constructible_v<_Tp>>{});
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000974 }
975 }
976
977 template <class _That>
978 inline _LIBCPP_INLINE_VISIBILITY
979 void __generic_assign(_That&& __that) {
980 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
981 // do nothing.
982 } else if (__that.valueless_by_exception()) {
983 this->__destroy();
984 } else {
985 __visitation::__base::__visit_alt_at(
986 __that.index(),
987 [this](auto& __this_alt, auto&& __that_alt) {
988 this->__assign_alt(
989 __this_alt,
Michael Park62118352017-06-07 10:22:43 +0000990 _VSTD::forward<decltype(__that_alt)>(__that_alt).__value);
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000991 },
992 *this, _VSTD::forward<_That>(__that));
993 }
994 }
995};
996
997template <class _Traits, _Trait = _Traits::__move_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +0000998class _LIBCPP_TEMPLATE_VIS __move_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +0000999
1000#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
1001 move_assignment) \
1002 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001003 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001004 move_assignable_trait> \
1005 : public __assignment<__traits<_Types...>> { \
1006 using __base_type = __assignment<__traits<_Types...>>; \
1007 \
1008 public: \
1009 using __base_type::__base_type; \
1010 using __base_type::operator=; \
1011 \
1012 __move_assignment(const __move_assignment&) = default; \
1013 __move_assignment(__move_assignment&&) = default; \
1014 ~__move_assignment() = default; \
1015 __move_assignment& operator=(const __move_assignment&) = default; \
1016 move_assignment \
1017 }
1018
1019_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1020 _Trait::_TriviallyAvailable,
1021 __move_assignment& operator=(__move_assignment&& __that) = default;);
1022
1023_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1024 _Trait::_Available,
1025 __move_assignment& operator=(__move_assignment&& __that) noexcept(
1026 __all<(is_nothrow_move_constructible_v<_Types> &&
1027 is_nothrow_move_assignable_v<_Types>)...>::value) {
1028 this->__generic_assign(_VSTD::move(__that));
1029 return *this;
1030 });
1031
1032_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1033 _Trait::_Unavailable,
1034 __move_assignment& operator=(__move_assignment&&) = delete;);
1035
1036#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
1037
1038template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001039class _LIBCPP_TEMPLATE_VIS __copy_assignment;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001040
1041#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
1042 copy_assignment) \
1043 template <class... _Types> \
Eric Fiselier87994112020-11-17 17:34:23 -05001044 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001045 copy_assignable_trait> \
1046 : public __move_assignment<__traits<_Types...>> { \
1047 using __base_type = __move_assignment<__traits<_Types...>>; \
1048 \
1049 public: \
1050 using __base_type::__base_type; \
1051 using __base_type::operator=; \
1052 \
1053 __copy_assignment(const __copy_assignment&) = default; \
1054 __copy_assignment(__copy_assignment&&) = default; \
1055 ~__copy_assignment() = default; \
1056 copy_assignment \
1057 __copy_assignment& operator=(__copy_assignment&&) = default; \
1058 }
1059
1060_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1061 _Trait::_TriviallyAvailable,
1062 __copy_assignment& operator=(const __copy_assignment& __that) = default;);
1063
1064_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1065 _Trait::_Available,
1066 __copy_assignment& operator=(const __copy_assignment& __that) {
1067 this->__generic_assign(__that);
1068 return *this;
1069 });
1070
1071_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1072 _Trait::_Unavailable,
1073 __copy_assignment& operator=(const __copy_assignment&) = delete;);
1074
1075#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1076
1077template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001078class _LIBCPP_TEMPLATE_VIS __impl
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001079 : public __copy_assignment<__traits<_Types...>> {
1080 using __base_type = __copy_assignment<__traits<_Types...>>;
1081
1082public:
1083 using __base_type::__base_type;
1084 using __base_type::operator=;
1085
1086 template <size_t _Ip, class _Arg>
1087 inline _LIBCPP_INLINE_VISIBILITY
1088 void __assign(_Arg&& __arg) {
1089 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
Michael Park62118352017-06-07 10:22:43 +00001090 _VSTD::forward<_Arg>(__arg));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001091 }
1092
1093 inline _LIBCPP_INLINE_VISIBILITY
1094 void __swap(__impl& __that) {
1095 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1096 // do nothing.
1097 } else if (this->index() == __that.index()) {
1098 __visitation::__base::__visit_alt_at(
1099 this->index(),
1100 [](auto& __this_alt, auto& __that_alt) {
1101 using _VSTD::swap;
1102 swap(__this_alt.__value, __that_alt.__value);
1103 },
1104 *this,
1105 __that);
1106 } else {
1107 __impl* __lhs = this;
1108 __impl* __rhs = _VSTD::addressof(__that);
1109 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1110 _VSTD::swap(__lhs, __rhs);
1111 }
1112 __impl __tmp(_VSTD::move(*__rhs));
Michael Park5dee7342020-06-16 15:15:10 -07001113#ifndef _LIBCPP_NO_EXCEPTIONS
Michael Park6a9ef642020-07-08 10:46:02 -07001114 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
Michael Park31967aa2020-06-16 13:29:23 -07001115 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1116 } else {
1117 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1118 // and `__tmp` is nothrow move constructible then we move `__tmp` back
1119 // into `__rhs` and provide the strong exception safety guarantee.
1120 try {
1121 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1122 } catch (...) {
1123 if (__tmp.__move_nothrow()) {
1124 this->__generic_construct(*__rhs, _VSTD::move(__tmp));
1125 }
1126 throw;
1127 }
1128 }
Michael Park5dee7342020-06-16 15:15:10 -07001129#else
1130 // this isn't consolidated with the `if constexpr` branch above due to
1131 // `throw` being ill-formed with exceptions disabled even when discarded.
1132 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1133#endif
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001134 this->__generic_construct(*__lhs, _VSTD::move(__tmp));
1135 }
1136 }
1137
1138private:
1139 inline _LIBCPP_INLINE_VISIBILITY
1140 bool __move_nothrow() const {
1141 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1142 return this->valueless_by_exception() || __results[this->index()];
1143 }
1144};
1145
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001146struct __no_narrowing_check {
1147 template <class _Dest, class _Source>
1148 using _Apply = __identity<_Dest>;
1149};
1150
1151struct __narrowing_check {
1152 template <class _Dest>
1153 static auto __test_impl(_Dest (&&)[1]) -> __identity<_Dest>;
1154 template <class _Dest, class _Source>
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001155 using _Apply _LIBCPP_NODEBUG_TYPE = decltype(__test_impl<_Dest>({_VSTD::declval<_Source>()}));
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001156};
1157
1158template <class _Dest, class _Source>
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001159using __check_for_narrowing _LIBCPP_NODEBUG_TYPE =
1160 typename _If<
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001161#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
1162 false &&
1163#endif
1164 is_arithmetic<_Dest>::value,
1165 __narrowing_check,
1166 __no_narrowing_check
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001167 >::template _Apply<_Dest, _Source>;
Eric Fiselier3aaf8a32019-07-14 18:21:15 +00001168
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001169template <class _Tp, size_t _Idx>
1170struct __overload {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001171 template <class _Up>
Eric Fiselier80f5dfb2019-07-14 18:31:55 +00001172 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001173};
1174
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001175template <class _Tp, size_t>
1176struct __overload_bool {
Zhihao Yuan821efb82019-06-20 22:09:40 +00001177 template <class _Up, class _Ap = __uncvref_t<_Up>>
1178 auto operator()(bool, _Up&&) const
1179 -> enable_if_t<is_same_v<_Ap, bool>, __identity<_Tp>>;
1180};
1181
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001182template <size_t _Idx>
1183struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};
1184template <size_t _Idx>
1185struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};
1186template <size_t _Idx>
1187struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};
1188template <size_t _Idx>
1189struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};
1190
1191template <class ..._Bases>
1192struct __all_overloads : _Bases... {
1193 void operator()() const;
1194 using _Bases::operator()...;
1195};
1196
1197template <class IdxSeq>
1198struct __make_overloads_imp;
1199
1200template <size_t ..._Idx>
1201struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1202 template <class ..._Types>
1203 using _Apply _LIBCPP_NODEBUG_TYPE = __all_overloads<__overload<_Types, _Idx>...>;
1204};
1205
1206template <class ..._Types>
1207using _MakeOverloads _LIBCPP_NODEBUG_TYPE = typename __make_overloads_imp<
1208 __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
Zhihao Yuan821efb82019-06-20 22:09:40 +00001209
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001210template <class _Tp, class... _Types>
Zhihao Yuan821efb82019-06-20 22:09:40 +00001211using __best_match_t =
Eric Fiselieraa7cdca2019-07-14 21:29:39 +00001212 typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001213
1214} // __variant_detail
1215
1216template <class... _Types>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001217class _LIBCPP_TEMPLATE_VIS variant
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001218 : private __sfinae_ctor_base<
1219 __all<is_copy_constructible_v<_Types>...>::value,
1220 __all<is_move_constructible_v<_Types>...>::value>,
1221 private __sfinae_assign_base<
1222 __all<(is_copy_constructible_v<_Types> &&
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001223 is_copy_assignable_v<_Types>)...>::value,
1224 __all<(is_move_constructible_v<_Types> &&
1225 is_move_assignable_v<_Types>)...>::value> {
1226 static_assert(0 < sizeof...(_Types),
1227 "variant must consist of at least one alternative.");
1228
1229 static_assert(__all<!is_array_v<_Types>...>::value,
1230 "variant can not have an array type as an alternative.");
1231
1232 static_assert(__all<!is_reference_v<_Types>...>::value,
1233 "variant can not have a reference type as an alternative.");
1234
1235 static_assert(__all<!is_void_v<_Types>...>::value,
1236 "variant can not have a void type as an alternative.");
1237
1238 using __first_type = variant_alternative_t<0, variant>;
1239
1240public:
1241 template <bool _Dummy = true,
1242 enable_if_t<__dependent_type<is_default_constructible<__first_type>,
1243 _Dummy>::value,
1244 int> = 0>
1245 inline _LIBCPP_INLINE_VISIBILITY
1246 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
1247 : __impl(in_place_index<0>) {}
1248
1249 variant(const variant&) = default;
1250 variant(variant&&) = default;
1251
1252 template <
1253 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001254 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
1255 enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0,
1256 enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001257 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1258 size_t _Ip =
1259 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1260 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1261 inline _LIBCPP_INLINE_VISIBILITY
1262 constexpr variant(_Arg&& __arg) noexcept(
1263 is_nothrow_constructible_v<_Tp, _Arg>)
1264 : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
1265
1266 template <size_t _Ip, class... _Args,
Eric Fiselier5d2df752018-03-23 23:42:30 +00001267 class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1268 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1269 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001270 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001271 explicit constexpr variant(
1272 in_place_index_t<_Ip>,
1273 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001274 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1275
Eric Fiselier5d2df752018-03-23 23:42:30 +00001276 template <
1277 size_t _Ip,
1278 class _Up,
1279 class... _Args,
1280 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1281 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001282 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1283 int> = 0>
1284 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier5d2df752018-03-23 23:42:30 +00001285 explicit constexpr variant(
1286 in_place_index_t<_Ip>,
1287 initializer_list<_Up> __il,
1288 _Args&&... __args) noexcept(
1289 is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001290 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1291
1292 template <
1293 class _Tp,
1294 class... _Args,
1295 size_t _Ip =
1296 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1297 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1298 inline _LIBCPP_INLINE_VISIBILITY
1299 explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1300 is_nothrow_constructible_v<_Tp, _Args...>)
1301 : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
1302
1303 template <
1304 class _Tp,
1305 class _Up,
1306 class... _Args,
1307 size_t _Ip =
1308 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1309 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1310 int> = 0>
1311 inline _LIBCPP_INLINE_VISIBILITY
1312 explicit constexpr variant(
1313 in_place_type_t<_Tp>,
1314 initializer_list<_Up> __il,
1315 _Args&&... __args) noexcept(
1316 is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
1317 : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
1318
1319 ~variant() = default;
1320
1321 variant& operator=(const variant&) = default;
1322 variant& operator=(variant&&) = default;
1323
1324 template <
1325 class _Arg,
Marshall Clowd5bbc242018-02-06 20:56:55 +00001326 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001327 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1328 size_t _Ip =
1329 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1330 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
1331 int> = 0>
1332 inline _LIBCPP_INLINE_VISIBILITY
1333 variant& operator=(_Arg&& __arg) noexcept(
1334 is_nothrow_assignable_v<_Tp&, _Arg> &&
1335 is_nothrow_constructible_v<_Tp, _Arg>) {
1336 __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg));
1337 return *this;
1338 }
1339
1340 template <
1341 size_t _Ip,
1342 class... _Args,
1343 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1344 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1345 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1346 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001347 _Tp& emplace(_Args&&... __args) {
1348 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001349 }
1350
1351 template <
1352 size_t _Ip,
1353 class _Up,
1354 class... _Args,
1355 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1356 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1357 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1358 int> = 0>
1359 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001360 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1361 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001362 }
1363
1364 template <
1365 class _Tp,
1366 class... _Args,
1367 size_t _Ip =
1368 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1369 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1370 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001371 _Tp& emplace(_Args&&... __args) {
1372 return __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001373 }
1374
1375 template <
1376 class _Tp,
1377 class _Up,
1378 class... _Args,
1379 size_t _Ip =
1380 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1381 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1382 int> = 0>
1383 inline _LIBCPP_INLINE_VISIBILITY
Eric Fiselier62928442017-04-15 19:32:02 +00001384 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1385 return __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001386 }
1387
1388 inline _LIBCPP_INLINE_VISIBILITY
1389 constexpr bool valueless_by_exception() const noexcept {
1390 return __impl.valueless_by_exception();
1391 }
1392
1393 inline _LIBCPP_INLINE_VISIBILITY
1394 constexpr size_t index() const noexcept { return __impl.index(); }
1395
1396 template <
1397 bool _Dummy = true,
1398 enable_if_t<
1399 __all<(
1400 __dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1401 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1402 int> = 0>
1403 inline _LIBCPP_INLINE_VISIBILITY
1404 void swap(variant& __that) noexcept(
1405 __all<(is_nothrow_move_constructible_v<_Types> &&
1406 is_nothrow_swappable_v<_Types>)...>::value) {
1407 __impl.__swap(__that.__impl);
1408 }
1409
1410private:
1411 __variant_detail::__impl<_Types...> __impl;
1412
1413 friend struct __variant_detail::__access::__variant;
1414 friend struct __variant_detail::__visitation::__variant;
1415};
1416
1417template <size_t _Ip, class... _Types>
1418inline _LIBCPP_INLINE_VISIBILITY
1419constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1420 return __v.index() == _Ip;
1421}
1422
1423template <class _Tp, class... _Types>
1424inline _LIBCPP_INLINE_VISIBILITY
1425constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1426 return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1427}
1428
1429template <size_t _Ip, class _Vp>
1430inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001431_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Richard Smith66d1c552018-08-27 21:41:50 +00001432constexpr auto&& __generic_get(_Vp&& __v) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001433 using __variant_detail::__access::__variant;
1434 if (!__holds_alternative<_Ip>(__v)) {
Eric Fiselier10642ea2016-12-03 01:58:07 +00001435 __throw_bad_variant_access();
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001436 }
1437 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1438}
1439
1440template <size_t _Ip, class... _Types>
1441inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001442_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001443constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
1444 variant<_Types...>& __v) {
1445 static_assert(_Ip < sizeof...(_Types));
1446 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1447 return __generic_get<_Ip>(__v);
1448}
1449
1450template <size_t _Ip, class... _Types>
1451inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001452_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001453constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
1454 variant<_Types...>&& __v) {
1455 static_assert(_Ip < sizeof...(_Types));
1456 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1457 return __generic_get<_Ip>(_VSTD::move(__v));
1458}
1459
1460template <size_t _Ip, class... _Types>
1461inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001462_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001463constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
1464 const variant<_Types...>& __v) {
1465 static_assert(_Ip < sizeof...(_Types));
1466 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1467 return __generic_get<_Ip>(__v);
1468}
1469
1470template <size_t _Ip, class... _Types>
1471inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001472_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001473constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
1474 const variant<_Types...>&& __v) {
1475 static_assert(_Ip < sizeof...(_Types));
1476 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1477 return __generic_get<_Ip>(_VSTD::move(__v));
1478}
1479
1480template <class _Tp, class... _Types>
1481inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001482_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001483constexpr _Tp& get(variant<_Types...>& __v) {
1484 static_assert(!is_void_v<_Tp>);
1485 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1486}
1487
1488template <class _Tp, class... _Types>
1489inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001490_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001491constexpr _Tp&& get(variant<_Types...>&& __v) {
1492 static_assert(!is_void_v<_Tp>);
1493 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1494 _VSTD::move(__v));
1495}
1496
1497template <class _Tp, class... _Types>
1498inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001499_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001500constexpr const _Tp& get(const variant<_Types...>& __v) {
1501 static_assert(!is_void_v<_Tp>);
1502 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1503}
1504
1505template <class _Tp, class... _Types>
1506inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001507_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001508constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1509 static_assert(!is_void_v<_Tp>);
1510 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1511 _VSTD::move(__v));
1512}
1513
1514template <size_t _Ip, class _Vp>
1515inline _LIBCPP_INLINE_VISIBILITY
1516constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1517 using __variant_detail::__access::__variant;
1518 return __v && __holds_alternative<_Ip>(*__v)
1519 ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value)
1520 : nullptr;
1521}
1522
1523template <size_t _Ip, class... _Types>
1524inline _LIBCPP_INLINE_VISIBILITY
1525constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1526get_if(variant<_Types...>* __v) noexcept {
1527 static_assert(_Ip < sizeof...(_Types));
1528 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1529 return __generic_get_if<_Ip>(__v);
1530}
1531
1532template <size_t _Ip, class... _Types>
1533inline _LIBCPP_INLINE_VISIBILITY
1534constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1535get_if(const variant<_Types...>* __v) noexcept {
1536 static_assert(_Ip < sizeof...(_Types));
1537 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1538 return __generic_get_if<_Ip>(__v);
1539}
1540
1541template <class _Tp, class... _Types>
1542inline _LIBCPP_INLINE_VISIBILITY
1543constexpr add_pointer_t<_Tp>
1544get_if(variant<_Types...>* __v) noexcept {
1545 static_assert(!is_void_v<_Tp>);
1546 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1547}
1548
1549template <class _Tp, class... _Types>
1550inline _LIBCPP_INLINE_VISIBILITY
1551constexpr add_pointer_t<const _Tp>
1552get_if(const variant<_Types...>* __v) noexcept {
1553 static_assert(!is_void_v<_Tp>);
1554 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1555}
1556
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001557template <class _Operator>
1558struct __convert_to_bool {
1559 template <class _T1, class _T2>
1560 _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
Arthur O'Dwyer07b22492020-11-27 11:02:06 -05001561 static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001562 "the relational operator does not return a type which is implicitly convertible to bool");
1563 return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
1564 }
1565};
1566
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001567template <class... _Types>
1568inline _LIBCPP_INLINE_VISIBILITY
1569constexpr bool operator==(const variant<_Types...>& __lhs,
1570 const variant<_Types...>& __rhs) {
1571 using __variant_detail::__visitation::__variant;
1572 if (__lhs.index() != __rhs.index()) return false;
1573 if (__lhs.valueless_by_exception()) return true;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001574 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001575}
1576
1577template <class... _Types>
1578inline _LIBCPP_INLINE_VISIBILITY
1579constexpr bool operator!=(const variant<_Types...>& __lhs,
1580 const variant<_Types...>& __rhs) {
1581 using __variant_detail::__visitation::__variant;
1582 if (__lhs.index() != __rhs.index()) return true;
1583 if (__lhs.valueless_by_exception()) return false;
1584 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001585 __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001586}
1587
1588template <class... _Types>
1589inline _LIBCPP_INLINE_VISIBILITY
1590constexpr bool operator<(const variant<_Types...>& __lhs,
1591 const variant<_Types...>& __rhs) {
1592 using __variant_detail::__visitation::__variant;
1593 if (__rhs.valueless_by_exception()) return false;
1594 if (__lhs.valueless_by_exception()) return true;
1595 if (__lhs.index() < __rhs.index()) return true;
1596 if (__lhs.index() > __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001597 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001598}
1599
1600template <class... _Types>
1601inline _LIBCPP_INLINE_VISIBILITY
1602constexpr bool operator>(const variant<_Types...>& __lhs,
1603 const variant<_Types...>& __rhs) {
1604 using __variant_detail::__visitation::__variant;
1605 if (__lhs.valueless_by_exception()) return false;
1606 if (__rhs.valueless_by_exception()) return true;
1607 if (__lhs.index() > __rhs.index()) return true;
1608 if (__lhs.index() < __rhs.index()) return false;
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001609 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001610}
1611
1612template <class... _Types>
1613inline _LIBCPP_INLINE_VISIBILITY
1614constexpr bool operator<=(const variant<_Types...>& __lhs,
1615 const variant<_Types...>& __rhs) {
1616 using __variant_detail::__visitation::__variant;
1617 if (__lhs.valueless_by_exception()) return true;
1618 if (__rhs.valueless_by_exception()) return false;
1619 if (__lhs.index() < __rhs.index()) return true;
1620 if (__lhs.index() > __rhs.index()) return false;
1621 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001622 __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001623}
1624
1625template <class... _Types>
1626inline _LIBCPP_INLINE_VISIBILITY
1627constexpr bool operator>=(const variant<_Types...>& __lhs,
1628 const variant<_Types...>& __rhs) {
1629 using __variant_detail::__visitation::__variant;
1630 if (__rhs.valueless_by_exception()) return true;
1631 if (__lhs.valueless_by_exception()) return false;
1632 if (__lhs.index() > __rhs.index()) return true;
1633 if (__lhs.index() < __rhs.index()) return false;
1634 return __variant::__visit_value_at(
Eric Fiselierfb6a2bc2018-09-19 17:53:21 +00001635 __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001636}
1637
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001638template <class... _Vs>
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001639inline _LIBCPP_INLINE_VISIBILITY
Louis Dionnecef92e62018-11-19 15:37:04 +00001640_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001641constexpr void __throw_if_valueless(_Vs&&... __vs) {
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001642 const bool __valueless = (... || __vs.valueless_by_exception());
1643 if (__valueless) {
1644 __throw_bad_variant_access();
1645 }
1646}
1647
1648template <class _Visitor, class... _Vs>
1649inline _LIBCPP_INLINE_VISIBILITY
1650_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier87994112020-11-17 17:34:23 -05001651constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001652 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001653 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Eric Fiselier87994112020-11-17 17:34:23 -05001654 return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001655 _VSTD::forward<_Vs>(__vs)...);
1656}
1657
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001658#if _LIBCPP_STD_VER > 17
1659template <class _Rp, class _Visitor, class... _Vs>
1660inline _LIBCPP_INLINE_VISIBILITY
1661_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
1662constexpr _Rp visit(_Visitor&& __visitor, _Vs&&... __vs) {
1663 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan24d0eea2021-01-25 13:34:03 -05001664 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Ruslan Arutyunyan33f34732021-01-25 11:12:25 -05001665 return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
1666 _VSTD::forward<_Vs>(__vs)...);
1667}
1668#endif
1669
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001670struct _LIBCPP_TEMPLATE_VIS monostate {};
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001671
1672inline _LIBCPP_INLINE_VISIBILITY
1673constexpr bool operator<(monostate, monostate) noexcept { return false; }
1674
1675inline _LIBCPP_INLINE_VISIBILITY
1676constexpr bool operator>(monostate, monostate) noexcept { return false; }
1677
1678inline _LIBCPP_INLINE_VISIBILITY
1679constexpr bool operator<=(monostate, monostate) noexcept { return true; }
1680
1681inline _LIBCPP_INLINE_VISIBILITY
1682constexpr bool operator>=(monostate, monostate) noexcept { return true; }
1683
1684inline _LIBCPP_INLINE_VISIBILITY
1685constexpr bool operator==(monostate, monostate) noexcept { return true; }
1686
1687inline _LIBCPP_INLINE_VISIBILITY
1688constexpr bool operator!=(monostate, monostate) noexcept { return false; }
1689
1690template <class... _Types>
1691inline _LIBCPP_INLINE_VISIBILITY
1692auto swap(variant<_Types...>& __lhs,
1693 variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs)))
1694 -> decltype(__lhs.swap(__rhs)) {
1695 __lhs.swap(__rhs);
1696}
1697
1698template <class... _Types>
Eric Fiselier698a97b2017-01-21 00:02:12 +00001699struct _LIBCPP_TEMPLATE_VIS hash<
1700 __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001701 using argument_type = variant<_Types...>;
1702 using result_type = size_t;
1703
1704 inline _LIBCPP_INLINE_VISIBILITY
1705 result_type operator()(const argument_type& __v) const {
1706 using __variant_detail::__visitation::__variant;
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001707 size_t __res =
1708 __v.valueless_by_exception()
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001709 ? 299792458 // Random value chosen by the universe upon creation
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001710 : __variant::__visit_alt(
1711 [](const auto& __alt) {
Marshall Clowe61ba952018-02-12 15:41:25 +00001712 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier698a97b2017-01-21 00:02:12 +00001713 using __value_type = remove_const_t<
1714 typename __alt_type::__value_type>;
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001715 return hash<__value_type>{}(__alt.__value);
1716 },
1717 __v);
Eric Fiselier9a4e3502016-12-02 23:38:31 +00001718 return __hash_combine(__res, hash<size_t>{}(__v.index()));
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001719 }
1720};
1721
1722template <>
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +00001723struct _LIBCPP_TEMPLATE_VIS hash<monostate> {
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001724 using argument_type = monostate;
1725 using result_type = size_t;
1726
1727 inline _LIBCPP_INLINE_VISIBILITY
Marshall Clow49036892017-03-23 02:40:28 +00001728 result_type operator()(const argument_type&) const _NOEXCEPT {
Eric Fiselier6b1683c2016-12-04 21:37:37 +00001729 return 66740831; // return a fundamentally attractive random value.
1730 }
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001731};
1732
1733#endif // _LIBCPP_STD_VER > 14
1734
1735_LIBCPP_END_NAMESPACE_STD
1736
Eric Fiselier8625d332017-11-19 04:57:22 +00001737_LIBCPP_POP_MACROS
1738
Eric Fiselier94cdacc2016-12-02 23:00:05 +00001739#endif // _LIBCPP_VARIANT