xref: /freebsd/contrib/llvm-project/libcxx/include/variant (revision 700637cbb5e582861067a11aaca4d053546871d2)
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// 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
7//
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);
25    constexpr variant(const variant&);
26    constexpr variant(variant&&) noexcept(see below);
27
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    constexpr ~variant();                                             // constexpr since c++20
46
47    // 20.7.2.3, assignment
48    constexpr variant& operator=(const variant&);
49    constexpr variant& operator=(variant&&) noexcept(see below);
50
51    template <class T>
52    constexpr variant& operator=(T&&) noexcept(see below);            // constexpr since c++20
53
54    // 20.7.2.4, modifiers
55    template <class T, class... Args>
56    constexpr T& emplace(Args&&...);                                  // constexpr since c++20
57
58    template <class T, class U, class... Args>
59    constexpr T& emplace(initializer_list<U>, Args&&...);             // constexpr since c++20
60
61    template <size_t I, class... Args>
62    constexpr variant_alternative_t<I, variant>& emplace(Args&&...);  // constexpr since c++20
63
64    template <size_t I, class U, class...  Args>
65    constexpr variant_alternative_t<I, variant>&
66        emplace(initializer_list<U>, Args&&...);                      // constexpr since c++20
67
68    // 20.7.2.5, value status
69    constexpr bool valueless_by_exception() const noexcept;
70    constexpr size_t index() const noexcept;
71
72    // 20.7.2.6, swap
73    void swap(variant&) noexcept(see below);
74
75    // [variant.visit], visitation
76    template<class Self, class Visitor>
77      constexpr decltype(auto) visit(this Self&&, Visitor&&); // Since C++26
78    template<class R, class Self, class Visitor>
79      constexpr R visit(this Self&&, Visitor&&);              // Since C++26
80  };
81
82  // 20.7.3, variant helper classes
83  template <class T> struct variant_size; // undefined
84
85  template <class T>
86  inline constexpr size_t variant_size_v = variant_size<T>::value;
87
88  template <class T> struct variant_size<const T>;
89  template <class T> struct variant_size<volatile T>;
90  template <class T> struct variant_size<const volatile T>;
91
92  template <class... Types>
93  struct variant_size<variant<Types...>>;
94
95  template <size_t I, class T> struct variant_alternative; // undefined
96
97  template <size_t I, class T>
98  using variant_alternative_t = typename variant_alternative<I, T>::type;
99
100  template <size_t I, class T> struct variant_alternative<I, const T>;
101  template <size_t I, class T> struct variant_alternative<I, volatile T>;
102  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
103
104  template <size_t I, class... Types>
105  struct variant_alternative<I, variant<Types...>>;
106
107  inline constexpr size_t variant_npos = -1;
108
109  // 20.7.4, value access
110  template <class T, class... Types>
111  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
112
113  template <size_t I, class... Types>
114  constexpr variant_alternative_t<I, variant<Types...>>&
115  get(variant<Types...>&);
116
117  template <size_t I, class... Types>
118  constexpr variant_alternative_t<I, variant<Types...>>&&
119  get(variant<Types...>&&);
120
121  template <size_t I, class... Types>
122  constexpr variant_alternative_t<I, variant<Types...>> const&
123  get(const variant<Types...>&);
124
125  template <size_t I, class... Types>
126  constexpr variant_alternative_t<I, variant<Types...>> const&&
127  get(const variant<Types...>&&);
128
129  template <class T, class...  Types>
130  constexpr T& get(variant<Types...>&);
131
132  template <class T, class... Types>
133  constexpr T&& get(variant<Types...>&&);
134
135  template <class T, class... Types>
136  constexpr const T& get(const variant<Types...>&);
137
138  template <class T, class... Types>
139  constexpr const T&& get(const variant<Types...>&&);
140
141  template <size_t I, class... Types>
142  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
143  get_if(variant<Types...>*) noexcept;
144
145  template <size_t I, class... Types>
146  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
147  get_if(const variant<Types...>*) noexcept;
148
149  template <class T, class... Types>
150  constexpr add_pointer_t<T>
151  get_if(variant<Types...>*) noexcept;
152
153  template <class T, class... Types>
154  constexpr add_pointer_t<const T>
155  get_if(const variant<Types...>*) noexcept;
156
157  // 20.7.5, relational operators
158  template <class... Types>
159  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
160
161  template <class... Types>
162  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
163
164  template <class... Types>
165  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
166
167  template <class... Types>
168  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
169
170  template <class... Types>
171  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
172
173  template <class... Types>
174  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
175
176  template <class... Types> requires (three_way_comparable<Types> && ...)
177  constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
178    operator<=>(const variant<Types...>&, const variant<Types...>&);           // since C++20
179
180  // 20.7.6, visitation
181  template <class Visitor, class... Variants>
182  constexpr see below visit(Visitor&&, Variants&&...);
183
184  template <class R, class Visitor, class... Variants>
185  constexpr R visit(Visitor&&, Variants&&...); // since C++20
186
187  // 20.7.7, class monostate
188  struct monostate;
189
190  // 20.7.8, monostate relational operators
191  constexpr bool operator==(monostate, monostate) noexcept;
192  constexpr bool operator!=(monostate, monostate) noexcept;             // until C++20
193  constexpr bool operator<(monostate, monostate) noexcept;              // until C++20
194  constexpr bool operator>(monostate, monostate) noexcept;              // until C++20
195  constexpr bool operator<=(monostate, monostate) noexcept;             // until C++20
196  constexpr bool operator>=(monostate, monostate) noexcept;             // until C++20
197  constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // since C++20
198
199  // 20.7.9, specialized algorithms
200  template <class... Types>
201  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
202
203  // 20.7.10, class bad_variant_access
204  class bad_variant_access;
205
206  // 20.7.11, hash support
207  template <class T> struct hash;
208  template <class... Types> struct hash<variant<Types...>>;
209  template <> struct hash<monostate>;
210
211} // namespace std
212
213*/
214
215#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
216#  include <__cxx03/__config>
217#else
218#  include <__compare/common_comparison_category.h>
219#  include <__compare/compare_three_way_result.h>
220#  include <__compare/ordering.h>
221#  include <__compare/three_way_comparable.h>
222#  include <__config>
223#  include <__exception/exception.h>
224#  include <__functional/hash.h>
225#  include <__functional/operations.h>
226#  include <__functional/unary_function.h>
227#  include <__fwd/variant.h>
228#  include <__memory/addressof.h>
229#  include <__memory/construct_at.h>
230#  include <__tuple/find_index.h>
231#  include <__tuple/sfinae_helpers.h>
232#  include <__type_traits/add_cv_quals.h>
233#  include <__type_traits/add_pointer.h>
234#  include <__type_traits/common_type.h>
235#  include <__type_traits/conditional.h>
236#  include <__type_traits/conjunction.h>
237#  include <__type_traits/decay.h>
238#  include <__type_traits/dependent_type.h>
239#  include <__type_traits/enable_if.h>
240#  include <__type_traits/invoke.h>
241#  include <__type_traits/is_array.h>
242#  include <__type_traits/is_assignable.h>
243#  include <__type_traits/is_constructible.h>
244#  include <__type_traits/is_convertible.h>
245#  include <__type_traits/is_core_convertible.h>
246#  include <__type_traits/is_destructible.h>
247#  include <__type_traits/is_nothrow_assignable.h>
248#  include <__type_traits/is_nothrow_constructible.h>
249#  include <__type_traits/is_reference.h>
250#  include <__type_traits/is_replaceable.h>
251#  include <__type_traits/is_same.h>
252#  include <__type_traits/is_swappable.h>
253#  include <__type_traits/is_trivially_assignable.h>
254#  include <__type_traits/is_trivially_constructible.h>
255#  include <__type_traits/is_trivially_destructible.h>
256#  include <__type_traits/is_trivially_relocatable.h>
257#  include <__type_traits/is_void.h>
258#  include <__type_traits/remove_const.h>
259#  include <__type_traits/remove_cvref.h>
260#  include <__type_traits/remove_reference.h>
261#  include <__type_traits/type_identity.h>
262#  include <__type_traits/void_t.h>
263#  include <__utility/declval.h>
264#  include <__utility/forward.h>
265#  include <__utility/forward_like.h>
266#  include <__utility/in_place.h>
267#  include <__utility/integer_sequence.h>
268#  include <__utility/move.h>
269#  include <__utility/swap.h>
270#  include <__variant/monostate.h>
271#  include <__verbose_abort>
272#  include <initializer_list>
273#  include <limits>
274#  include <version>
275
276// standard-mandated includes
277
278// [variant.syn]
279#  include <compare>
280
281#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
282#    pragma GCC system_header
283#  endif
284
285_LIBCPP_PUSH_MACROS
286#  include <__undef_macros>
287
288_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD
289
290class _LIBCPP_EXPORTED_FROM_ABI bad_variant_access : public exception {
291public:
292  const char* what() const _NOEXCEPT override;
293};
294
295_LIBCPP_END_UNVERSIONED_NAMESPACE_STD
296
297_LIBCPP_BEGIN_NAMESPACE_STD
298
299#  if _LIBCPP_STD_VER >= 17
300
301// Light N-dimensional array of function pointers. Used in place of std::array to avoid
302// adding a dependency.
303template <class _Tp, size_t _Size>
304struct __farray {
305  static_assert(_Size > 0, "N-dimensional array should never be empty in std::visit");
306  _Tp __buf_[_Size] = {};
307
308  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t __n) const noexcept { return __buf_[__n]; }
309};
310
311[[noreturn]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_variant_access() {
312#    if _LIBCPP_HAS_EXCEPTIONS
313  throw bad_variant_access();
314#    else
315  _LIBCPP_VERBOSE_ABORT("bad_variant_access was thrown in -fno-exceptions mode");
316#    endif
317}
318
319// variant_size
320template <class _Tp>
321struct variant_size<const _Tp> : variant_size<_Tp> {};
322
323template <class _Tp>
324struct variant_size<volatile _Tp> : variant_size<_Tp> {};
325
326template <class _Tp>
327struct variant_size<const volatile _Tp> : variant_size<_Tp> {};
328
329template <class... _Types>
330struct variant_size<variant<_Types...>> : integral_constant<size_t, sizeof...(_Types)> {};
331
332// variant_alternative
333template <size_t _Ip, class _Tp>
334struct variant_alternative<_Ip, const _Tp> : add_const<variant_alternative_t<_Ip, _Tp>> {};
335
336template <size_t _Ip, class _Tp>
337struct variant_alternative<_Ip, volatile _Tp> : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
338
339template <size_t _Ip, class _Tp>
340struct variant_alternative<_Ip, const volatile _Tp> : add_cv<variant_alternative_t<_Ip, _Tp>> {};
341
342template <size_t _Ip, class... _Types>
343struct variant_alternative<_Ip, variant<_Types...>> {
344  static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
345  using type _LIBCPP_NODEBUG = __type_pack_element<_Ip, _Types...>;
346};
347
348template <size_t _NumAlternatives>
349_LIBCPP_HIDE_FROM_ABI constexpr auto __choose_index_type() {
350#    ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
351  if constexpr (_NumAlternatives < numeric_limits<unsigned char>::max())
352    return static_cast<unsigned char>(0);
353  else if constexpr (_NumAlternatives < numeric_limits<unsigned short>::max())
354    return static_cast<unsigned short>(0);
355  else
356#    endif // _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
357    return static_cast<unsigned int>(0);
358}
359
360template <size_t _NumAlts>
361using __variant_index_t _LIBCPP_NODEBUG = decltype(std::__choose_index_type<_NumAlts>());
362
363template <class _IndexType>
364constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
365
366template <class... _Types>
367_LIBCPP_HIDE_FROM_ABI constexpr variant<_Types...>& __as_variant(variant<_Types...>& __vs) noexcept {
368  return __vs;
369}
370
371template <class... _Types>
372_LIBCPP_HIDE_FROM_ABI constexpr const variant<_Types...>& __as_variant(const variant<_Types...>& __vs) noexcept {
373  return __vs;
374}
375
376template <class... _Types>
377_LIBCPP_HIDE_FROM_ABI constexpr variant<_Types...>&& __as_variant(variant<_Types...>&& __vs) noexcept {
378  return std::move(__vs);
379}
380
381template <class... _Types>
382_LIBCPP_HIDE_FROM_ABI constexpr const variant<_Types...>&& __as_variant(const variant<_Types...>&& __vs) noexcept {
383  return std::move(__vs);
384}
385
386namespace __find_detail {
387
388template <class _Tp, class... _Types>
389_LIBCPP_HIDE_FROM_ABI constexpr size_t __find_index() {
390  constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
391  size_t __result            = __not_found;
392  for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
393    if (__matches[__i]) {
394      if (__result != __not_found) {
395        return __ambiguous;
396      }
397      __result = __i;
398    }
399  }
400  return __result;
401}
402
403template <size_t _Index>
404struct __find_unambiguous_index_sfinae_impl : integral_constant<size_t, _Index> {};
405
406template <>
407struct __find_unambiguous_index_sfinae_impl<__not_found> {};
408
409template <>
410struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
411
412template <class _Tp, class... _Types>
413struct __find_unambiguous_index_sfinae
414    : __find_unambiguous_index_sfinae_impl<__find_detail::__find_index<_Tp, _Types...>()> {};
415
416} // namespace __find_detail
417
418namespace __variant_detail {
419
420struct __valueless_t {};
421
422enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
423
424template <typename _Tp, template <typename> class _IsTriviallyAvailable, template <typename> class _IsAvailable>
425constexpr _Trait __trait =
426    _IsTriviallyAvailable<_Tp>::value ? _Trait::_TriviallyAvailable
427    : _IsAvailable<_Tp>::value
428        ? _Trait::_Available
429        : _Trait::_Unavailable;
430
431_LIBCPP_HIDE_FROM_ABI constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
432  _Trait __result = _Trait::_TriviallyAvailable;
433  for (_Trait __t : __traits) {
434    if (static_cast<int>(__t) > static_cast<int>(__result)) {
435      __result = __t;
436    }
437  }
438  return __result;
439}
440
441template <typename... _Types>
442struct __traits {
443  static constexpr _Trait __copy_constructible_trait =
444      __variant_detail::__common_trait({__trait<_Types, is_trivially_copy_constructible, is_copy_constructible>...});
445
446  static constexpr _Trait __move_constructible_trait =
447      __variant_detail::__common_trait({__trait<_Types, is_trivially_move_constructible, is_move_constructible>...});
448
449  static constexpr _Trait __copy_assignable_trait = __variant_detail::__common_trait(
450      {__copy_constructible_trait, __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
451
452  static constexpr _Trait __move_assignable_trait = __variant_detail::__common_trait(
453      {__move_constructible_trait, __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
454
455  static constexpr _Trait __destructible_trait =
456      __variant_detail::__common_trait({__trait<_Types, is_trivially_destructible, is_destructible>...});
457};
458
459namespace __access {
460
461struct __union {
462  template <class _Vp>
463  _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
464    return std::forward<_Vp>(__v).__head;
465  }
466
467  template <class _Vp, size_t _Ip>
468  _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
469    return __get_alt(std::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
470  }
471};
472
473struct __base {
474  template <size_t _Ip, class _Vp>
475  _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v) {
476    return __union::__get_alt(std::forward<_Vp>(__v).__data, in_place_index<_Ip>);
477  }
478};
479
480struct __variant {
481  template <size_t _Ip, class _Vp>
482  _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v) {
483    return __base::__get_alt<_Ip>(std::forward<_Vp>(__v).__impl_);
484  }
485};
486
487} // namespace __access
488
489namespace __visitation {
490
491struct __base {
492  template <class _Visitor, class... _Vs>
493  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
494  __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
495    constexpr auto __fdiagonal = __make_fdiagonal<_Visitor&&, decltype(std::forward<_Vs>(__vs).__as_base())...>();
496    return __fdiagonal[__index](std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__as_base()...);
497  }
498
499  template <class _Visitor, class... _Vs>
500  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, _Vs&&... __vs) {
501    constexpr auto __fmatrix = __make_fmatrix<_Visitor&&, decltype(std::forward<_Vs>(__vs).__as_base())...>();
502    return __at(__fmatrix, __vs.index()...)(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__as_base()...);
503  }
504
505private:
506  template <class _Tp>
507  _LIBCPP_HIDE_FROM_ABI static constexpr const _Tp& __at(const _Tp& __elem) {
508    return __elem;
509  }
510
511  template <class _Tp, size_t _Np, typename... _Indices>
512  _LIBCPP_HIDE_FROM_ABI static constexpr auto&&
513  __at(const __farray<_Tp, _Np>& __elems, size_t __index, _Indices... __indices) {
514    return __at(__elems[__index], __indices...);
515  }
516
517  template <class _Fp, class... _Fs>
518  static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_visitor_return_type_check() {
519    static_assert(
520        __all<is_same_v<_Fp, _Fs>...>::value, "`std::visit` requires the visitor to have a single return type.");
521  }
522
523  template <class... _Fs>
524  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_farray(_Fs&&... __fs) {
525    __std_visit_visitor_return_type_check<__remove_cvref_t<_Fs>...>();
526    using __result = __farray<common_type_t<__remove_cvref_t<_Fs>...>, sizeof...(_Fs)>;
527    return __result{{std::forward<_Fs>(__fs)...}};
528  }
529
530  template <size_t... _Is>
531  struct __dispatcher {
532    template <class _Fp, class... _Vs>
533    _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
534      return std::__invoke(static_cast<_Fp>(__f), __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
535    }
536  };
537
538  template <class _Fp, class... _Vs, size_t... _Is>
539  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_dispatch(index_sequence<_Is...>) {
540    return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
541  }
542
543  template <size_t _Ip, class _Fp, class... _Vs>
544  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal_impl() {
545    return __make_dispatch<_Fp, _Vs...>(index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{});
546  }
547
548  template <class _Fp, class... _Vs, size_t... _Is>
549  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
550    return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
551  }
552
553  template <class _Fp, class _Vp, class... _Vs>
554  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal() {
555    constexpr size_t __np = __remove_cvref_t<_Vp>::__size();
556    static_assert(__all<(__np == __remove_cvref_t<_Vs>::__size())...>::value);
557    return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<__np>{});
558  }
559
560  template <class _Fp, class... _Vs, size_t... _Is>
561  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
562    return __make_dispatch<_Fp, _Vs...>(__is);
563  }
564
565  template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
566  _LIBCPP_HIDE_FROM_ABI static constexpr auto
567  __make_fmatrix_impl(index_sequence<_Is...>, index_sequence<_Js...>, _Ls... __ls) {
568    return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(index_sequence<_Is..., _Js>{}, __ls...)...);
569  }
570
571  template <class _Fp, class... _Vs>
572  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fmatrix() {
573    return __make_fmatrix_impl<_Fp, _Vs...>(
574        index_sequence<>{}, make_index_sequence<__remove_cvref_t<_Vs>::__size()>{}...);
575  }
576};
577
578struct __variant {
579  template <class _Visitor, class... _Vs>
580  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
581  __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
582    return __base::__visit_alt_at(__index, std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__impl_...);
583  }
584
585  template <class _Visitor, class... _Vs>
586  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, _Vs&&... __vs) {
587    return __base::__visit_alt(
588        std::forward<_Visitor>(__visitor), std::__as_variant(std::forward<_Vs>(__vs)).__impl_...);
589  }
590
591  template <class _Visitor, class... _Vs>
592  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
593  __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
594    return __visit_alt_at(__index, __make_value_visitor(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...);
595  }
596
597  template <class _Visitor, class... _Vs>
598  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_value(_Visitor&& __visitor, _Vs&&... __vs) {
599    return __visit_alt(__make_value_visitor(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...);
600  }
601
602#    if _LIBCPP_STD_VER >= 20
603  template <class _Rp, class _Visitor, class... _Vs>
604  _LIBCPP_HIDE_FROM_ABI static constexpr _Rp __visit_value(_Visitor&& __visitor, _Vs&&... __vs) {
605    return __visit_alt(__make_value_visitor<_Rp>(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...);
606  }
607#    endif
608
609private:
610  template <class _Visitor, class... _Values>
611  static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_exhaustive_visitor_check() {
612    static_assert(is_invocable_v<_Visitor, _Values...>, "`std::visit` requires the visitor to be exhaustive.");
613  }
614
615  template <class _Visitor>
616  struct __value_visitor {
617    template <class... _Alts>
618    _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Alts&&... __alts) const {
619      __std_visit_exhaustive_visitor_check< _Visitor, decltype((std::forward<_Alts>(__alts).__value))...>();
620      return std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...);
621    }
622    _Visitor&& __visitor;
623  };
624
625#    if _LIBCPP_STD_VER >= 20
626  template <class _Rp, class _Visitor>
627  struct __value_visitor_return_type {
628    template <class... _Alts>
629    _LIBCPP_HIDE_FROM_ABI constexpr _Rp operator()(_Alts&&... __alts) const {
630      __std_visit_exhaustive_visitor_check< _Visitor, decltype((std::forward<_Alts>(__alts).__value))...>();
631      if constexpr (is_void_v<_Rp>) {
632        std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...);
633      } else {
634        return std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...);
635      }
636    }
637
638    _Visitor&& __visitor;
639  };
640#    endif
641
642  template <class _Visitor>
643  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
644    return __value_visitor<_Visitor>{std::forward<_Visitor>(__visitor)};
645  }
646
647#    if _LIBCPP_STD_VER >= 20
648  template <class _Rp, class _Visitor>
649  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
650    return __value_visitor_return_type<_Rp, _Visitor>{std::forward<_Visitor>(__visitor)};
651  }
652#    endif
653};
654
655} // namespace __visitation
656
657// Adding semi-colons in macro expansions helps clang-format to do a better job.
658// This macro is used to avoid compilation errors due to "stray" semi-colons.
659#    define _LIBCPP_EAT_SEMICOLON static_assert(true, "")
660
661template <size_t _Index, class _Tp>
662struct __alt {
663  using __value_type _LIBCPP_NODEBUG = _Tp;
664  static constexpr size_t __index    = _Index;
665
666  template <class... _Args>
667  _LIBCPP_HIDE_FROM_ABI explicit constexpr __alt(in_place_t, _Args&&... __args)
668      : __value(std::forward<_Args>(__args)...) {}
669
670  __value_type __value;
671};
672
673template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
674union __union;
675
676template <_Trait _DestructibleTrait, size_t _Index>
677union __union<_DestructibleTrait, _Index> {};
678
679#    define _LIBCPP_VARIANT_UNION(destructible_trait, destructor_definition)                                           \
680      template <size_t _Index, class _Tp, class... _Types>                                                             \
681      union __union<destructible_trait, _Index, _Tp, _Types...> {                                                      \
682      public:                                                                                                          \
683        _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(__valueless_t) noexcept : __dummy{} {}                        \
684                                                                                                                       \
685        template <class... _Args>                                                                                      \
686        _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(in_place_index_t<0>, _Args&&... __args)                       \
687            : __head(in_place, std::forward<_Args>(__args)...) {}                                                      \
688                                                                                                                       \
689        template <size_t _Ip, class... _Args>                                                                          \
690        _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args)                     \
691            : __tail(in_place_index<_Ip - 1>, std::forward<_Args>(__args)...) {}                                       \
692                                                                                                                       \
693        _LIBCPP_HIDE_FROM_ABI __union(const __union&)            = default;                                            \
694        _LIBCPP_HIDE_FROM_ABI __union(__union&&)                 = default;                                            \
695        _LIBCPP_HIDE_FROM_ABI __union& operator=(const __union&) = default;                                            \
696        _LIBCPP_HIDE_FROM_ABI __union& operator=(__union&&)      = default;                                            \
697        destructor_definition;                                                                                         \
698                                                                                                                       \
699      private:                                                                                                         \
700        char __dummy;                                                                                                  \
701        __alt<_Index, _Tp> __head;                                                                                     \
702        __union<destructible_trait, _Index + 1, _Types...> __tail;                                                     \
703                                                                                                                       \
704        friend struct __access::__union;                                                                               \
705      }
706
707_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable,
708                      _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = default);
709_LIBCPP_VARIANT_UNION(
710    _Trait::_Available, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() {} _LIBCPP_EAT_SEMICOLON);
711_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = delete);
712
713#    undef _LIBCPP_VARIANT_UNION
714
715template <_Trait _DestructibleTrait, class... _Types>
716class __base {
717public:
718  using __index_t _LIBCPP_NODEBUG = __variant_index_t<sizeof...(_Types)>;
719
720  _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(__valueless_t __tag) noexcept
721      : __data(__tag), __index(__variant_npos<__index_t>) {}
722
723  template <size_t _Ip, class... _Args>
724  _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
725      : __data(in_place_index<_Ip>, std::forward<_Args>(__args)...), __index(_Ip) {}
726
727  _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept { return index() == variant_npos; }
728
729  _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept {
730    return __index == __variant_npos<__index_t> ? variant_npos : __index;
731  }
732
733protected:
734  _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() & { return *this; }
735
736  _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() && { return std::move(*this); }
737
738  _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() const& { return *this; }
739
740  _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() const&& { return std::move(*this); }
741
742  _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Types); }
743
744  __union<_DestructibleTrait, 0, _Types...> __data;
745  __index_t __index;
746
747  friend struct __access::__base;
748  friend struct __visitation::__base;
749};
750
751template <class _Traits, _Trait = _Traits::__destructible_trait>
752class __dtor;
753
754#    define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor_definition, destroy)                             \
755      template <class... _Types>                                                                                       \
756      class __dtor<__traits<_Types...>, destructible_trait> : public __base<destructible_trait, _Types...> {           \
757        using __base_type _LIBCPP_NODEBUG = __base<destructible_trait, _Types...>;                                     \
758        using __index_t _LIBCPP_NODEBUG   = typename __base_type::__index_t;                                           \
759                                                                                                                       \
760      public:                                                                                                          \
761        using __base_type::__base_type;                                                                                \
762        using __base_type::operator=;                                                                                  \
763        _LIBCPP_HIDE_FROM_ABI __dtor(const __dtor&)            = default;                                              \
764        _LIBCPP_HIDE_FROM_ABI __dtor(__dtor&&)                 = default;                                              \
765        _LIBCPP_HIDE_FROM_ABI __dtor& operator=(const __dtor&) = default;                                              \
766        _LIBCPP_HIDE_FROM_ABI __dtor& operator=(__dtor&&)      = default;                                              \
767        destructor_definition;                                                                                         \
768                                                                                                                       \
769      protected:                                                                                                       \
770        destroy;                                                                                                       \
771      }
772
773_LIBCPP_VARIANT_DESTRUCTOR(
774    _Trait::_TriviallyAvailable,
775    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = default,
776    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept {
777      this->__index = __variant_npos<__index_t>;
778    } _LIBCPP_EAT_SEMICOLON);
779
780_LIBCPP_VARIANT_DESTRUCTOR(
781    _Trait::_Available,
782    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() { __destroy(); } _LIBCPP_EAT_SEMICOLON,
783    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept {
784      if (!this->valueless_by_exception()) {
785        __visitation::__base::__visit_alt(
786            [](auto& __alt) noexcept {
787              using __alt_type = __remove_cvref_t<decltype(__alt)>;
788              __alt.~__alt_type();
789            },
790            *this);
791      }
792      this->__index = __variant_npos<__index_t>;
793    } _LIBCPP_EAT_SEMICOLON);
794
795_LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable,
796                           _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor()                 = delete,
797                           _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept = delete);
798
799#    undef _LIBCPP_VARIANT_DESTRUCTOR
800
801template <class _Traits>
802class __ctor : public __dtor<_Traits> {
803  using __base_type _LIBCPP_NODEBUG = __dtor<_Traits>;
804
805public:
806  using __base_type::__base_type;
807  using __base_type::operator=;
808
809protected:
810  template <class _Rhs>
811  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
812    __lhs.__destroy();
813    if (!__rhs.valueless_by_exception()) {
814      auto __rhs_index = __rhs.index();
815      __visitation::__base::__visit_alt_at(
816          __rhs_index,
817          [&__lhs](auto&& __rhs_alt) {
818            std::__construct_at(std::addressof(__lhs.__data),
819                                in_place_index<__decay_t<decltype(__rhs_alt)>::__index>,
820                                std::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
821          },
822          std::forward<_Rhs>(__rhs));
823      __lhs.__index = __rhs_index;
824    }
825  }
826};
827
828template <class _Traits, _Trait = _Traits::__move_constructible_trait>
829class __move_constructor;
830
831#    define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, move_constructor_definition)                    \
832      template <class... _Types>                                                                                       \
833      class __move_constructor<__traits<_Types...>, move_constructible_trait> : public __ctor<__traits<_Types...>> {   \
834        using __base_type _LIBCPP_NODEBUG = __ctor<__traits<_Types...>>;                                               \
835                                                                                                                       \
836      public:                                                                                                          \
837        using __base_type::__base_type;                                                                                \
838        using __base_type::operator=;                                                                                  \
839                                                                                                                       \
840        _LIBCPP_HIDE_FROM_ABI __move_constructor(const __move_constructor&)            = default;                      \
841        _LIBCPP_HIDE_FROM_ABI ~__move_constructor()                                    = default;                      \
842        _LIBCPP_HIDE_FROM_ABI __move_constructor& operator=(const __move_constructor&) = default;                      \
843        _LIBCPP_HIDE_FROM_ABI __move_constructor& operator=(__move_constructor&&)      = default;                      \
844        move_constructor_definition;                                                                                   \
845      }
846
847_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
848    _Trait::_TriviallyAvailable,
849    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) = default);
850
851_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
852    _Trait::_Available,
853    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) noexcept(
854        __all<is_nothrow_move_constructible_v<_Types>...>::value) : __move_constructor(__valueless_t{}) {
855      this->__generic_construct(*this, std::move(__that));
856    } _LIBCPP_EAT_SEMICOLON);
857
858_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
859    _Trait::_Unavailable,
860    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&&) = delete);
861
862#    undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
863
864template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
865class __copy_constructor;
866
867#    define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, copy_constructor_definition)                    \
868      template <class... _Types>                                                                                       \
869      class __copy_constructor<__traits<_Types...>, copy_constructible_trait>                                          \
870          : public __move_constructor<__traits<_Types...>> {                                                           \
871        using __base_type _LIBCPP_NODEBUG = __move_constructor<__traits<_Types...>>;                                   \
872                                                                                                                       \
873      public:                                                                                                          \
874        using __base_type::__base_type;                                                                                \
875        using __base_type::operator=;                                                                                  \
876                                                                                                                       \
877        _LIBCPP_HIDE_FROM_ABI __copy_constructor(__copy_constructor&&)                 = default;                      \
878        _LIBCPP_HIDE_FROM_ABI ~__copy_constructor()                                    = default;                      \
879        _LIBCPP_HIDE_FROM_ABI __copy_constructor& operator=(const __copy_constructor&) = default;                      \
880        _LIBCPP_HIDE_FROM_ABI __copy_constructor& operator=(__copy_constructor&&)      = default;                      \
881        copy_constructor_definition;                                                                                   \
882      }
883
884_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
885    _Trait::_TriviallyAvailable,
886    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) = default);
887
888_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
889    _Trait::_Available,
890    _LIBCPP_HIDE_FROM_ABI
891    _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) : __copy_constructor(
892        __valueless_t{}) { this->__generic_construct(*this, __that); } _LIBCPP_EAT_SEMICOLON);
893
894_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
895    _Trait::_Unavailable,
896    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor&) = delete);
897
898#    undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
899
900template <class _Traits>
901class __assignment : public __copy_constructor<_Traits> {
902  using __base_type _LIBCPP_NODEBUG = __copy_constructor<_Traits>;
903
904public:
905  using __base_type::__base_type;
906  using __base_type::operator=;
907
908  template <size_t _Ip, class... _Args>
909  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto& __emplace(_Args&&... __args) {
910    this->__destroy();
911    std::__construct_at(std::addressof(this->__data), in_place_index<_Ip>, std::forward<_Args>(__args)...);
912    this->__index = _Ip;
913    return __access::__base::__get_alt<_Ip>(*this).__value;
914  }
915
916protected:
917  template <size_t _Ip, class _Tp, class _Arg>
918  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
919    if (this->index() == _Ip) {
920      __a.__value = std::forward<_Arg>(__arg);
921    } else {
922      struct {
923        _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(true_type) const {
924          __this->__emplace<_Ip>(std::forward<_Arg>(__arg));
925        }
926        _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(false_type) const {
927          __this->__emplace<_Ip>(_Tp(std::forward<_Arg>(__arg)));
928        }
929        __assignment* __this;
930        _Arg&& __arg;
931      } __impl{this, std::forward<_Arg>(__arg)};
932      __impl(bool_constant < is_nothrow_constructible_v<_Tp, _Arg> || !is_nothrow_move_constructible_v < _Tp >> {});
933    }
934  }
935
936  template <class _That>
937  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_assign(_That&& __that) {
938    if (this->valueless_by_exception() && __that.valueless_by_exception()) {
939      // do nothing.
940    } else if (__that.valueless_by_exception()) {
941      this->__destroy();
942    } else {
943      __visitation::__base::__visit_alt_at(
944          __that.index(),
945          [this](auto& __this_alt, auto&& __that_alt) {
946            this->__assign_alt(__this_alt, std::forward<decltype(__that_alt)>(__that_alt).__value);
947          },
948          *this,
949          std::forward<_That>(__that));
950    }
951  }
952};
953
954template <class _Traits, _Trait = _Traits::__move_assignable_trait>
955class __move_assignment;
956
957#    define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, move_assignment_definition)                         \
958      template <class... _Types>                                                                                       \
959      class __move_assignment<__traits<_Types...>, move_assignable_trait> : public __assignment<__traits<_Types...>> { \
960        using __base_type _LIBCPP_NODEBUG = __assignment<__traits<_Types...>>;                                         \
961                                                                                                                       \
962      public:                                                                                                          \
963        using __base_type::__base_type;                                                                                \
964        using __base_type::operator=;                                                                                  \
965                                                                                                                       \
966        _LIBCPP_HIDE_FROM_ABI __move_assignment(const __move_assignment&)            = default;                        \
967        _LIBCPP_HIDE_FROM_ABI __move_assignment(__move_assignment&&)                 = default;                        \
968        _LIBCPP_HIDE_FROM_ABI ~__move_assignment()                                   = default;                        \
969        _LIBCPP_HIDE_FROM_ABI __move_assignment& operator=(const __move_assignment&) = default;                        \
970        move_assignment_definition;                                                                                    \
971      }
972
973_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_TriviallyAvailable,
974                                _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=(
975                                    __move_assignment&& __that) = default);
976
977_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
978    _Trait::_Available,
979    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment&
980    operator=(__move_assignment&& __that) noexcept(
981        __all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_move_assignable_v<_Types>)...>::value) {
982      this->__generic_assign(std::move(__that));
983      return *this;
984    } _LIBCPP_EAT_SEMICOLON);
985
986_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
987    _Trait::_Unavailable,
988    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=(__move_assignment&&) = delete);
989
990#    undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
991
992template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
993class __copy_assignment;
994
995#    define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, copy_assignment_definition)                         \
996      template <class... _Types>                                                                                       \
997      class __copy_assignment<__traits<_Types...>, copy_assignable_trait>                                              \
998          : public __move_assignment<__traits<_Types...>> {                                                            \
999        using __base_type _LIBCPP_NODEBUG = __move_assignment<__traits<_Types...>>;                                    \
1000                                                                                                                       \
1001      public:                                                                                                          \
1002        using __base_type::__base_type;                                                                                \
1003        using __base_type::operator=;                                                                                  \
1004                                                                                                                       \
1005        _LIBCPP_HIDE_FROM_ABI __copy_assignment(const __copy_assignment&)       = default;                             \
1006        _LIBCPP_HIDE_FROM_ABI __copy_assignment(__copy_assignment&&)            = default;                             \
1007        _LIBCPP_HIDE_FROM_ABI ~__copy_assignment()                              = default;                             \
1008        _LIBCPP_HIDE_FROM_ABI __copy_assignment& operator=(__copy_assignment&&) = default;                             \
1009        copy_assignment_definition;                                                                                    \
1010      }
1011
1012_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_TriviallyAvailable,
1013                                _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=(
1014                                    const __copy_assignment& __that) = default);
1015
1016_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1017    _Trait::_Available,
1018    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment&
1019    operator=(const __copy_assignment& __that) {
1020      this->__generic_assign(__that);
1021      return *this;
1022    } _LIBCPP_EAT_SEMICOLON);
1023
1024_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_Unavailable,
1025                                _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=(
1026                                    const __copy_assignment&) = delete);
1027
1028#    undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1029
1030template <class... _Types>
1031class __impl : public __copy_assignment<__traits<_Types...>> {
1032  using __base_type _LIBCPP_NODEBUG = __copy_assignment<__traits<_Types...>>;
1033
1034public:
1035  using __base_type::__base_type; // get in_place_index_t constructor & friends
1036  _LIBCPP_HIDE_FROM_ABI __impl(__impl const&)            = default;
1037  _LIBCPP_HIDE_FROM_ABI __impl(__impl&&)                 = default;
1038  _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl const&) = default;
1039  _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl&&)      = default;
1040
1041  template <size_t _Ip, class _Arg>
1042  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign(_Arg&& __arg) {
1043    this->__assign_alt(__access::__base::__get_alt<_Ip>(*this), std::forward<_Arg>(__arg));
1044  }
1045
1046  inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__impl& __that) {
1047    if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1048      // do nothing.
1049    } else if (this->index() == __that.index()) {
1050      __visitation::__base::__visit_alt_at(
1051          this->index(),
1052          [](auto& __this_alt, auto& __that_alt) {
1053            using std::swap;
1054            swap(__this_alt.__value, __that_alt.__value);
1055          },
1056          *this,
1057          __that);
1058    } else {
1059      __impl* __lhs = this;
1060      __impl* __rhs = std::addressof(__that);
1061      if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1062        std::swap(__lhs, __rhs);
1063      }
1064      __impl __tmp(std::move(*__rhs));
1065#    if _LIBCPP_HAS_EXCEPTIONS
1066      if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
1067        this->__generic_construct(*__rhs, std::move(*__lhs));
1068      } else {
1069        // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1070        // and `__tmp` is nothrow move constructible then we move `__tmp` back
1071        // into `__rhs` and provide the strong exception safety guarantee.
1072        try {
1073          this->__generic_construct(*__rhs, std::move(*__lhs));
1074        } catch (...) {
1075          if (__tmp.__move_nothrow()) {
1076            this->__generic_construct(*__rhs, std::move(__tmp));
1077          }
1078          throw;
1079        }
1080      }
1081#    else
1082      // this isn't consolidated with the `if constexpr` branch above due to
1083      // `throw` being ill-formed with exceptions disabled even when discarded.
1084      this->__generic_construct(*__rhs, std::move(*__lhs));
1085#    endif
1086      this->__generic_construct(*__lhs, std::move(__tmp));
1087    }
1088  }
1089
1090private:
1091  constexpr inline _LIBCPP_HIDE_FROM_ABI bool __move_nothrow() const {
1092    constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1093    return this->valueless_by_exception() || __results[this->index()];
1094  }
1095};
1096
1097struct __no_narrowing_check {
1098  template <class _Dest, class _Source>
1099  using _Apply _LIBCPP_NODEBUG = __type_identity<_Dest>;
1100};
1101
1102struct __narrowing_check {
1103  template <class _Dest>
1104  static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>;
1105  template <class _Dest, class _Source>
1106  using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({std::declval<_Source>()}));
1107};
1108
1109template <class _Dest, class _Source>
1110using __check_for_narrowing _LIBCPP_NODEBUG =
1111    typename _If< is_arithmetic<_Dest>::value, __narrowing_check, __no_narrowing_check >::template _Apply<_Dest,
1112                                                                                                          _Source>;
1113
1114template <class _Tp, size_t _Idx>
1115struct __overload {
1116  template <class _Up>
1117  auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
1118};
1119
1120template <class... _Bases>
1121struct __all_overloads : _Bases... {
1122  void operator()() const;
1123  using _Bases::operator()...;
1124};
1125
1126template <class _IdxSeq>
1127struct __make_overloads_imp;
1128
1129template <size_t... _Idx>
1130struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1131  template <class... _Types>
1132  using _Apply _LIBCPP_NODEBUG = __all_overloads<__overload<_Types, _Idx>...>;
1133};
1134
1135template <class... _Types>
1136using _MakeOverloads _LIBCPP_NODEBUG =
1137    typename __make_overloads_imp< __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
1138
1139template <class _Tp, class... _Types>
1140using __best_match_t _LIBCPP_NODEBUG = typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
1141
1142} // namespace __variant_detail
1143
1144template <class _Visitor, class... _Vs, typename = void_t<decltype(std::__as_variant(std::declval<_Vs>()))...>>
1145_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs);
1146
1147#    if _LIBCPP_STD_VER >= 20
1148template <class _Rp,
1149          class _Visitor,
1150          class... _Vs,
1151          typename = void_t<decltype(std::__as_variant(std::declval<_Vs>()))...>>
1152_LIBCPP_HIDE_FROM_ABI constexpr _Rp visit(_Visitor&& __visitor, _Vs&&... __vs);
1153#    endif
1154
1155template <class... _Types>
1156class _LIBCPP_DECLSPEC_EMPTY_BASES _LIBCPP_NO_SPECIALIZATIONS variant
1157    : private __sfinae_ctor_base< __all<is_copy_constructible_v<_Types>...>::value,
1158                                  __all<is_move_constructible_v<_Types>...>::value>,
1159      private __sfinae_assign_base<
1160          __all<(is_copy_constructible_v<_Types> && is_copy_assignable_v<_Types>)...>::value,
1161          __all<(is_move_constructible_v<_Types> && is_move_assignable_v<_Types>)...>::value> {
1162  static_assert(0 < sizeof...(_Types), "variant must consist of at least one alternative.");
1163
1164  static_assert(__all<!is_array_v<_Types>...>::value, "variant can not have an array type as an alternative.");
1165
1166  static_assert(__all<!is_reference_v<_Types>...>::value, "variant can not have a reference type as an alternative.");
1167
1168  static_assert(__all<!is_void_v<_Types>...>::value, "variant can not have a void type as an alternative.");
1169
1170  using __first_type _LIBCPP_NODEBUG = variant_alternative_t<0, variant>;
1171
1172public:
1173  using __trivially_relocatable _LIBCPP_NODEBUG =
1174      conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>;
1175  using __replaceable _LIBCPP_NODEBUG = conditional_t<_And<__is_replaceable<_Types>...>::value, variant, void>;
1176
1177  template <bool _Dummy                                                                               = true,
1178            enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0>
1179  _LIBCPP_HIDE_FROM_ABI constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
1180      : __impl_(in_place_index<0>) {}
1181
1182  _LIBCPP_HIDE_FROM_ABI constexpr variant(const variant&) = default;
1183  _LIBCPP_HIDE_FROM_ABI constexpr variant(variant&&)      = default;
1184
1185  template < class _Arg,
1186             enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int>        = 0,
1187             enable_if_t<!__is_inplace_type<__remove_cvref_t<_Arg>>::value, int>  = 0,
1188             enable_if_t<!__is_inplace_index<__remove_cvref_t<_Arg>>::value, int> = 0,
1189             class _Tp  = __variant_detail::__best_match_t<_Arg, _Types...>,
1190             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1191             enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1192  _LIBCPP_HIDE_FROM_ABI constexpr variant(_Arg&& __arg) noexcept(is_nothrow_constructible_v<_Tp, _Arg>)
1193      : __impl_(in_place_index<_Ip>, std::forward<_Arg>(__arg)) {}
1194
1195  template <size_t _Ip,
1196            class... _Args,
1197            class                                               = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1198            class _Tp                                           = variant_alternative_t<_Ip, variant<_Types...>>,
1199            enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1200  _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(in_place_index_t<_Ip>, _Args&&... __args) noexcept(
1201      is_nothrow_constructible_v<_Tp, _Args...>)
1202      : __impl_(in_place_index<_Ip>, std::forward<_Args>(__args)...) {}
1203
1204  template < size_t _Ip,
1205             class _Up,
1206             class... _Args,
1207             enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1208             class _Tp                                   = variant_alternative_t<_Ip, variant<_Types...>>,
1209             enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
1210  _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(
1211      in_place_index_t<_Ip>,
1212      initializer_list<_Up> __il,
1213      _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
1214      : __impl_(in_place_index<_Ip>, __il, std::forward<_Args>(__args)...) {}
1215
1216  template < class _Tp,
1217             class... _Args,
1218             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1219             enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1220  _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1221      is_nothrow_constructible_v<_Tp, _Args...>)
1222      : __impl_(in_place_index<_Ip>, std::forward<_Args>(__args)...) {}
1223
1224  template < class _Tp,
1225             class _Up,
1226             class... _Args,
1227             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1228             enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
1229  _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(
1230      in_place_type_t<_Tp>,
1231      initializer_list<_Up> __il,
1232      _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
1233      : __impl_(in_place_index<_Ip>, __il, std::forward<_Args>(__args)...) {}
1234
1235  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~variant() = default;
1236
1237  _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(const variant&) = default;
1238  _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(variant&&)      = default;
1239
1240  template < class _Arg,
1241             enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int> = 0,
1242             class _Tp  = __variant_detail::__best_match_t<_Arg, _Types...>,
1243             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1244             enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>, int> = 0>
1245  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 variant&
1246  operator=(_Arg&& __arg) noexcept(is_nothrow_assignable_v<_Tp&, _Arg> && is_nothrow_constructible_v<_Tp, _Arg>) {
1247    __impl_.template __assign<_Ip>(std::forward<_Arg>(__arg));
1248    return *this;
1249  }
1250
1251  template < size_t _Ip,
1252             class... _Args,
1253             enable_if_t<(_Ip < sizeof...(_Types)), int>         = 0,
1254             class _Tp                                           = variant_alternative_t<_Ip, variant<_Types...>>,
1255             enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1256  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
1257    return __impl_.template __emplace<_Ip>(std::forward<_Args>(__args)...);
1258  }
1259
1260  template < size_t _Ip,
1261             class _Up,
1262             class... _Args,
1263             enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1264             class _Tp                                   = variant_alternative_t<_Ip, variant<_Types...>>,
1265             enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
1266  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1267    return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...);
1268  }
1269
1270  template < class _Tp,
1271             class... _Args,
1272             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1273             enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1274  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
1275    return __impl_.template __emplace<_Ip>(std::forward<_Args>(__args)...);
1276  }
1277
1278  template < class _Tp,
1279             class _Up,
1280             class... _Args,
1281             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1282             enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
1283  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1284    return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...);
1285  }
1286
1287  _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept {
1288    return __impl_.valueless_by_exception();
1289  }
1290
1291  _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept { return __impl_.index(); }
1292
1293  template < bool _Dummy       = true,
1294             enable_if_t< __all<(__dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1295                                 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1296                          int> = 0>
1297  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(variant& __that) noexcept(
1298      __all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_swappable_v<_Types>)...>::value) {
1299    __impl_.__swap(__that.__impl_);
1300  }
1301
1302#    if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
1303  // Helper class to implement [variant.visit]/10
1304  //   Constraints: The call to visit does not use an explicit template-argument-list
1305  //   that begins with a type template-argument.
1306  struct __variant_visit_barrier_tag {
1307    _LIBCPP_HIDE_FROM_ABI explicit __variant_visit_barrier_tag() = default;
1308  };
1309
1310  template <__variant_visit_barrier_tag = __variant_visit_barrier_tag{}, class _Self, class _Visitor>
1311  _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) visit(this _Self&& __self, _Visitor&& __visitor) {
1312    return std::visit(std::forward<_Visitor>(__visitor), std::__forward_as<_Self, variant>(__self));
1313  }
1314
1315  template <class _Rp, class _Self, class _Visitor>
1316  _LIBCPP_HIDE_FROM_ABI constexpr _Rp visit(this _Self&& __self, _Visitor&& __visitor) {
1317    return std::visit<_Rp>(std::forward<_Visitor>(__visitor), std::__forward_as<_Self, variant>(__self));
1318  }
1319#    endif
1320
1321private:
1322  __variant_detail::__impl<_Types...> __impl_;
1323
1324  friend struct __variant_detail::__access::__variant;
1325  friend struct __variant_detail::__visitation::__variant;
1326};
1327
1328template <size_t _Ip, class... _Types>
1329_LIBCPP_HIDE_FROM_ABI constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1330  return __v.index() == _Ip;
1331}
1332
1333template <class _Tp, class... _Types>
1334_LIBCPP_HIDE_FROM_ABI constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1335  return std::__holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1336}
1337
1338template <size_t _Ip, class _Vp>
1339_LIBCPP_HIDE_FROM_ABI constexpr auto&& __generic_get(_Vp&& __v) {
1340  using __variant_detail::__access::__variant;
1341  if (!std::__holds_alternative<_Ip>(__v)) {
1342    std::__throw_bad_variant_access();
1343  }
1344  return __variant::__get_alt<_Ip>(std::forward<_Vp>(__v)).__value;
1345}
1346
1347template <size_t _Ip, class... _Types>
1348_LIBCPP_HIDE_FROM_ABI constexpr variant_alternative_t<_Ip, variant<_Types...>>& get(variant<_Types...>& __v) {
1349  static_assert(_Ip < sizeof...(_Types));
1350  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1351  return std::__generic_get<_Ip>(__v);
1352}
1353
1354template <size_t _Ip, class... _Types>
1355_LIBCPP_HIDE_FROM_ABI constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get(variant<_Types...>&& __v) {
1356  static_assert(_Ip < sizeof...(_Types));
1357  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1358  return std::__generic_get<_Ip>(std::move(__v));
1359}
1360
1361template <size_t _Ip, class... _Types>
1362_LIBCPP_HIDE_FROM_ABI constexpr const variant_alternative_t<_Ip, variant<_Types...>>&
1363get(const variant<_Types...>& __v) {
1364  static_assert(_Ip < sizeof...(_Types));
1365  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1366  return std::__generic_get<_Ip>(__v);
1367}
1368
1369template <size_t _Ip, class... _Types>
1370_LIBCPP_HIDE_FROM_ABI constexpr const variant_alternative_t<_Ip, variant<_Types...>>&&
1371get(const variant<_Types...>&& __v) {
1372  static_assert(_Ip < sizeof...(_Types));
1373  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1374  return std::__generic_get<_Ip>(std::move(__v));
1375}
1376
1377template <class _Tp, class... _Types>
1378_LIBCPP_HIDE_FROM_ABI constexpr _Tp& get(variant<_Types...>& __v) {
1379  static_assert(!is_void_v<_Tp>);
1380  return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1381}
1382
1383template <class _Tp, class... _Types>
1384_LIBCPP_HIDE_FROM_ABI constexpr _Tp&& get(variant<_Types...>&& __v) {
1385  static_assert(!is_void_v<_Tp>);
1386  return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(std::move(__v));
1387}
1388
1389template <class _Tp, class... _Types>
1390_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& get(const variant<_Types...>& __v) {
1391  static_assert(!is_void_v<_Tp>);
1392  return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1393}
1394
1395template <class _Tp, class... _Types>
1396_LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& get(const variant<_Types...>&& __v) {
1397  static_assert(!is_void_v<_Tp>);
1398  return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(std::move(__v));
1399}
1400
1401template <size_t _Ip, class _Vp>
1402_LIBCPP_HIDE_FROM_ABI constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1403  using __variant_detail::__access::__variant;
1404  return __v && std::__holds_alternative<_Ip>(*__v) ? std::addressof(__variant::__get_alt<_Ip>(*__v).__value) : nullptr;
1405}
1406
1407template <size_t _Ip, class... _Types>
1408_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1409get_if(variant<_Types...>* __v) noexcept {
1410  static_assert(_Ip < sizeof...(_Types));
1411  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1412  return std::__generic_get_if<_Ip>(__v);
1413}
1414
1415template <size_t _Ip, class... _Types>
1416_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1417get_if(const variant<_Types...>* __v) noexcept {
1418  static_assert(_Ip < sizeof...(_Types));
1419  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1420  return std::__generic_get_if<_Ip>(__v);
1421}
1422
1423template <class _Tp, class... _Types>
1424_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __v) noexcept {
1425  static_assert(!is_void_v<_Tp>);
1426  return std::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1427}
1428
1429template <class _Tp, class... _Types>
1430_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const _Tp> get_if(const variant<_Types...>* __v) noexcept {
1431  static_assert(!is_void_v<_Tp>);
1432  return std::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1433}
1434
1435template <class _Operator>
1436struct __convert_to_bool {
1437  template <class _T1, class _T2>
1438  _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_T1&& __t1, _T2&& __t2) const {
1439    static_assert(is_convertible<decltype(_Operator{}(std::forward<_T1>(__t1), std::forward<_T2>(__t2))), bool>::value,
1440                  "the relational operator does not return a type which is implicitly convertible to bool");
1441    return _Operator{}(std::forward<_T1>(__t1), std::forward<_T2>(__t2));
1442  }
1443};
1444
1445template <class... _Types>
1446#    if _LIBCPP_STD_VER >= 26
1447  requires(requires(const _Types& __t) {
1448    { __t == __t } -> __core_convertible_to<bool>;
1449  } && ...)
1450#    endif
1451_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1452  using __variant_detail::__visitation::__variant;
1453  if (__lhs.index() != __rhs.index())
1454    return false;
1455  if (__lhs.valueless_by_exception())
1456    return true;
1457  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
1458}
1459
1460#    if _LIBCPP_STD_VER >= 20
1461
1462template <class... _Types>
1463  requires(three_way_comparable<_Types> && ...)
1464_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...>
1465operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1466  using __variant_detail::__visitation::__variant;
1467  using __result_t = common_comparison_category_t<compare_three_way_result_t<_Types>...>;
1468  if (__lhs.valueless_by_exception() && __rhs.valueless_by_exception())
1469    return strong_ordering::equal;
1470  if (__lhs.valueless_by_exception())
1471    return strong_ordering::less;
1472  if (__rhs.valueless_by_exception())
1473    return strong_ordering::greater;
1474  if (auto __c = __lhs.index() <=> __rhs.index(); __c != 0)
1475    return __c;
1476  auto __three_way = []<class _Type>(const _Type& __v, const _Type& __w) -> __result_t { return __v <=> __w; };
1477  return __variant::__visit_value_at(__lhs.index(), __three_way, __lhs, __rhs);
1478}
1479
1480#    endif // _LIBCPP_STD_VER >= 20
1481
1482template <class... _Types>
1483#    if _LIBCPP_STD_VER >= 26
1484  requires(requires(const _Types& __t) {
1485    { __t != __t } -> __core_convertible_to<bool>;
1486  } && ...)
1487#    endif
1488_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1489  using __variant_detail::__visitation::__variant;
1490  if (__lhs.index() != __rhs.index())
1491    return true;
1492  if (__lhs.valueless_by_exception())
1493    return false;
1494  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
1495}
1496
1497template <class... _Types>
1498#    if _LIBCPP_STD_VER >= 26
1499  requires(requires(const _Types& __t) {
1500    { __t < __t } -> __core_convertible_to<bool>;
1501  } && ...)
1502#    endif
1503_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1504  using __variant_detail::__visitation::__variant;
1505  if (__rhs.valueless_by_exception())
1506    return false;
1507  if (__lhs.valueless_by_exception())
1508    return true;
1509  if (__lhs.index() < __rhs.index())
1510    return true;
1511  if (__lhs.index() > __rhs.index())
1512    return false;
1513  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
1514}
1515
1516template <class... _Types>
1517#    if _LIBCPP_STD_VER >= 26
1518  requires(requires(const _Types& __t) {
1519    { __t > __t } -> __core_convertible_to<bool>;
1520  } && ...)
1521#    endif
1522_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1523  using __variant_detail::__visitation::__variant;
1524  if (__lhs.valueless_by_exception())
1525    return false;
1526  if (__rhs.valueless_by_exception())
1527    return true;
1528  if (__lhs.index() > __rhs.index())
1529    return true;
1530  if (__lhs.index() < __rhs.index())
1531    return false;
1532  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
1533}
1534
1535template <class... _Types>
1536#    if _LIBCPP_STD_VER >= 26
1537  requires(requires(const _Types& __t) {
1538    { __t <= __t } -> __core_convertible_to<bool>;
1539  } && ...)
1540#    endif
1541_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1542  using __variant_detail::__visitation::__variant;
1543  if (__lhs.valueless_by_exception())
1544    return true;
1545  if (__rhs.valueless_by_exception())
1546    return false;
1547  if (__lhs.index() < __rhs.index())
1548    return true;
1549  if (__lhs.index() > __rhs.index())
1550    return false;
1551  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
1552}
1553
1554template <class... _Types>
1555#    if _LIBCPP_STD_VER >= 26
1556  requires(requires(const _Types& __t) {
1557    { __t >= __t } -> __core_convertible_to<bool>;
1558  } && ...)
1559#    endif
1560_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1561  using __variant_detail::__visitation::__variant;
1562  if (__rhs.valueless_by_exception())
1563    return true;
1564  if (__lhs.valueless_by_exception())
1565    return false;
1566  if (__lhs.index() > __rhs.index())
1567    return true;
1568  if (__lhs.index() < __rhs.index())
1569    return false;
1570  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
1571}
1572
1573template <class... _Vs>
1574_LIBCPP_HIDE_FROM_ABI constexpr void __throw_if_valueless(_Vs&&... __vs) {
1575  const bool __valueless = (... || std::__as_variant(__vs).valueless_by_exception());
1576  if (__valueless) {
1577    std::__throw_bad_variant_access();
1578  }
1579}
1580
1581template < class _Visitor, class... _Vs, typename>
1582_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) {
1583  using __variant_detail::__visitation::__variant;
1584  std::__throw_if_valueless(std::forward<_Vs>(__vs)...);
1585  return __variant::__visit_value(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...);
1586}
1587
1588#    if _LIBCPP_STD_VER >= 20
1589template < class _Rp, class _Visitor, class... _Vs, typename>
1590_LIBCPP_HIDE_FROM_ABI constexpr _Rp visit(_Visitor&& __visitor, _Vs&&... __vs) {
1591  using __variant_detail::__visitation::__variant;
1592  std::__throw_if_valueless(std::forward<_Vs>(__vs)...);
1593  return __variant::__visit_value<_Rp>(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...);
1594}
1595#    endif
1596
1597template <class... _Types>
1598_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto
1599swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs)))
1600    -> decltype(__lhs.swap(__rhs)) {
1601  return __lhs.swap(__rhs);
1602}
1603
1604template <class... _Types>
1605struct hash< __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
1606#    if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1607  using argument_type _LIBCPP_DEPRECATED_IN_CXX17 = variant<_Types...>;
1608  using result_type _LIBCPP_DEPRECATED_IN_CXX17   = size_t;
1609#    endif
1610
1611  _LIBCPP_HIDE_FROM_ABI size_t operator()(const variant<_Types...>& __v) const {
1612    using __variant_detail::__visitation::__variant;
1613    size_t __res =
1614        __v.valueless_by_exception()
1615            ? 299792458 // Random value chosen by the universe upon creation
1616            : __variant::__visit_alt(
1617                  [](const auto& __alt) {
1618                    using __alt_type   = __remove_cvref_t<decltype(__alt)>;
1619                    using __value_type = remove_const_t< typename __alt_type::__value_type>;
1620                    return hash<__value_type>{}(__alt.__value);
1621                  },
1622                  __v);
1623    return std::__hash_combine(__res, hash<size_t>{}(__v.index()));
1624  }
1625};
1626
1627// __unchecked_get is the same as std::get, except, it is UB to use it with the wrong
1628// type whereas std::get will throw or returning nullptr. This makes it faster than
1629// std::get.
1630template <size_t _Ip, class _Vp>
1631_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(_Vp&& __v) noexcept {
1632  using __variant_detail::__access::__variant;
1633  return __variant::__get_alt<_Ip>(std::forward<_Vp>(__v)).__value;
1634}
1635
1636template <class _Tp, class... _Types>
1637_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept {
1638  return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1639}
1640
1641template <class _Tp, class... _Types>
1642_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
1643  return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1644}
1645
1646#  endif // _LIBCPP_STD_VER >= 17
1647
1648_LIBCPP_END_NAMESPACE_STD
1649
1650_LIBCPP_POP_MACROS
1651
1652#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1653#    include <cstddef>
1654#    include <exception>
1655#    include <tuple>
1656#    include <type_traits>
1657#    include <typeinfo>
1658#    include <utility>
1659#  endif
1660#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
1661
1662#endif // _LIBCPP_VARIANT
1663