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