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