blob: a4a3c5bfa868ef8b02fb75d29b83c03bbe655b53 [file] [log] [blame]
Eric Fiselier0d3d8de2016-12-02 23:00:051// -*- C++ -*-
Louis Dionneeb8650a2021-11-17 21:25:012//===----------------------------------------------------------------------===//
Eric Fiselier0d3d8de2016-12-02 23:00:053//
Chandler Carruth57b08b02019-01-19 10:56:404// 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 Fiselier0d3d8de2016-12-02 23:00:057//
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 Dionne1d5f6a82019-01-10 20:06:1125 variant(const variant&); // constexpr in C++20
26 variant(variant&&) noexcept(see below); // constexpr in C++20
Eric Fiselier0d3d8de2016-12-02 23:00:0527
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 Dionne1d5f6a82019-01-10 20:06:1148 variant& operator=(const variant&); // constexpr in C++20
49 variant& operator=(variant&&) noexcept(see below); // constexpr in C++20
Eric Fiselier0d3d8de2016-12-02 23:00:0550
51 template <class T> variant& operator=(T&&) noexcept(see below);
52
53 // 20.7.2.4, modifiers
54 template <class T, class... Args>
Eric Fiselier25514752017-04-15 19:32:0255 T& emplace(Args&&...);
Eric Fiselier0d3d8de2016-12-02 23:00:0556
57 template <class T, class U, class... Args>
Eric Fiselier25514752017-04-15 19:32:0258 T& emplace(initializer_list<U>, Args&&...);
Eric Fiselier0d3d8de2016-12-02 23:00:0559
60 template <size_t I, class... Args>
Eric Fiselier25514752017-04-15 19:32:0261 variant_alternative_t<I, variant>& emplace(Args&&...);
Eric Fiselier0d3d8de2016-12-02 23:00:0562
63 template <size_t I, class U, class... Args>
Eric Fiselier25514752017-04-15 19:32:0264 variant_alternative_t<I, variant>& emplace(initializer_list<U>, Args&&...);
Eric Fiselier0d3d8de2016-12-02 23:00:0565
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 Clow40a01d52018-01-02 17:17:0178 inline constexpr size_t variant_size_v = variant_size<T>::value;
Eric Fiselier0d3d8de2016-12-02 23:00:0579
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 Clow40a01d52018-01-02 17:17:0199 inline constexpr size_t variant_npos = -1;
Eric Fiselier0d3d8de2016-12-02 23:00:05100
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
Kent Rossc4566ca2022-08-14 23:14:57168 template <class... Types>
169 constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
170 operator<=>(const variant<Types...>&, const variant<Types...>&); // since C++20
171
Eric Fiselier0d3d8de2016-12-02 23:00:05172 // 20.7.6, visitation
173 template <class Visitor, class... Variants>
174 constexpr see below visit(Visitor&&, Variants&&...);
175
Ruslan Arutyunyan51faba32021-01-25 16:12:25176 template <class R, class Visitor, class... Variants>
177 constexpr R visit(Visitor&&, Variants&&...); // since C++20
178
Eric Fiselier0d3d8de2016-12-02 23:00:05179 // 20.7.7, class monostate
180 struct monostate;
181
182 // 20.7.8, monostate relational operators
Eric Fiselier0d3d8de2016-12-02 23:00:05183 constexpr bool operator==(monostate, monostate) noexcept;
Kent Rossc4566ca2022-08-14 23:14:57184 constexpr bool operator!=(monostate, monostate) noexcept; // until C++20
185 constexpr bool operator<(monostate, monostate) noexcept; // until C++20
186 constexpr bool operator>(monostate, monostate) noexcept; // until C++20
187 constexpr bool operator<=(monostate, monostate) noexcept; // until C++20
188 constexpr bool operator>=(monostate, monostate) noexcept; // until C++20
189 constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // since C++20
Eric Fiselier0d3d8de2016-12-02 23:00:05190
191 // 20.7.9, specialized algorithms
192 template <class... Types>
193 void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
194
195 // 20.7.10, class bad_variant_access
196 class bad_variant_access;
197
198 // 20.7.11, hash support
199 template <class T> struct hash;
200 template <class... Types> struct hash<variant<Types...>>;
201 template <> struct hash<monostate>;
202
203} // namespace std
204
205*/
206
Louis Dionne385cc252022-03-25 16:55:36207#include <__assert> // all public C++ headers provide the assertion handler
Louis Dionne2eadbc82020-11-04 20:01:25208#include <__availability>
Kent Rossc4566ca2022-08-14 23:14:57209#include <__compare/common_comparison_category.h>
210#include <__compare/compare_three_way_result.h>
211#include <__compare/three_way_comparable.h>
Arthur O'Dwyerbfbd73f2021-05-19 15:57:04212#include <__config>
zoecarver1a294032021-05-27 16:23:19213#include <__functional/hash.h>
Nikolas Klauser169a66e2022-02-11 18:15:18214#include <__functional/operations.h>
215#include <__functional/unary_function.h>
zoecarver1a294032021-05-27 16:23:19216#include <__tuple>
Nikolas Klauser7ae66e52022-08-13 21:10:31217#include <__type_traits/dependent_type.h>
Christopher Di Bella6adbc832021-06-05 02:47:47218#include <__utility/forward.h>
Nikolas Klauser52915d72022-03-05 18:17:07219#include <__utility/in_place.h>
220#include <__utility/move.h>
221#include <__utility/swap.h>
Mark de Wever321c2ea2021-07-07 19:27:27222#include <__variant/monostate.h>
Eric Fiselier0d3d8de2016-12-02 23:00:05223#include <exception>
Eric Fiselier0d3d8de2016-12-02 23:00:05224#include <initializer_list>
Arthur O'Dwyerbfbd73f2021-05-19 15:57:04225#include <limits>
Eric Fiselier0d3d8de2016-12-02 23:00:05226#include <new>
227#include <tuple>
228#include <type_traits>
Marshall Clowf56972e2018-09-12 19:41:40229#include <version>
Eric Fiselier0d3d8de2016-12-02 23:00:05230
Mark de Wever8ff2d6a2022-08-20 08:34:26231#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
Louis Dionnede4a57c2022-06-27 19:53:41232# include <typeinfo>
233# include <utility>
234#endif
235
Nikolas Klauserdb1978b2022-06-16 20:43:46236// standard-mandated includes
237#include <compare>
238
Eric Fiselier0d3d8de2016-12-02 23:00:05239#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Arthur O'Dwyerfa6b9e42022-02-02 01:16:40240# pragma GCC system_header
Eric Fiselier0d3d8de2016-12-02 23:00:05241#endif
242
Eric Fiselierafa6f832017-11-19 04:57:22243_LIBCPP_PUSH_MACROS
244#include <__undef_macros>
245
Eric Fiselier0d3d8de2016-12-02 23:00:05246namespace std { // explicitly not using versioning namespace
247
Louis Dionne8a063df2018-11-19 15:37:04248class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
Eric Fiselier0d3d8de2016-12-02 23:00:05249public:
Nikolas Klauser4262b522022-08-24 00:14:29250 const char* what() const _NOEXCEPT override;
Eric Fiselier0d3d8de2016-12-02 23:00:05251};
252
253} // namespace std
254
255_LIBCPP_BEGIN_NAMESPACE_STD
256
Louis Dionnea4cb5ae2021-08-31 14:49:06257#if _LIBCPP_STD_VER > 14
Eric Fiselier0d3d8de2016-12-02 23:00:05258
zoecarver08494272021-07-07 22:25:53259// Light N-dimensional array of function pointers. Used in place of std::array to avoid
260// adding a dependency.
261template<class _Tp, size_t _Size>
262struct __farray {
263 static_assert(_Size > 0, "N-dimensional array should never be empty in std::visit");
264 _Tp __buf_[_Size] = {};
265
266 _LIBCPP_INLINE_VISIBILITY constexpr
267 const _Tp &operator[](size_t __n) const noexcept {
268 return __buf_[__n];
269 }
270};
271
Eric Fiselier63322af2016-12-03 01:58:07272_LIBCPP_NORETURN
Kent Rossc4566ca2022-08-14 23:14:57273inline _LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:04274_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier63322af2016-12-03 01:58:07275void __throw_bad_variant_access() {
276#ifndef _LIBCPP_NO_EXCEPTIONS
277 throw bad_variant_access();
278#else
279 _VSTD::abort();
280#endif
281}
282
Eric Fiselier0d3d8de2016-12-02 23:00:05283template <class... _Types>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00284class _LIBCPP_TEMPLATE_VIS variant;
Eric Fiselier0d3d8de2016-12-02 23:00:05285
286template <class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00287struct _LIBCPP_TEMPLATE_VIS variant_size;
Eric Fiselier0d3d8de2016-12-02 23:00:05288
289template <class _Tp>
Louis Dionnecb793e12021-09-22 13:35:32290inline constexpr size_t variant_size_v = variant_size<_Tp>::value;
Eric Fiselier0d3d8de2016-12-02 23:00:05291
292template <class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00293struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};
Eric Fiselier0d3d8de2016-12-02 23:00:05294
295template <class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00296struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {};
Eric Fiselier0d3d8de2016-12-02 23:00:05297
298template <class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00299struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp>
Eric Fiselier0d3d8de2016-12-02 23:00:05300 : variant_size<_Tp> {};
301
302template <class... _Types>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00303struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>>
Eric Fiselier0d3d8de2016-12-02 23:00:05304 : integral_constant<size_t, sizeof...(_Types)> {};
305
306template <size_t _Ip, class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00307struct _LIBCPP_TEMPLATE_VIS variant_alternative;
Eric Fiselier0d3d8de2016-12-02 23:00:05308
309template <size_t _Ip, class _Tp>
310using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;
311
312template <size_t _Ip, class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00313struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp>
Eric Fiselier0d3d8de2016-12-02 23:00:05314 : add_const<variant_alternative_t<_Ip, _Tp>> {};
315
316template <size_t _Ip, class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00317struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp>
Eric Fiselier0d3d8de2016-12-02 23:00:05318 : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
319
320template <size_t _Ip, class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00321struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
Eric Fiselier0d3d8de2016-12-02 23:00:05322 : add_cv<variant_alternative_t<_Ip, _Tp>> {};
323
324template <size_t _Ip, class... _Types>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00325struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
Marshall Clow0c69d6e2017-06-12 16:13:17326 static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
Eric Fiselier0d3d8de2016-12-02 23:00:05327 using type = __type_pack_element<_Ip, _Types...>;
328};
329
Louis Dionnecb793e12021-09-22 13:35:32330inline constexpr size_t variant_npos = static_cast<size_t>(-1);
Eric Fiselier0ed52532017-11-19 04:19:44331
Nikolas Klauser80c7e932022-08-13 11:23:16332_LIBCPP_HIDE_FROM_ABI constexpr int __choose_index_type(unsigned int __num_elem) {
Arthur O'Dwyerd586f922020-11-27 16:02:06333 if (__num_elem < numeric_limits<unsigned char>::max())
Eric Fiselier0ed52532017-11-19 04:19:44334 return 0;
Arthur O'Dwyerd586f922020-11-27 16:02:06335 if (__num_elem < numeric_limits<unsigned short>::max())
Eric Fiselier0ed52532017-11-19 04:19:44336 return 1;
337 return 2;
338}
339
340template <size_t _NumAlts>
341using __variant_index_t =
342#ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
343 unsigned int;
344#else
345 std::tuple_element_t<
346 __choose_index_type(_NumAlts),
347 std::tuple<unsigned char, unsigned short, unsigned int>
348 >;
349#endif
350
351template <class _IndexType>
352constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
Eric Fiselier0d3d8de2016-12-02 23:00:05353
Marek Kurdej0324b462021-03-25 17:09:11354template <class... _Types>
355class _LIBCPP_TEMPLATE_VIS variant;
356
357template <class... _Types>
358_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&
359__as_variant(variant<_Types...>& __vs) noexcept {
360 return __vs;
361}
362
363template <class... _Types>
364_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&
365__as_variant(const variant<_Types...>& __vs) noexcept {
366 return __vs;
367}
368
369template <class... _Types>
370_LIBCPP_INLINE_VISIBILITY constexpr variant<_Types...>&&
371__as_variant(variant<_Types...>&& __vs) noexcept {
372 return _VSTD::move(__vs);
373}
374
375template <class... _Types>
376_LIBCPP_INLINE_VISIBILITY constexpr const variant<_Types...>&&
377__as_variant(const variant<_Types...>&& __vs) noexcept {
378 return _VSTD::move(__vs);
379}
380
Eric Fiselier0d3d8de2016-12-02 23:00:05381namespace __find_detail {
382
383template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:57384_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05385constexpr size_t __find_index() {
386 constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
387 size_t __result = __not_found;
388 for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
389 if (__matches[__i]) {
390 if (__result != __not_found) {
391 return __ambiguous;
392 }
393 __result = __i;
394 }
395 }
396 return __result;
397}
398
399template <size_t _Index>
400struct __find_unambiguous_index_sfinae_impl
401 : integral_constant<size_t, _Index> {};
402
403template <>
404struct __find_unambiguous_index_sfinae_impl<__not_found> {};
405
406template <>
407struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
408
409template <class _Tp, class... _Types>
410struct __find_unambiguous_index_sfinae
411 : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};
412
413} // namespace __find_detail
414
415namespace __variant_detail {
416
417struct __valueless_t {};
418
419enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
420
Eric Fiselier9c097572020-11-17 22:34:23421template <typename _Tp,
422 template <typename> class _IsTriviallyAvailable,
423 template <typename> class _IsAvailable>
Eric Fiselier0d3d8de2016-12-02 23:00:05424constexpr _Trait __trait =
425 _IsTriviallyAvailable<_Tp>::value
426 ? _Trait::_TriviallyAvailable
427 : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable;
428
Kent Rossc4566ca2022-08-14 23:14:57429_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05430constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
431 _Trait __result = _Trait::_TriviallyAvailable;
432 for (_Trait __t : __traits) {
433 if (static_cast<int>(__t) > static_cast<int>(__result)) {
434 __result = __t;
435 }
436 }
437 return __result;
438}
439
Eric Fiselier9c097572020-11-17 22:34:23440template <typename... _Types>
Eric Fiselier0d3d8de2016-12-02 23:00:05441struct __traits {
442 static constexpr _Trait __copy_constructible_trait =
443 __common_trait({__trait<_Types,
444 is_trivially_copy_constructible,
445 is_copy_constructible>...});
446
447 static constexpr _Trait __move_constructible_trait =
448 __common_trait({__trait<_Types,
449 is_trivially_move_constructible,
450 is_move_constructible>...});
451
452 static constexpr _Trait __copy_assignable_trait = __common_trait(
453 {__copy_constructible_trait,
Eric Fiselier0d3d8de2016-12-02 23:00:05454 __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
455
456 static constexpr _Trait __move_assignable_trait = __common_trait(
457 {__move_constructible_trait,
458 __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
459
460 static constexpr _Trait __destructible_trait = __common_trait(
461 {__trait<_Types, is_trivially_destructible, is_destructible>...});
462};
463
464namespace __access {
465
466struct __union {
467 template <class _Vp>
Kent Rossc4566ca2022-08-14 23:14:57468 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05469 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
470 return _VSTD::forward<_Vp>(__v).__head;
471 }
472
473 template <class _Vp, size_t _Ip>
Kent Rossc4566ca2022-08-14 23:14:57474 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05475 static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
476 return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
477 }
478};
479
480struct __base {
481 template <size_t _Ip, class _Vp>
Kent Rossc4566ca2022-08-14 23:14:57482 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05483 static constexpr auto&& __get_alt(_Vp&& __v) {
484 return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data,
485 in_place_index<_Ip>);
486 }
487};
488
489struct __variant {
490 template <size_t _Ip, class _Vp>
Kent Rossc4566ca2022-08-14 23:14:57491 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05492 static constexpr auto&& __get_alt(_Vp&& __v) {
Nikolas Klauser84fc2c32022-09-02 14:19:07493 return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl_);
Eric Fiselier0d3d8de2016-12-02 23:00:05494 }
495};
496
497} // namespace __access
498
499namespace __visitation {
500
501struct __base {
Eric Fiselier9c097572020-11-17 22:34:23502 template <class _Visitor, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57503 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23504 static constexpr decltype(auto)
505 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
506 constexpr auto __fdiagonal =
507 __make_fdiagonal<_Visitor&&,
508 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
509 return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor),
510 _VSTD::forward<_Vs>(__vs).__as_base()...);
511 }
512
513 template <class _Visitor, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57514 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23515 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
516 _Vs&&... __vs) {
517 constexpr auto __fmatrix =
518 __make_fmatrix<_Visitor&&,
519 decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>();
520 return __at(__fmatrix, __vs.index()...)(
521 _VSTD::forward<_Visitor>(__visitor),
522 _VSTD::forward<_Vs>(__vs).__as_base()...);
523 }
524
525private:
526 template <class _Tp>
Kent Rossc4566ca2022-08-14 23:14:57527 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23528 static constexpr const _Tp& __at(const _Tp& __elem) { return __elem; }
529
530 template <class _Tp, size_t _Np, typename... _Indices>
Kent Rossc4566ca2022-08-14 23:14:57531 _LIBCPP_HIDE_FROM_ABI
zoecarver08494272021-07-07 22:25:53532 static constexpr auto&& __at(const __farray<_Tp, _Np>& __elems,
Eric Fiselier9c097572020-11-17 22:34:23533 size_t __index, _Indices... __indices) {
534 return __at(__elems[__index], __indices...);
535 }
536
537 template <class _Fp, class... _Fs>
538 static constexpr void __std_visit_visitor_return_type_check() {
539 static_assert(
540 __all<is_same_v<_Fp, _Fs>...>::value,
541 "`std::visit` requires the visitor to have a single return type.");
542 }
543
544 template <class... _Fs>
Kent Rossc4566ca2022-08-14 23:14:57545 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23546 static constexpr auto __make_farray(_Fs&&... __fs) {
547 __std_visit_visitor_return_type_check<__uncvref_t<_Fs>...>();
zoecarver08494272021-07-07 22:25:53548 using __result = __farray<common_type_t<__uncvref_t<_Fs>...>, sizeof...(_Fs)>;
Eric Fiselier9c097572020-11-17 22:34:23549 return __result{{_VSTD::forward<_Fs>(__fs)...}};
550 }
551
Arthur O'Dwyerd586f922020-11-27 16:02:06552 template <size_t... _Is>
Eric Fiselier9c097572020-11-17 22:34:23553 struct __dispatcher {
554 template <class _Fp, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57555 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23556 static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
Nikolas Klauser1b9c5f62022-04-06 21:10:21557 return _VSTD::__invoke(
Eric Fiselier9c097572020-11-17 22:34:23558 static_cast<_Fp>(__f),
559 __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
Michael Park7d15ece2020-08-30 16:42:35560 }
561 };
562
Eric Fiselier9c097572020-11-17 22:34:23563 template <class _Fp, class... _Vs, size_t... _Is>
Kent Rossc4566ca2022-08-14 23:14:57564 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23565 static constexpr auto __make_dispatch(index_sequence<_Is...>) {
566 return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
Eric Fiselier0d3d8de2016-12-02 23:00:05567 }
568
Eric Fiselier9c097572020-11-17 22:34:23569 template <size_t _Ip, class _Fp, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57570 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23571 static constexpr auto __make_fdiagonal_impl() {
572 return __make_dispatch<_Fp, _Vs...>(
Nikolas Klauser3c6bd172022-03-18 16:49:02573 index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{});
Eric Fiselier0d3d8de2016-12-02 23:00:05574 }
Eric Fiselier9c097572020-11-17 22:34:23575
576 template <class _Fp, class... _Vs, size_t... _Is>
Kent Rossc4566ca2022-08-14 23:14:57577 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23578 static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
579 return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
580 }
581
582 template <class _Fp, class _Vp, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57583 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23584 static constexpr auto __make_fdiagonal() {
585 constexpr size_t _Np = __uncvref_t<_Vp>::__size();
586 static_assert(__all<(_Np == __uncvref_t<_Vs>::__size())...>::value);
587 return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{});
588 }
589
590 template <class _Fp, class... _Vs, size_t... _Is>
Kent Rossc4566ca2022-08-14 23:14:57591 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23592 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
593 return __make_dispatch<_Fp, _Vs...>(__is);
594 }
595
596 template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
Kent Rossc4566ca2022-08-14 23:14:57597 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23598 static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>,
599 index_sequence<_Js...>,
600 _Ls... __ls) {
601 return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(
602 index_sequence<_Is..., _Js>{}, __ls...)...);
603 }
604
605 template <class _Fp, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57606 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23607 static constexpr auto __make_fmatrix() {
608 return __make_fmatrix_impl<_Fp, _Vs...>(
609 index_sequence<>{}, make_index_sequence<__uncvref_t<_Vs>::__size()>{}...);
Eric Fiselier0d3d8de2016-12-02 23:00:05610 }
611};
612
613struct __variant {
Eric Fiselier9c097572020-11-17 22:34:23614 template <class _Visitor, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57615 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05616 static constexpr decltype(auto)
Eric Fiselier9c097572020-11-17 22:34:23617 __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier0d3d8de2016-12-02 23:00:05618 return __base::__visit_alt_at(__index,
Eric Fiselier9c097572020-11-17 22:34:23619 _VSTD::forward<_Visitor>(__visitor),
Nikolas Klauser84fc2c32022-09-02 14:19:07620 _VSTD::forward<_Vs>(__vs).__impl_...);
Eric Fiselier0d3d8de2016-12-02 23:00:05621 }
622
Eric Fiselier9c097572020-11-17 22:34:23623 template <class _Visitor, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57624 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23625 static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor,
626 _Vs&&... __vs) {
Marek Kurdej0324b462021-03-25 17:09:11627 return __base::__visit_alt(
628 _VSTD::forward<_Visitor>(__visitor),
Nikolas Klauser84fc2c32022-09-02 14:19:07629 _VSTD::__as_variant(_VSTD::forward<_Vs>(__vs)).__impl_...);
Eric Fiselier0d3d8de2016-12-02 23:00:05630 }
631
Eric Fiselier9c097572020-11-17 22:34:23632 template <class _Visitor, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57633 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05634 static constexpr decltype(auto)
Eric Fiselier9c097572020-11-17 22:34:23635 __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
636 return __visit_alt_at(
637 __index,
638 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
639 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier0d3d8de2016-12-02 23:00:05640 }
641
Eric Fiselier9c097572020-11-17 22:34:23642 template <class _Visitor, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57643 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23644 static constexpr decltype(auto) __visit_value(_Visitor&& __visitor,
645 _Vs&&... __vs) {
646 return __visit_alt(
647 __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)),
648 _VSTD::forward<_Vs>(__vs)...);
Eric Fiselier0d3d8de2016-12-02 23:00:05649 }
Marek Kurdej0324b462021-03-25 17:09:11650
Ruslan Arutyunyan51faba32021-01-25 16:12:25651#if _LIBCPP_STD_VER > 17
652 template <class _Rp, class _Visitor, class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:57653 _LIBCPP_HIDE_FROM_ABI
Ruslan Arutyunyan51faba32021-01-25 16:12:25654 static constexpr _Rp __visit_value(_Visitor&& __visitor,
655 _Vs&&... __vs) {
656 return __visit_alt(
657 __make_value_visitor<_Rp>(_VSTD::forward<_Visitor>(__visitor)),
658 _VSTD::forward<_Vs>(__vs)...);
659 }
660#endif
Eric Fiselier0d3d8de2016-12-02 23:00:05661
662private:
Eric Fiselier9c097572020-11-17 22:34:23663 template <class _Visitor, class... _Values>
Eric Fiselier0d3d8de2016-12-02 23:00:05664 static constexpr void __std_visit_exhaustive_visitor_check() {
Eric Fiselier9c097572020-11-17 22:34:23665 static_assert(is_invocable_v<_Visitor, _Values...>,
Eric Fiselier0d3d8de2016-12-02 23:00:05666 "`std::visit` requires the visitor to be exhaustive.");
667 }
668
Eric Fiselier9c097572020-11-17 22:34:23669 template <class _Visitor>
Eric Fiselier0d3d8de2016-12-02 23:00:05670 struct __value_visitor {
671 template <class... _Alts>
Kent Rossc4566ca2022-08-14 23:14:57672 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05673 constexpr decltype(auto) operator()(_Alts&&... __alts) const {
674 __std_visit_exhaustive_visitor_check<
Eric Fiselier9c097572020-11-17 22:34:23675 _Visitor,
676 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
Nikolas Klauser1b9c5f62022-04-06 21:10:21677 return _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor),
678 _VSTD::forward<_Alts>(__alts).__value...);
Eric Fiselier0d3d8de2016-12-02 23:00:05679 }
Eric Fiselier9c097572020-11-17 22:34:23680 _Visitor&& __visitor;
Eric Fiselier0d3d8de2016-12-02 23:00:05681 };
682
Ruslan Arutyunyan51faba32021-01-25 16:12:25683#if _LIBCPP_STD_VER > 17
684 template <class _Rp, class _Visitor>
685 struct __value_visitor_return_type {
686 template <class... _Alts>
Kent Rossc4566ca2022-08-14 23:14:57687 _LIBCPP_HIDE_FROM_ABI
Ruslan Arutyunyan51faba32021-01-25 16:12:25688 constexpr _Rp operator()(_Alts&&... __alts) const {
689 __std_visit_exhaustive_visitor_check<
690 _Visitor,
691 decltype((_VSTD::forward<_Alts>(__alts).__value))...>();
692 if constexpr (is_void_v<_Rp>) {
Nikolas Klauser1b9c5f62022-04-06 21:10:21693 _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor),
694 _VSTD::forward<_Alts>(__alts).__value...);
Ruslan Arutyunyan51faba32021-01-25 16:12:25695 }
696 else {
Nikolas Klauser1b9c5f62022-04-06 21:10:21697 return _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor),
698 _VSTD::forward<_Alts>(__alts).__value...);
Ruslan Arutyunyan51faba32021-01-25 16:12:25699 }
700 }
701
702 _Visitor&& __visitor;
703 };
704#endif
705
Eric Fiselier9c097572020-11-17 22:34:23706 template <class _Visitor>
Kent Rossc4566ca2022-08-14 23:14:57707 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier9c097572020-11-17 22:34:23708 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
709 return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)};
Eric Fiselier0d3d8de2016-12-02 23:00:05710 }
Ruslan Arutyunyan51faba32021-01-25 16:12:25711
712#if _LIBCPP_STD_VER > 17
713 template <class _Rp, class _Visitor>
Kent Rossc4566ca2022-08-14 23:14:57714 _LIBCPP_HIDE_FROM_ABI
Ruslan Arutyunyan51faba32021-01-25 16:12:25715 static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
716 return __value_visitor_return_type<_Rp, _Visitor>{_VSTD::forward<_Visitor>(__visitor)};
717 }
Ruslan Arutyunyan51faba32021-01-25 16:12:25718#endif
Nico Webera206d992021-01-25 20:10:41719};
Eric Fiselier0d3d8de2016-12-02 23:00:05720
721} // namespace __visitation
722
723template <size_t _Index, class _Tp>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00724struct _LIBCPP_TEMPLATE_VIS __alt {
Eric Fiselier0d3d8de2016-12-02 23:00:05725 using __value_type = _Tp;
726
727 template <class... _Args>
Kent Rossc4566ca2022-08-14 23:14:57728 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05729 explicit constexpr __alt(in_place_t, _Args&&... __args)
730 : __value(_VSTD::forward<_Args>(__args)...) {}
731
732 __value_type __value;
733};
734
735template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00736union _LIBCPP_TEMPLATE_VIS __union;
Eric Fiselier0d3d8de2016-12-02 23:00:05737
738template <_Trait _DestructibleTrait, size_t _Index>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00739union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
Eric Fiselier0d3d8de2016-12-02 23:00:05740
741#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \
742 template <size_t _Index, class _Tp, class... _Types> \
Kent Rossc4566ca2022-08-14 23:14:57743 union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, \
Eric Fiselier0d3d8de2016-12-02 23:00:05744 _Index, \
745 _Tp, \
746 _Types...> { \
747 public: \
Kent Rossc4566ca2022-08-14 23:14:57748 _LIBCPP_HIDE_FROM_ABI \
Eric Fiselier0d3d8de2016-12-02 23:00:05749 explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \
750 \
751 template <class... _Args> \
Kent Rossc4566ca2022-08-14 23:14:57752 _LIBCPP_HIDE_FROM_ABI \
Eric Fiselier0d3d8de2016-12-02 23:00:05753 explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \
754 : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \
755 \
756 template <size_t _Ip, class... _Args> \
Kent Rossc4566ca2022-08-14 23:14:57757 _LIBCPP_HIDE_FROM_ABI \
Eric Fiselier0d3d8de2016-12-02 23:00:05758 explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \
759 : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \
760 \
761 __union(const __union&) = default; \
762 __union(__union&&) = default; \
763 \
764 destructor \
765 \
766 __union& operator=(const __union&) = default; \
767 __union& operator=(__union&&) = default; \
768 \
769 private: \
770 char __dummy; \
771 __alt<_Index, _Tp> __head; \
772 __union<destructible_trait, _Index + 1, _Types...> __tail; \
773 \
774 friend struct __access::__union; \
775 }
776
777_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
778_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {});
779_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
780
781#undef _LIBCPP_VARIANT_UNION
782
783template <_Trait _DestructibleTrait, class... _Types>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00784class _LIBCPP_TEMPLATE_VIS __base {
Eric Fiselier0d3d8de2016-12-02 23:00:05785public:
Eric Fiselier0ed52532017-11-19 04:19:44786 using __index_t = __variant_index_t<sizeof...(_Types)>;
787
Kent Rossc4566ca2022-08-14 23:14:57788 _LIBCPP_HIDE_FROM_ABI
Nikolas Klauserb48c5012022-07-08 16:17:26789 explicit constexpr __base(__valueless_t __tag) noexcept
790 : __data(__tag), __index(__variant_npos<__index_t>) {}
Eric Fiselier0d3d8de2016-12-02 23:00:05791
792 template <size_t _Ip, class... _Args>
Kent Rossc4566ca2022-08-14 23:14:57793 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05794 explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
Eric Fiseliercb3ef152016-12-02 23:17:33795 :
796 __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...),
797 __index(_Ip) {}
Eric Fiselier0d3d8de2016-12-02 23:00:05798
Kent Rossc4566ca2022-08-14 23:14:57799 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05800 constexpr bool valueless_by_exception() const noexcept {
801 return index() == variant_npos;
802 }
803
Kent Rossc4566ca2022-08-14 23:14:57804 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05805 constexpr size_t index() const noexcept {
Eric Fiselier0ed52532017-11-19 04:19:44806 return __index == __variant_npos<__index_t> ? variant_npos : __index;
Eric Fiselier0d3d8de2016-12-02 23:00:05807 }
808
809protected:
Kent Rossc4566ca2022-08-14 23:14:57810 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05811 constexpr auto&& __as_base() & { return *this; }
812
Kent Rossc4566ca2022-08-14 23:14:57813 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05814 constexpr auto&& __as_base() && { return _VSTD::move(*this); }
815
Kent Rossc4566ca2022-08-14 23:14:57816 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05817 constexpr auto&& __as_base() const & { return *this; }
818
Kent Rossc4566ca2022-08-14 23:14:57819 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05820 constexpr auto&& __as_base() const && { return _VSTD::move(*this); }
821
Kent Rossc4566ca2022-08-14 23:14:57822 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:05823 static constexpr size_t __size() { return sizeof...(_Types); }
824
825 __union<_DestructibleTrait, 0, _Types...> __data;
Eric Fiselier0ed52532017-11-19 04:19:44826 __index_t __index;
Eric Fiselier0d3d8de2016-12-02 23:00:05827
828 friend struct __access::__base;
829 friend struct __visitation::__base;
830};
831
832template <class _Traits, _Trait = _Traits::__destructible_trait>
Louis Dionnefe7245b2020-10-05 20:30:23833class _LIBCPP_TEMPLATE_VIS __dtor;
Eric Fiselier0d3d8de2016-12-02 23:00:05834
835#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \
836 template <class... _Types> \
Louis Dionnefe7245b2020-10-05 20:30:23837 class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, \
838 destructible_trait> \
Eric Fiselier0d3d8de2016-12-02 23:00:05839 : public __base<destructible_trait, _Types...> { \
840 using __base_type = __base<destructible_trait, _Types...>; \
Eric Fiselier0ed52532017-11-19 04:19:44841 using __index_t = typename __base_type::__index_t; \
Eric Fiselier0d3d8de2016-12-02 23:00:05842 \
843 public: \
844 using __base_type::__base_type; \
845 using __base_type::operator=; \
846 \
Louis Dionnefe7245b2020-10-05 20:30:23847 __dtor(const __dtor&) = default; \
848 __dtor(__dtor&&) = default; \
Eric Fiselier0d3d8de2016-12-02 23:00:05849 destructor \
Louis Dionnefe7245b2020-10-05 20:30:23850 __dtor& operator=(const __dtor&) = default; \
851 __dtor& operator=(__dtor&&) = default; \
Eric Fiselier0d3d8de2016-12-02 23:00:05852 \
853 protected: \
Kent Rossc4566ca2022-08-14 23:14:57854 inline _LIBCPP_HIDE_FROM_ABI \
Eric Fiselier0d3d8de2016-12-02 23:00:05855 destroy \
856 }
857
858_LIBCPP_VARIANT_DESTRUCTOR(
859 _Trait::_TriviallyAvailable,
Louis Dionnefe7245b2020-10-05 20:30:23860 ~__dtor() = default;,
Eric Fiselier0ed52532017-11-19 04:19:44861 void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
Eric Fiselier0d3d8de2016-12-02 23:00:05862
863_LIBCPP_VARIANT_DESTRUCTOR(
864 _Trait::_Available,
Louis Dionnefe7245b2020-10-05 20:30:23865 ~__dtor() { __destroy(); },
Eric Fiselier0d3d8de2016-12-02 23:00:05866 void __destroy() noexcept {
867 if (!this->valueless_by_exception()) {
868 __visitation::__base::__visit_alt(
869 [](auto& __alt) noexcept {
Marshall Clow8ea7ede2018-02-12 15:41:25870 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselier0d3d8de2016-12-02 23:00:05871 __alt.~__alt_type();
872 },
873 *this);
874 }
Eric Fiselier0ed52532017-11-19 04:19:44875 this->__index = __variant_npos<__index_t>;
Eric Fiselier0d3d8de2016-12-02 23:00:05876 });
877
878_LIBCPP_VARIANT_DESTRUCTOR(
879 _Trait::_Unavailable,
Louis Dionnefe7245b2020-10-05 20:30:23880 ~__dtor() = delete;,
Eric Fiselier0d3d8de2016-12-02 23:00:05881 void __destroy() noexcept = delete;);
882
883#undef _LIBCPP_VARIANT_DESTRUCTOR
884
885template <class _Traits>
Louis Dionnefe7245b2020-10-05 20:30:23886class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> {
887 using __base_type = __dtor<_Traits>;
Eric Fiselier0d3d8de2016-12-02 23:00:05888
889public:
890 using __base_type::__base_type;
891 using __base_type::operator=;
892
893protected:
894 template <size_t _Ip, class _Tp, class... _Args>
Kent Rossc4566ca2022-08-14 23:14:57895 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier25514752017-04-15 19:32:02896 static _Tp& __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) {
Eric Fiselier9c097572020-11-17 22:34:23897 ::new ((void*)_VSTD::addressof(__a))
Eric Fiselier0d3d8de2016-12-02 23:00:05898 __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...);
Eric Fiselier9c097572020-11-17 22:34:23899 return __a.__value;
Eric Fiselier0d3d8de2016-12-02 23:00:05900 }
901
902 template <class _Rhs>
Kent Rossc4566ca2022-08-14 23:14:57903 _LIBCPP_HIDE_FROM_ABI
Louis Dionnefe7245b2020-10-05 20:30:23904 static void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
Eric Fiselier0d3d8de2016-12-02 23:00:05905 __lhs.__destroy();
906 if (!__rhs.valueless_by_exception()) {
907 __visitation::__base::__visit_alt_at(
908 __rhs.index(),
909 [](auto& __lhs_alt, auto&& __rhs_alt) {
910 __construct_alt(
911 __lhs_alt,
912 _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
913 },
914 __lhs, _VSTD::forward<_Rhs>(__rhs));
915 __lhs.__index = __rhs.index();
916 }
917 }
918};
919
920template <class _Traits, _Trait = _Traits::__move_constructible_trait>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00921class _LIBCPP_TEMPLATE_VIS __move_constructor;
Eric Fiselier0d3d8de2016-12-02 23:00:05922
923#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \
924 move_constructor) \
925 template <class... _Types> \
Louis Dionnefe7245b2020-10-05 20:30:23926 class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, \
927 move_constructible_trait> \
928 : public __ctor<__traits<_Types...>> { \
929 using __base_type = __ctor<__traits<_Types...>>; \
Eric Fiselier0d3d8de2016-12-02 23:00:05930 \
931 public: \
932 using __base_type::__base_type; \
933 using __base_type::operator=; \
934 \
935 __move_constructor(const __move_constructor&) = default; \
936 move_constructor \
937 ~__move_constructor() = default; \
938 __move_constructor& operator=(const __move_constructor&) = default; \
939 __move_constructor& operator=(__move_constructor&&) = default; \
940 }
941
942_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
943 _Trait::_TriviallyAvailable,
944 __move_constructor(__move_constructor&& __that) = default;);
945
946_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
947 _Trait::_Available,
948 __move_constructor(__move_constructor&& __that) noexcept(
949 __all<is_nothrow_move_constructible_v<_Types>...>::value)
950 : __move_constructor(__valueless_t{}) {
951 this->__generic_construct(*this, _VSTD::move(__that));
952 });
953
954_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
955 _Trait::_Unavailable,
956 __move_constructor(__move_constructor&&) = delete;);
957
958#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
959
960template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
Eric Fiseliere2f2d1ed2017-01-04 23:56:00961class _LIBCPP_TEMPLATE_VIS __copy_constructor;
Eric Fiselier0d3d8de2016-12-02 23:00:05962
963#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \
964 copy_constructor) \
965 template <class... _Types> \
Kent Rossc4566ca2022-08-14 23:14:57966 class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, \
Eric Fiselier0d3d8de2016-12-02 23:00:05967 copy_constructible_trait> \
968 : public __move_constructor<__traits<_Types...>> { \
969 using __base_type = __move_constructor<__traits<_Types...>>; \
970 \
971 public: \
972 using __base_type::__base_type; \
973 using __base_type::operator=; \
974 \
975 copy_constructor \
976 __copy_constructor(__copy_constructor&&) = default; \
977 ~__copy_constructor() = default; \
978 __copy_constructor& operator=(const __copy_constructor&) = default; \
979 __copy_constructor& operator=(__copy_constructor&&) = default; \
980 }
981
982_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
983 _Trait::_TriviallyAvailable,
984 __copy_constructor(const __copy_constructor& __that) = default;);
985
986_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
987 _Trait::_Available,
988 __copy_constructor(const __copy_constructor& __that)
989 : __copy_constructor(__valueless_t{}) {
990 this->__generic_construct(*this, __that);
991 });
992
993_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
994 _Trait::_Unavailable,
995 __copy_constructor(const __copy_constructor&) = delete;);
996
997#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
998
999template <class _Traits>
Eric Fiseliere2f2d1ed2017-01-04 23:56:001000class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {
Eric Fiselier0d3d8de2016-12-02 23:00:051001 using __base_type = __copy_constructor<_Traits>;
1002
1003public:
1004 using __base_type::__base_type;
1005 using __base_type::operator=;
1006
1007 template <size_t _Ip, class... _Args>
Kent Rossc4566ca2022-08-14 23:14:571008 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier25514752017-04-15 19:32:021009 auto& __emplace(_Args&&... __args) {
Eric Fiselier0d3d8de2016-12-02 23:00:051010 this->__destroy();
Eric Fiselier25514752017-04-15 19:32:021011 auto& __res = this->__construct_alt(__access::__base::__get_alt<_Ip>(*this),
Eric Fiselier9c097572020-11-17 22:34:231012 _VSTD::forward<_Args>(__args)...);
Eric Fiselier0d3d8de2016-12-02 23:00:051013 this->__index = _Ip;
Eric Fiselier25514752017-04-15 19:32:021014 return __res;
Eric Fiselier0d3d8de2016-12-02 23:00:051015 }
1016
1017protected:
Michael Parka8b05742017-06-07 10:22:431018 template <size_t _Ip, class _Tp, class _Arg>
Kent Rossc4566ca2022-08-14 23:14:571019 _LIBCPP_HIDE_FROM_ABI
Michael Parka8b05742017-06-07 10:22:431020 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
Eric Fiselier0d3d8de2016-12-02 23:00:051021 if (this->index() == _Ip) {
1022 __a.__value = _VSTD::forward<_Arg>(__arg);
1023 } else {
1024 struct {
1025 void operator()(true_type) const {
Michael Parka8b05742017-06-07 10:22:431026 __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg));
Eric Fiselier0d3d8de2016-12-02 23:00:051027 }
1028 void operator()(false_type) const {
Michael Parka8b05742017-06-07 10:22:431029 __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg)));
Eric Fiselier0d3d8de2016-12-02 23:00:051030 }
1031 __assignment* __this;
1032 _Arg&& __arg;
1033 } __impl{this, _VSTD::forward<_Arg>(__arg)};
Michael Parka8b05742017-06-07 10:22:431034 __impl(bool_constant<is_nothrow_constructible_v<_Tp, _Arg> ||
1035 !is_nothrow_move_constructible_v<_Tp>>{});
Eric Fiselier0d3d8de2016-12-02 23:00:051036 }
1037 }
1038
1039 template <class _That>
Kent Rossc4566ca2022-08-14 23:14:571040 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051041 void __generic_assign(_That&& __that) {
1042 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1043 // do nothing.
1044 } else if (__that.valueless_by_exception()) {
1045 this->__destroy();
1046 } else {
1047 __visitation::__base::__visit_alt_at(
1048 __that.index(),
1049 [this](auto& __this_alt, auto&& __that_alt) {
1050 this->__assign_alt(
1051 __this_alt,
Michael Parka8b05742017-06-07 10:22:431052 _VSTD::forward<decltype(__that_alt)>(__that_alt).__value);
Eric Fiselier0d3d8de2016-12-02 23:00:051053 },
1054 *this, _VSTD::forward<_That>(__that));
1055 }
1056 }
1057};
1058
1059template <class _Traits, _Trait = _Traits::__move_assignable_trait>
Eric Fiseliere2f2d1ed2017-01-04 23:56:001060class _LIBCPP_TEMPLATE_VIS __move_assignment;
Eric Fiselier0d3d8de2016-12-02 23:00:051061
1062#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \
1063 move_assignment) \
1064 template <class... _Types> \
Kent Rossc4566ca2022-08-14 23:14:571065 class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, \
Eric Fiselier0d3d8de2016-12-02 23:00:051066 move_assignable_trait> \
1067 : public __assignment<__traits<_Types...>> { \
1068 using __base_type = __assignment<__traits<_Types...>>; \
1069 \
1070 public: \
1071 using __base_type::__base_type; \
1072 using __base_type::operator=; \
1073 \
1074 __move_assignment(const __move_assignment&) = default; \
1075 __move_assignment(__move_assignment&&) = default; \
1076 ~__move_assignment() = default; \
1077 __move_assignment& operator=(const __move_assignment&) = default; \
1078 move_assignment \
1079 }
1080
1081_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1082 _Trait::_TriviallyAvailable,
1083 __move_assignment& operator=(__move_assignment&& __that) = default;);
1084
1085_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1086 _Trait::_Available,
1087 __move_assignment& operator=(__move_assignment&& __that) noexcept(
1088 __all<(is_nothrow_move_constructible_v<_Types> &&
1089 is_nothrow_move_assignable_v<_Types>)...>::value) {
1090 this->__generic_assign(_VSTD::move(__that));
1091 return *this;
1092 });
1093
1094_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
1095 _Trait::_Unavailable,
1096 __move_assignment& operator=(__move_assignment&&) = delete;);
1097
1098#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
1099
1100template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
Eric Fiseliere2f2d1ed2017-01-04 23:56:001101class _LIBCPP_TEMPLATE_VIS __copy_assignment;
Eric Fiselier0d3d8de2016-12-02 23:00:051102
1103#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \
1104 copy_assignment) \
1105 template <class... _Types> \
Kent Rossc4566ca2022-08-14 23:14:571106 class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, \
Eric Fiselier0d3d8de2016-12-02 23:00:051107 copy_assignable_trait> \
1108 : public __move_assignment<__traits<_Types...>> { \
1109 using __base_type = __move_assignment<__traits<_Types...>>; \
1110 \
1111 public: \
1112 using __base_type::__base_type; \
1113 using __base_type::operator=; \
1114 \
1115 __copy_assignment(const __copy_assignment&) = default; \
1116 __copy_assignment(__copy_assignment&&) = default; \
1117 ~__copy_assignment() = default; \
1118 copy_assignment \
1119 __copy_assignment& operator=(__copy_assignment&&) = default; \
1120 }
1121
1122_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1123 _Trait::_TriviallyAvailable,
1124 __copy_assignment& operator=(const __copy_assignment& __that) = default;);
1125
1126_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1127 _Trait::_Available,
1128 __copy_assignment& operator=(const __copy_assignment& __that) {
1129 this->__generic_assign(__that);
1130 return *this;
1131 });
1132
1133_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1134 _Trait::_Unavailable,
1135 __copy_assignment& operator=(const __copy_assignment&) = delete;);
1136
1137#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1138
1139template <class... _Types>
Eric Fiseliere2f2d1ed2017-01-04 23:56:001140class _LIBCPP_TEMPLATE_VIS __impl
Eric Fiselier0d3d8de2016-12-02 23:00:051141 : public __copy_assignment<__traits<_Types...>> {
1142 using __base_type = __copy_assignment<__traits<_Types...>>;
1143
1144public:
Louis Dionnee39095a2022-03-03 18:39:121145 using __base_type::__base_type; // get in_place_index_t constructor & friends
1146 __impl(__impl const&) = default;
1147 __impl(__impl&&) = default;
1148 __impl& operator=(__impl const&) = default;
1149 __impl& operator=(__impl&&) = default;
Eric Fiselier0d3d8de2016-12-02 23:00:051150
1151 template <size_t _Ip, class _Arg>
Kent Rossc4566ca2022-08-14 23:14:571152 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051153 void __assign(_Arg&& __arg) {
1154 this->__assign_alt(__access::__base::__get_alt<_Ip>(*this),
Michael Parka8b05742017-06-07 10:22:431155 _VSTD::forward<_Arg>(__arg));
Eric Fiselier0d3d8de2016-12-02 23:00:051156 }
1157
Kent Rossc4566ca2022-08-14 23:14:571158 inline _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051159 void __swap(__impl& __that) {
1160 if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1161 // do nothing.
1162 } else if (this->index() == __that.index()) {
1163 __visitation::__base::__visit_alt_at(
1164 this->index(),
1165 [](auto& __this_alt, auto& __that_alt) {
1166 using _VSTD::swap;
1167 swap(__this_alt.__value, __that_alt.__value);
1168 },
1169 *this,
1170 __that);
1171 } else {
1172 __impl* __lhs = this;
1173 __impl* __rhs = _VSTD::addressof(__that);
1174 if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1175 _VSTD::swap(__lhs, __rhs);
1176 }
1177 __impl __tmp(_VSTD::move(*__rhs));
Michael Park8fbd6d92020-06-16 22:15:101178#ifndef _LIBCPP_NO_EXCEPTIONS
Michael Park6ab32082020-07-08 17:46:021179 if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
Michael Parkada2a8e2020-06-16 20:29:231180 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1181 } else {
1182 // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1183 // and `__tmp` is nothrow move constructible then we move `__tmp` back
1184 // into `__rhs` and provide the strong exception safety guarantee.
1185 try {
1186 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1187 } catch (...) {
1188 if (__tmp.__move_nothrow()) {
1189 this->__generic_construct(*__rhs, _VSTD::move(__tmp));
1190 }
1191 throw;
1192 }
1193 }
Michael Park8fbd6d92020-06-16 22:15:101194#else
1195 // this isn't consolidated with the `if constexpr` branch above due to
1196 // `throw` being ill-formed with exceptions disabled even when discarded.
1197 this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
1198#endif
Eric Fiselier0d3d8de2016-12-02 23:00:051199 this->__generic_construct(*__lhs, _VSTD::move(__tmp));
1200 }
1201 }
1202
1203private:
Kent Rossc4566ca2022-08-14 23:14:571204 inline _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051205 bool __move_nothrow() const {
1206 constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1207 return this->valueless_by_exception() || __results[this->index()];
1208 }
1209};
1210
Eric Fiselier194b3372019-07-14 18:21:151211struct __no_narrowing_check {
1212 template <class _Dest, class _Source>
Nikolas Klauser3c6bd172022-03-18 16:49:021213 using _Apply = __type_identity<_Dest>;
Eric Fiselier194b3372019-07-14 18:21:151214};
1215
1216struct __narrowing_check {
1217 template <class _Dest>
Nikolas Klauser3c6bd172022-03-18 16:49:021218 static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>;
Eric Fiselier194b3372019-07-14 18:21:151219 template <class _Dest, class _Source>
Louis Dionne3557c7c2021-08-31 14:32:111220 using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({declval<_Source>()}));
Eric Fiselier194b3372019-07-14 18:21:151221};
1222
1223template <class _Dest, class _Source>
Louis Dionne3557c7c2021-08-31 14:32:111224using __check_for_narrowing _LIBCPP_NODEBUG =
Eric Fiselier40669782019-07-14 21:29:391225 typename _If<
Eric Fiselier194b3372019-07-14 18:21:151226#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
1227 false &&
1228#endif
1229 is_arithmetic<_Dest>::value,
1230 __narrowing_check,
1231 __no_narrowing_check
Eric Fiselier40669782019-07-14 21:29:391232 >::template _Apply<_Dest, _Source>;
Eric Fiselier194b3372019-07-14 18:21:151233
Eric Fiselier40669782019-07-14 21:29:391234template <class _Tp, size_t _Idx>
1235struct __overload {
Zhihao Yuan4513f0f2019-06-20 22:09:401236 template <class _Up>
Eric Fiselieraae0cb62019-07-14 18:31:551237 auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
Eric Fiselier0d3d8de2016-12-02 23:00:051238};
1239
Eric Fiselier40669782019-07-14 21:29:391240template <class _Tp, size_t>
1241struct __overload_bool {
Zhihao Yuan4513f0f2019-06-20 22:09:401242 template <class _Up, class _Ap = __uncvref_t<_Up>>
1243 auto operator()(bool, _Up&&) const
Nikolas Klauser3c6bd172022-03-18 16:49:021244 -> enable_if_t<is_same_v<_Ap, bool>, __type_identity<_Tp>>;
Zhihao Yuan4513f0f2019-06-20 22:09:401245};
1246
Eric Fiselier40669782019-07-14 21:29:391247template <size_t _Idx>
1248struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};
1249template <size_t _Idx>
1250struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};
1251template <size_t _Idx>
1252struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};
1253template <size_t _Idx>
1254struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};
1255
1256template <class ..._Bases>
1257struct __all_overloads : _Bases... {
1258 void operator()() const;
1259 using _Bases::operator()...;
1260};
1261
1262template <class IdxSeq>
1263struct __make_overloads_imp;
1264
1265template <size_t ..._Idx>
1266struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1267 template <class ..._Types>
Louis Dionne3557c7c2021-08-31 14:32:111268 using _Apply _LIBCPP_NODEBUG = __all_overloads<__overload<_Types, _Idx>...>;
Eric Fiselier40669782019-07-14 21:29:391269};
1270
1271template <class ..._Types>
Louis Dionne3557c7c2021-08-31 14:32:111272using _MakeOverloads _LIBCPP_NODEBUG = typename __make_overloads_imp<
Eric Fiselier40669782019-07-14 21:29:391273 __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
Zhihao Yuan4513f0f2019-06-20 22:09:401274
Eric Fiselier0d3d8de2016-12-02 23:00:051275template <class _Tp, class... _Types>
Zhihao Yuan4513f0f2019-06-20 22:09:401276using __best_match_t =
Eric Fiselier40669782019-07-14 21:29:391277 typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
Eric Fiselier0d3d8de2016-12-02 23:00:051278
Nikolas Klauser9c52a192022-02-01 17:11:491279} // namespace __variant_detail
Eric Fiselier0d3d8de2016-12-02 23:00:051280
1281template <class... _Types>
Eric Fiseliere2f2d1ed2017-01-04 23:56:001282class _LIBCPP_TEMPLATE_VIS variant
Eric Fiselier0d3d8de2016-12-02 23:00:051283 : private __sfinae_ctor_base<
1284 __all<is_copy_constructible_v<_Types>...>::value,
1285 __all<is_move_constructible_v<_Types>...>::value>,
1286 private __sfinae_assign_base<
1287 __all<(is_copy_constructible_v<_Types> &&
Eric Fiselier0d3d8de2016-12-02 23:00:051288 is_copy_assignable_v<_Types>)...>::value,
1289 __all<(is_move_constructible_v<_Types> &&
1290 is_move_assignable_v<_Types>)...>::value> {
1291 static_assert(0 < sizeof...(_Types),
1292 "variant must consist of at least one alternative.");
1293
1294 static_assert(__all<!is_array_v<_Types>...>::value,
1295 "variant can not have an array type as an alternative.");
1296
1297 static_assert(__all<!is_reference_v<_Types>...>::value,
1298 "variant can not have a reference type as an alternative.");
1299
1300 static_assert(__all<!is_void_v<_Types>...>::value,
1301 "variant can not have a void type as an alternative.");
1302
1303 using __first_type = variant_alternative_t<0, variant>;
1304
1305public:
1306 template <bool _Dummy = true,
1307 enable_if_t<__dependent_type<is_default_constructible<__first_type>,
1308 _Dummy>::value,
1309 int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571310 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051311 constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
Nikolas Klauser84fc2c32022-09-02 14:19:071312 : __impl_(in_place_index<0>) {}
Eric Fiselier0d3d8de2016-12-02 23:00:051313
1314 variant(const variant&) = default;
1315 variant(variant&&) = default;
1316
1317 template <
1318 class _Arg,
Marshall Clow655c4692018-02-06 20:56:551319 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
1320 enable_if_t<!__is_inplace_type<__uncvref_t<_Arg>>::value, int> = 0,
1321 enable_if_t<!__is_inplace_index<__uncvref_t<_Arg>>::value, int> = 0,
Eric Fiselier0d3d8de2016-12-02 23:00:051322 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1323 size_t _Ip =
1324 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1325 enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571326 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051327 constexpr variant(_Arg&& __arg) noexcept(
1328 is_nothrow_constructible_v<_Tp, _Arg>)
Nikolas Klauser84fc2c32022-09-02 14:19:071329 : __impl_(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {}
Eric Fiselier0d3d8de2016-12-02 23:00:051330
1331 template <size_t _Ip, class... _Args,
Eric Fiseliercd5e6a32018-03-23 23:42:301332 class = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1333 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1334 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571335 _LIBCPP_HIDE_FROM_ABI
Eric Fiseliercd5e6a32018-03-23 23:42:301336 explicit constexpr variant(
1337 in_place_index_t<_Ip>,
1338 _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
Nikolas Klauser84fc2c32022-09-02 14:19:071339 : __impl_(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
Eric Fiselier0d3d8de2016-12-02 23:00:051340
Eric Fiseliercd5e6a32018-03-23 23:42:301341 template <
1342 size_t _Ip,
1343 class _Up,
1344 class... _Args,
1345 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1346 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
Eric Fiselier0d3d8de2016-12-02 23:00:051347 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1348 int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571349 _LIBCPP_HIDE_FROM_ABI
Eric Fiseliercd5e6a32018-03-23 23:42:301350 explicit constexpr variant(
1351 in_place_index_t<_Ip>,
1352 initializer_list<_Up> __il,
1353 _Args&&... __args) noexcept(
1354 is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
Nikolas Klauser84fc2c32022-09-02 14:19:071355 : __impl_(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
Eric Fiselier0d3d8de2016-12-02 23:00:051356
1357 template <
1358 class _Tp,
1359 class... _Args,
1360 size_t _Ip =
1361 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1362 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571363 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051364 explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1365 is_nothrow_constructible_v<_Tp, _Args...>)
Nikolas Klauser84fc2c32022-09-02 14:19:071366 : __impl_(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {}
Eric Fiselier0d3d8de2016-12-02 23:00:051367
1368 template <
1369 class _Tp,
1370 class _Up,
1371 class... _Args,
1372 size_t _Ip =
1373 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1374 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1375 int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571376 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051377 explicit constexpr variant(
1378 in_place_type_t<_Tp>,
1379 initializer_list<_Up> __il,
1380 _Args&&... __args) noexcept(
1381 is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
Nikolas Klauser84fc2c32022-09-02 14:19:071382 : __impl_(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {}
Eric Fiselier0d3d8de2016-12-02 23:00:051383
1384 ~variant() = default;
1385
1386 variant& operator=(const variant&) = default;
1387 variant& operator=(variant&&) = default;
1388
1389 template <
1390 class _Arg,
Marshall Clow655c4692018-02-06 20:56:551391 enable_if_t<!is_same_v<__uncvref_t<_Arg>, variant>, int> = 0,
Eric Fiselier0d3d8de2016-12-02 23:00:051392 class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>,
1393 size_t _Ip =
1394 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1395 enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>,
1396 int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571397 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051398 variant& operator=(_Arg&& __arg) noexcept(
1399 is_nothrow_assignable_v<_Tp&, _Arg> &&
1400 is_nothrow_constructible_v<_Tp, _Arg>) {
Nikolas Klauser84fc2c32022-09-02 14:19:071401 __impl_.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg));
Eric Fiselier0d3d8de2016-12-02 23:00:051402 return *this;
1403 }
1404
1405 template <
1406 size_t _Ip,
1407 class... _Args,
1408 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1409 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1410 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571411 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier25514752017-04-15 19:32:021412 _Tp& emplace(_Args&&... __args) {
Nikolas Klauser84fc2c32022-09-02 14:19:071413 return __impl_.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier0d3d8de2016-12-02 23:00:051414 }
1415
1416 template <
1417 size_t _Ip,
1418 class _Up,
1419 class... _Args,
1420 enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1421 class _Tp = variant_alternative_t<_Ip, variant<_Types...>>,
1422 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1423 int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571424 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier25514752017-04-15 19:32:021425 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
Nikolas Klauser84fc2c32022-09-02 14:19:071426 return __impl_.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier0d3d8de2016-12-02 23:00:051427 }
1428
1429 template <
1430 class _Tp,
1431 class... _Args,
1432 size_t _Ip =
1433 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1434 enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571435 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier25514752017-04-15 19:32:021436 _Tp& emplace(_Args&&... __args) {
Nikolas Klauser84fc2c32022-09-02 14:19:071437 return __impl_.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...);
Eric Fiselier0d3d8de2016-12-02 23:00:051438 }
1439
1440 template <
1441 class _Tp,
1442 class _Up,
1443 class... _Args,
1444 size_t _Ip =
1445 __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1446 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>,
1447 int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571448 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier25514752017-04-15 19:32:021449 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
Nikolas Klauser84fc2c32022-09-02 14:19:071450 return __impl_.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...);
Eric Fiselier0d3d8de2016-12-02 23:00:051451 }
1452
Kent Rossc4566ca2022-08-14 23:14:571453 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051454 constexpr bool valueless_by_exception() const noexcept {
Nikolas Klauser84fc2c32022-09-02 14:19:071455 return __impl_.valueless_by_exception();
Eric Fiselier0d3d8de2016-12-02 23:00:051456 }
1457
Kent Rossc4566ca2022-08-14 23:14:571458 _LIBCPP_HIDE_FROM_ABI
Nikolas Klauser84fc2c32022-09-02 14:19:071459 constexpr size_t index() const noexcept { return __impl_.index(); }
Eric Fiselier0d3d8de2016-12-02 23:00:051460
1461 template <
1462 bool _Dummy = true,
1463 enable_if_t<
1464 __all<(
1465 __dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1466 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1467 int> = 0>
Kent Rossc4566ca2022-08-14 23:14:571468 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051469 void swap(variant& __that) noexcept(
1470 __all<(is_nothrow_move_constructible_v<_Types> &&
1471 is_nothrow_swappable_v<_Types>)...>::value) {
Nikolas Klauser84fc2c32022-09-02 14:19:071472 __impl_.__swap(__that.__impl_);
Eric Fiselier0d3d8de2016-12-02 23:00:051473 }
1474
1475private:
Nikolas Klauser84fc2c32022-09-02 14:19:071476 __variant_detail::__impl<_Types...> __impl_;
Eric Fiselier0d3d8de2016-12-02 23:00:051477
1478 friend struct __variant_detail::__access::__variant;
1479 friend struct __variant_detail::__visitation::__variant;
1480};
1481
1482template <size_t _Ip, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571483_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051484constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1485 return __v.index() == _Ip;
1486}
1487
1488template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571489_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051490constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1491 return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1492}
1493
1494template <size_t _Ip, class _Vp>
Kent Rossc4566ca2022-08-14 23:14:571495_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041496_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Richard Smith67c364d2018-08-27 21:41:501497constexpr auto&& __generic_get(_Vp&& __v) {
Eric Fiselier0d3d8de2016-12-02 23:00:051498 using __variant_detail::__access::__variant;
1499 if (!__holds_alternative<_Ip>(__v)) {
Eric Fiselier63322af2016-12-03 01:58:071500 __throw_bad_variant_access();
Eric Fiselier0d3d8de2016-12-02 23:00:051501 }
1502 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1503}
1504
1505template <size_t _Ip, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571506_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041507_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier0d3d8de2016-12-02 23:00:051508constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(
1509 variant<_Types...>& __v) {
1510 static_assert(_Ip < sizeof...(_Types));
1511 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1512 return __generic_get<_Ip>(__v);
1513}
1514
1515template <size_t _Ip, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571516_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041517_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier0d3d8de2016-12-02 23:00:051518constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(
1519 variant<_Types...>&& __v) {
1520 static_assert(_Ip < sizeof...(_Types));
1521 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1522 return __generic_get<_Ip>(_VSTD::move(__v));
1523}
1524
1525template <size_t _Ip, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571526_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041527_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier0d3d8de2016-12-02 23:00:051528constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get(
1529 const variant<_Types...>& __v) {
1530 static_assert(_Ip < sizeof...(_Types));
1531 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1532 return __generic_get<_Ip>(__v);
1533}
1534
1535template <size_t _Ip, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571536_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041537_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier0d3d8de2016-12-02 23:00:051538constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get(
1539 const variant<_Types...>&& __v) {
1540 static_assert(_Ip < sizeof...(_Types));
1541 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1542 return __generic_get<_Ip>(_VSTD::move(__v));
1543}
1544
1545template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571546_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041547_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier0d3d8de2016-12-02 23:00:051548constexpr _Tp& get(variant<_Types...>& __v) {
1549 static_assert(!is_void_v<_Tp>);
1550 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1551}
1552
1553template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571554_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041555_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier0d3d8de2016-12-02 23:00:051556constexpr _Tp&& get(variant<_Types...>&& __v) {
1557 static_assert(!is_void_v<_Tp>);
1558 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1559 _VSTD::move(__v));
1560}
1561
1562template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571563_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041564_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier0d3d8de2016-12-02 23:00:051565constexpr const _Tp& get(const variant<_Types...>& __v) {
1566 static_assert(!is_void_v<_Tp>);
1567 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1568}
1569
1570template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571571_LIBCPP_HIDE_FROM_ABI
Louis Dionne8a063df2018-11-19 15:37:041572_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
Eric Fiselier0d3d8de2016-12-02 23:00:051573constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1574 static_assert(!is_void_v<_Tp>);
1575 return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(
1576 _VSTD::move(__v));
1577}
1578
1579template <size_t _Ip, class _Vp>
Kent Rossc4566ca2022-08-14 23:14:571580_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051581constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1582 using __variant_detail::__access::__variant;
1583 return __v && __holds_alternative<_Ip>(*__v)
1584 ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value)
1585 : nullptr;
1586}
1587
1588template <size_t _Ip, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571589_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051590constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1591get_if(variant<_Types...>* __v) noexcept {
1592 static_assert(_Ip < sizeof...(_Types));
1593 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1594 return __generic_get_if<_Ip>(__v);
1595}
1596
1597template <size_t _Ip, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571598_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051599constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1600get_if(const variant<_Types...>* __v) noexcept {
1601 static_assert(_Ip < sizeof...(_Types));
1602 static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1603 return __generic_get_if<_Ip>(__v);
1604}
1605
1606template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571607_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051608constexpr add_pointer_t<_Tp>
1609get_if(variant<_Types...>* __v) noexcept {
1610 static_assert(!is_void_v<_Tp>);
1611 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1612}
1613
1614template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571615_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051616constexpr add_pointer_t<const _Tp>
1617get_if(const variant<_Types...>* __v) noexcept {
1618 static_assert(!is_void_v<_Tp>);
1619 return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1620}
1621
Eric Fiselier7dca3122018-09-19 17:53:211622template <class _Operator>
1623struct __convert_to_bool {
1624 template <class _T1, class _T2>
Kent Rossc4566ca2022-08-14 23:14:571625 _LIBCPP_HIDE_FROM_ABI
1626 constexpr bool operator()(_T1 && __t1, _T2&& __t2) const {
Arthur O'Dwyerd586f922020-11-27 16:02:061627 static_assert(is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value,
Eric Fiselier7dca3122018-09-19 17:53:211628 "the relational operator does not return a type which is implicitly convertible to bool");
1629 return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2));
1630 }
1631};
1632
Eric Fiselier0d3d8de2016-12-02 23:00:051633template <class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571634_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051635constexpr bool operator==(const variant<_Types...>& __lhs,
1636 const variant<_Types...>& __rhs) {
1637 using __variant_detail::__visitation::__variant;
1638 if (__lhs.index() != __rhs.index()) return false;
1639 if (__lhs.valueless_by_exception()) return true;
Eric Fiselier7dca3122018-09-19 17:53:211640 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
Eric Fiselier0d3d8de2016-12-02 23:00:051641}
1642
Kent Rossc4566ca2022-08-14 23:14:571643# if _LIBCPP_STD_VER > 17
1644
Eric Fiselier0d3d8de2016-12-02 23:00:051645template <class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571646_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...>
1647operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1648 using __variant_detail::__visitation::__variant;
1649 using __result_t = common_comparison_category_t<compare_three_way_result_t<_Types>...>;
1650 if (__lhs.valueless_by_exception() && __rhs.valueless_by_exception())
1651 return strong_ordering::equal;
1652 if (__lhs.valueless_by_exception())
1653 return strong_ordering::less;
1654 if (__rhs.valueless_by_exception())
1655 return strong_ordering::greater;
1656 if (auto __c = __lhs.index() <=> __rhs.index(); __c != 0)
1657 return __c;
1658 auto __three_way = []<class _Type>(const _Type& __v, const _Type& __w) -> __result_t { return __v <=> __w; };
1659 return __variant::__visit_value_at(__lhs.index(), __three_way, __lhs, __rhs);
1660}
1661
1662# endif // _LIBCPP_STD_VER > 17
1663
1664template <class... _Types>
1665_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051666constexpr bool operator!=(const variant<_Types...>& __lhs,
1667 const variant<_Types...>& __rhs) {
1668 using __variant_detail::__visitation::__variant;
1669 if (__lhs.index() != __rhs.index()) return true;
1670 if (__lhs.valueless_by_exception()) return false;
1671 return __variant::__visit_value_at(
Eric Fiselier7dca3122018-09-19 17:53:211672 __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
Eric Fiselier0d3d8de2016-12-02 23:00:051673}
1674
1675template <class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571676_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051677constexpr bool operator<(const variant<_Types...>& __lhs,
1678 const variant<_Types...>& __rhs) {
1679 using __variant_detail::__visitation::__variant;
1680 if (__rhs.valueless_by_exception()) return false;
1681 if (__lhs.valueless_by_exception()) return true;
1682 if (__lhs.index() < __rhs.index()) return true;
1683 if (__lhs.index() > __rhs.index()) return false;
Eric Fiselier7dca3122018-09-19 17:53:211684 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
Eric Fiselier0d3d8de2016-12-02 23:00:051685}
1686
1687template <class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571688_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051689constexpr bool operator>(const variant<_Types...>& __lhs,
1690 const variant<_Types...>& __rhs) {
1691 using __variant_detail::__visitation::__variant;
1692 if (__lhs.valueless_by_exception()) return false;
1693 if (__rhs.valueless_by_exception()) return true;
1694 if (__lhs.index() > __rhs.index()) return true;
1695 if (__lhs.index() < __rhs.index()) return false;
Eric Fiselier7dca3122018-09-19 17:53:211696 return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
Eric Fiselier0d3d8de2016-12-02 23:00:051697}
1698
1699template <class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571700_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051701constexpr bool operator<=(const variant<_Types...>& __lhs,
1702 const variant<_Types...>& __rhs) {
1703 using __variant_detail::__visitation::__variant;
1704 if (__lhs.valueless_by_exception()) return true;
1705 if (__rhs.valueless_by_exception()) return false;
1706 if (__lhs.index() < __rhs.index()) return true;
1707 if (__lhs.index() > __rhs.index()) return false;
1708 return __variant::__visit_value_at(
Eric Fiselier7dca3122018-09-19 17:53:211709 __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
Eric Fiselier0d3d8de2016-12-02 23:00:051710}
1711
1712template <class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571713_LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051714constexpr bool operator>=(const variant<_Types...>& __lhs,
1715 const variant<_Types...>& __rhs) {
1716 using __variant_detail::__visitation::__variant;
1717 if (__rhs.valueless_by_exception()) return true;
1718 if (__lhs.valueless_by_exception()) return false;
1719 if (__lhs.index() > __rhs.index()) return true;
1720 if (__lhs.index() < __rhs.index()) return false;
1721 return __variant::__visit_value_at(
Eric Fiselier7dca3122018-09-19 17:53:211722 __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
Eric Fiselier0d3d8de2016-12-02 23:00:051723}
1724
Ruslan Arutyunyan9d509582021-01-25 18:34:031725template <class... _Vs>
Kent Rossc4566ca2022-08-14 23:14:571726_LIBCPP_HIDE_FROM_ABI
1727_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
1728constexpr void __throw_if_valueless(_Vs&&... __vs) {
Marek Kurdej0324b462021-03-25 17:09:111729 const bool __valueless =
1730 (... || _VSTD::__as_variant(__vs).valueless_by_exception());
Ruslan Arutyunyan51faba32021-01-25 16:12:251731 if (__valueless) {
Marek Kurdej0324b462021-03-25 17:09:111732 __throw_bad_variant_access();
Ruslan Arutyunyan51faba32021-01-25 16:12:251733 }
1734}
1735
Marek Kurdej0324b462021-03-25 17:09:111736template <
1737 class _Visitor, class... _Vs,
Arthur O'Dwyerab3fcc52021-05-10 17:04:161738 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
Kent Rossc4566ca2022-08-14 23:14:571739_LIBCPP_HIDE_FROM_ABI
1740_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
1741constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
Eric Fiselier0d3d8de2016-12-02 23:00:051742 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan9d509582021-01-25 18:34:031743 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Eric Fiselier9c097572020-11-17 22:34:231744 return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor),
Eric Fiselier0d3d8de2016-12-02 23:00:051745 _VSTD::forward<_Vs>(__vs)...);
1746}
1747
Ruslan Arutyunyan51faba32021-01-25 16:12:251748#if _LIBCPP_STD_VER > 17
Marek Kurdej0324b462021-03-25 17:09:111749template <
1750 class _Rp, class _Visitor, class... _Vs,
Arthur O'Dwyerab3fcc52021-05-10 17:04:161751 typename = void_t<decltype(_VSTD::__as_variant(declval<_Vs>()))...> >
Kent Rossc4566ca2022-08-14 23:14:571752_LIBCPP_HIDE_FROM_ABI
1753_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
1754constexpr _Rp visit(_Visitor&& __visitor, _Vs&&... __vs) {
Ruslan Arutyunyan51faba32021-01-25 16:12:251755 using __variant_detail::__visitation::__variant;
Ruslan Arutyunyan9d509582021-01-25 18:34:031756 _VSTD::__throw_if_valueless(_VSTD::forward<_Vs>(__vs)...);
Ruslan Arutyunyan51faba32021-01-25 16:12:251757 return __variant::__visit_value<_Rp>(_VSTD::forward<_Visitor>(__visitor),
1758 _VSTD::forward<_Vs>(__vs)...);
1759}
1760#endif
1761
Eric Fiselier0d3d8de2016-12-02 23:00:051762template <class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571763_LIBCPP_HIDE_FROM_ABI
Louis Dionneb28cb532021-08-16 16:41:581764auto swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1765 noexcept(noexcept(__lhs.swap(__rhs)))
1766 -> decltype( __lhs.swap(__rhs))
1767 { return __lhs.swap(__rhs); }
Eric Fiselier0d3d8de2016-12-02 23:00:051768
1769template <class... _Types>
Eric Fiselierf9127592017-01-21 00:02:121770struct _LIBCPP_TEMPLATE_VIS hash<
1771 __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
Eric Fiselier0d3d8de2016-12-02 23:00:051772 using argument_type = variant<_Types...>;
1773 using result_type = size_t;
1774
Kent Rossc4566ca2022-08-14 23:14:571775 _LIBCPP_HIDE_FROM_ABI
Eric Fiselier0d3d8de2016-12-02 23:00:051776 result_type operator()(const argument_type& __v) const {
1777 using __variant_detail::__visitation::__variant;
Eric Fiselier918f32f2016-12-02 23:38:311778 size_t __res =
1779 __v.valueless_by_exception()
Eric Fiselier02460ba2016-12-04 21:37:371780 ? 299792458 // Random value chosen by the universe upon creation
Eric Fiselier0d3d8de2016-12-02 23:00:051781 : __variant::__visit_alt(
1782 [](const auto& __alt) {
Marshall Clow8ea7ede2018-02-12 15:41:251783 using __alt_type = __uncvref_t<decltype(__alt)>;
Eric Fiselierf9127592017-01-21 00:02:121784 using __value_type = remove_const_t<
1785 typename __alt_type::__value_type>;
Eric Fiselier0d3d8de2016-12-02 23:00:051786 return hash<__value_type>{}(__alt.__value);
1787 },
1788 __v);
Eric Fiselier918f32f2016-12-02 23:38:311789 return __hash_combine(__res, hash<size_t>{}(__v.index()));
Eric Fiselier0d3d8de2016-12-02 23:00:051790 }
1791};
1792
zoecarver1a294032021-05-27 16:23:191793// __unchecked_get is the same as std::get, except, it is UB to use it with the wrong
1794// type whereas std::get will throw or returning nullptr. This makes it faster than
1795// std::get.
1796template <size_t _Ip, class _Vp>
Kent Rossc4566ca2022-08-14 23:14:571797_LIBCPP_HIDE_FROM_ABI
zoecarver1a294032021-05-27 16:23:191798constexpr auto&& __unchecked_get(_Vp&& __v) noexcept {
1799 using __variant_detail::__access::__variant;
1800 return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value;
1801}
1802
1803template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571804_LIBCPP_HIDE_FROM_ABI
zoecarver1a294032021-05-27 16:23:191805constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept {
1806 return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1807}
1808
1809template <class _Tp, class... _Types>
Kent Rossc4566ca2022-08-14 23:14:571810_LIBCPP_HIDE_FROM_ABI
zoecarver1a294032021-05-27 16:23:191811constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
1812 return __unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1813}
1814
Louis Dionne4cd6ca12021-04-20 16:03:321815#endif // _LIBCPP_STD_VER > 14
Eric Fiselier0d3d8de2016-12-02 23:00:051816
1817_LIBCPP_END_NAMESPACE_STD
1818
Eric Fiselierafa6f832017-11-19 04:57:221819_LIBCPP_POP_MACROS
1820
Louis Dionne4cd6ca12021-04-20 16:03:321821#endif // _LIBCPP_VARIANT