llvm-project

Форк
0
1650 строк · 72.1 Кб
1
// -*- C++ -*-
2
//===----------------------------------------------------------------------===//
3
//
4
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5
// See https://llvm.org/LICENSE.txt for license information.
6
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7
//
8
//===----------------------------------------------------------------------===//
9

10
#ifndef _LIBCPP_VARIANT
11
#define _LIBCPP_VARIANT
12

13
/*
14
   variant synopsis
15

16
namespace std {
17

18
  // 20.7.2, class template variant
19
  template <class... Types>
20
  class variant {
21
  public:
22

23
    // 20.7.2.1, constructors
24
    constexpr variant() noexcept(see below);
25
    constexpr variant(const variant&);
26
    constexpr variant(variant&&) noexcept(see below);
27

28
    template <class T> constexpr variant(T&&) noexcept(see below);
29

30
    template <class T, class... Args>
31
    constexpr explicit variant(in_place_type_t<T>, Args&&...);
32

33
    template <class T, class U, class... Args>
34
    constexpr explicit variant(
35
        in_place_type_t<T>, initializer_list<U>, Args&&...);
36

37
    template <size_t I, class... Args>
38
    constexpr explicit variant(in_place_index_t<I>, Args&&...);
39

40
    template <size_t I, class U, class... Args>
41
    constexpr explicit variant(
42
        in_place_index_t<I>, initializer_list<U>, Args&&...);
43

44
    // 20.7.2.2, destructor
45
    constexpr ~variant();                                             // constexpr since c++20
46

47
    // 20.7.2.3, assignment
48
    constexpr variant& operator=(const variant&);
49
    constexpr variant& operator=(variant&&) noexcept(see below);
50

51
    template <class T>
52
    constexpr variant& operator=(T&&) noexcept(see below);            // constexpr since c++20
53

54
    // 20.7.2.4, modifiers
55
    template <class T, class... Args>
56
    constexpr T& emplace(Args&&...);                                  // constexpr since c++20
57

58
    template <class T, class U, class... Args>
59
    constexpr T& emplace(initializer_list<U>, Args&&...);             // constexpr since c++20
60

61
    template <size_t I, class... Args>
62
    constexpr variant_alternative_t<I, variant>& emplace(Args&&...);  // constexpr since c++20
63

64
    template <size_t I, class U, class...  Args>
65
    constexpr variant_alternative_t<I, variant>&
66
        emplace(initializer_list<U>, Args&&...);                      // constexpr since c++20
67

68
    // 20.7.2.5, value status
69
    constexpr bool valueless_by_exception() const noexcept;
70
    constexpr size_t index() const noexcept;
71

72
    // 20.7.2.6, swap
73
    void swap(variant&) noexcept(see below);
74

75
    // [variant.visit], visitation
76
    template<class Self, class Visitor>
77
      constexpr decltype(auto) visit(this Self&&, Visitor&&); // Since C++26
78
    template<class R, class Self, class Visitor>
79
      constexpr R visit(this Self&&, Visitor&&);              // Since C++26
80
  };
81

82
  // 20.7.3, variant helper classes
83
  template <class T> struct variant_size; // undefined
84

85
  template <class T>
86
  inline constexpr size_t variant_size_v = variant_size<T>::value;
87

88
  template <class T> struct variant_size<const T>;
89
  template <class T> struct variant_size<volatile T>;
90
  template <class T> struct variant_size<const volatile T>;
91

92
  template <class... Types>
93
  struct variant_size<variant<Types...>>;
94

95
  template <size_t I, class T> struct variant_alternative; // undefined
96

97
  template <size_t I, class T>
98
  using variant_alternative_t = typename variant_alternative<I, T>::type;
99

100
  template <size_t I, class T> struct variant_alternative<I, const T>;
101
  template <size_t I, class T> struct variant_alternative<I, volatile T>;
102
  template <size_t I, class T> struct variant_alternative<I, const volatile T>;
103

104
  template <size_t I, class... Types>
105
  struct variant_alternative<I, variant<Types...>>;
106

107
  inline constexpr size_t variant_npos = -1;
108

109
  // 20.7.4, value access
110
  template <class T, class... Types>
111
  constexpr bool holds_alternative(const variant<Types...>&) noexcept;
112

113
  template <size_t I, class... Types>
114
  constexpr variant_alternative_t<I, variant<Types...>>&
115
  get(variant<Types...>&);
116

117
  template <size_t I, class... Types>
118
  constexpr variant_alternative_t<I, variant<Types...>>&&
119
  get(variant<Types...>&&);
120

121
  template <size_t I, class... Types>
122
  constexpr variant_alternative_t<I, variant<Types...>> const&
123
  get(const variant<Types...>&);
124

125
  template <size_t I, class... Types>
126
  constexpr variant_alternative_t<I, variant<Types...>> const&&
127
  get(const variant<Types...>&&);
128

129
  template <class T, class...  Types>
130
  constexpr T& get(variant<Types...>&);
131

132
  template <class T, class... Types>
133
  constexpr T&& get(variant<Types...>&&);
134

135
  template <class T, class... Types>
136
  constexpr const T& get(const variant<Types...>&);
137

138
  template <class T, class... Types>
139
  constexpr const T&& get(const variant<Types...>&&);
140

141
  template <size_t I, class... Types>
142
  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
143
  get_if(variant<Types...>*) noexcept;
144

145
  template <size_t I, class... Types>
146
  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
147
  get_if(const variant<Types...>*) noexcept;
148

149
  template <class T, class... Types>
150
  constexpr add_pointer_t<T>
151
  get_if(variant<Types...>*) noexcept;
152

153
  template <class T, class... Types>
154
  constexpr add_pointer_t<const T>
155
  get_if(const variant<Types...>*) noexcept;
156

157
  // 20.7.5, relational operators
158
  template <class... Types>
159
  constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
160

161
  template <class... Types>
162
  constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
163

164
  template <class... Types>
165
  constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
166

167
  template <class... Types>
168
  constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
169

170
  template <class... Types>
171
  constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
172

173
  template <class... Types>
174
  constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
175

176
  template <class... Types> requires (three_way_comparable<Types> && ...)
177
  constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
178
    operator<=>(const variant<Types...>&, const variant<Types...>&);           // since C++20
179

180
  // 20.7.6, visitation
181
  template <class Visitor, class... Variants>
182
  constexpr see below visit(Visitor&&, Variants&&...);
183

184
  template <class R, class Visitor, class... Variants>
185
  constexpr R visit(Visitor&&, Variants&&...); // since C++20
186

187
  // 20.7.7, class monostate
188
  struct monostate;
189

190
  // 20.7.8, monostate relational operators
191
  constexpr bool operator==(monostate, monostate) noexcept;
192
  constexpr bool operator!=(monostate, monostate) noexcept;             // until C++20
193
  constexpr bool operator<(monostate, monostate) noexcept;              // until C++20
194
  constexpr bool operator>(monostate, monostate) noexcept;              // until C++20
195
  constexpr bool operator<=(monostate, monostate) noexcept;             // until C++20
196
  constexpr bool operator>=(monostate, monostate) noexcept;             // until C++20
197
  constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // since C++20
198

199
  // 20.7.9, specialized algorithms
200
  template <class... Types>
201
  void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
202

203
  // 20.7.10, class bad_variant_access
204
  class bad_variant_access;
205

206
  // 20.7.11, hash support
207
  template <class T> struct hash;
208
  template <class... Types> struct hash<variant<Types...>>;
209
  template <> struct hash<monostate>;
210

211
} // namespace std
212

213
*/
214

215
#include <__compare/common_comparison_category.h>
216
#include <__compare/compare_three_way_result.h>
217
#include <__compare/three_way_comparable.h>
218
#include <__config>
219
#include <__exception/exception.h>
220
#include <__functional/hash.h>
221
#include <__functional/invoke.h>
222
#include <__functional/operations.h>
223
#include <__functional/unary_function.h>
224
#include <__memory/addressof.h>
225
#include <__memory/construct_at.h>
226
#include <__tuple/find_index.h>
227
#include <__tuple/sfinae_helpers.h>
228
#include <__type_traits/add_const.h>
229
#include <__type_traits/add_cv.h>
230
#include <__type_traits/add_pointer.h>
231
#include <__type_traits/add_volatile.h>
232
#include <__type_traits/common_type.h>
233
#include <__type_traits/conjunction.h>
234
#include <__type_traits/dependent_type.h>
235
#include <__type_traits/is_array.h>
236
#include <__type_traits/is_constructible.h>
237
#include <__type_traits/is_destructible.h>
238
#include <__type_traits/is_nothrow_assignable.h>
239
#include <__type_traits/is_nothrow_constructible.h>
240
#include <__type_traits/is_reference.h>
241
#include <__type_traits/is_trivially_assignable.h>
242
#include <__type_traits/is_trivially_constructible.h>
243
#include <__type_traits/is_trivially_destructible.h>
244
#include <__type_traits/is_trivially_relocatable.h>
245
#include <__type_traits/is_void.h>
246
#include <__type_traits/remove_const.h>
247
#include <__type_traits/remove_cvref.h>
248
#include <__type_traits/type_identity.h>
249
#include <__type_traits/void_t.h>
250
#include <__utility/declval.h>
251
#include <__utility/forward.h>
252
#include <__utility/forward_like.h>
253
#include <__utility/in_place.h>
254
#include <__utility/integer_sequence.h>
255
#include <__utility/move.h>
256
#include <__utility/swap.h>
257
#include <__variant/monostate.h>
258
#include <__verbose_abort>
259
#include <initializer_list>
260
#include <limits>
261
#include <new>
262
#include <version>
263

264
// standard-mandated includes
265

266
// [variant.syn]
267
#include <compare>
268

269
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
270
#  pragma GCC system_header
271
#endif
272

273
_LIBCPP_PUSH_MACROS
274
#include <__undef_macros>
275

276
namespace std { // explicitly not using versioning namespace
277

278
class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception {
279
public:
280
  const char* what() const _NOEXCEPT override;
281
};
282

283
} // namespace std
284

285
_LIBCPP_BEGIN_NAMESPACE_STD
286

287
#if _LIBCPP_STD_VER >= 17
288

289
// Light N-dimensional array of function pointers. Used in place of std::array to avoid
290
// adding a dependency.
291
template <class _Tp, size_t _Size>
292
struct __farray {
293
  static_assert(_Size > 0, "N-dimensional array should never be empty in std::visit");
294
  _Tp __buf_[_Size] = {};
295

296
  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t __n) const noexcept { return __buf_[__n]; }
297
};
298

299
_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS void
300
__throw_bad_variant_access() {
301
#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
302
  throw bad_variant_access();
303
#  else
304
  _LIBCPP_VERBOSE_ABORT("bad_variant_access was thrown in -fno-exceptions mode");
305
#  endif
306
}
307

308
template <class... _Types>
309
class _LIBCPP_TEMPLATE_VIS variant;
310

311
template <class _Tp>
312
struct _LIBCPP_TEMPLATE_VIS variant_size;
313

314
template <class _Tp>
315
inline constexpr size_t variant_size_v = variant_size<_Tp>::value;
316

317
template <class _Tp>
318
struct _LIBCPP_TEMPLATE_VIS variant_size<const _Tp> : variant_size<_Tp> {};
319

320
template <class _Tp>
321
struct _LIBCPP_TEMPLATE_VIS variant_size<volatile _Tp> : variant_size<_Tp> {};
322

323
template <class _Tp>
324
struct _LIBCPP_TEMPLATE_VIS variant_size<const volatile _Tp> : variant_size<_Tp> {};
325

326
template <class... _Types>
327
struct _LIBCPP_TEMPLATE_VIS variant_size<variant<_Types...>> : integral_constant<size_t, sizeof...(_Types)> {};
328

329
template <size_t _Ip, class _Tp>
330
struct _LIBCPP_TEMPLATE_VIS variant_alternative;
331

332
template <size_t _Ip, class _Tp>
333
using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type;
334

335
template <size_t _Ip, class _Tp>
336
struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const _Tp> : add_const<variant_alternative_t<_Ip, _Tp>> {};
337

338
template <size_t _Ip, class _Tp>
339
struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, volatile _Tp> : add_volatile<variant_alternative_t<_Ip, _Tp>> {};
340

341
template <size_t _Ip, class _Tp>
342
struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp> : add_cv<variant_alternative_t<_Ip, _Tp>> {};
343

344
template <size_t _Ip, class... _Types>
345
struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
346
  static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
347
  using type = __type_pack_element<_Ip, _Types...>;
348
};
349

350
inline constexpr size_t variant_npos = static_cast<size_t>(-1);
351

352
template <size_t _NumAlternatives>
353
_LIBCPP_HIDE_FROM_ABI constexpr auto __choose_index_type() {
354
#  ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
355
  if constexpr (_NumAlternatives < numeric_limits<unsigned char>::max())
356
    return static_cast<unsigned char>(0);
357
  else if constexpr (_NumAlternatives < numeric_limits<unsigned short>::max())
358
    return static_cast<unsigned short>(0);
359
  else
360
#  endif // _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
361
    return static_cast<unsigned int>(0);
362
}
363

364
template <size_t _NumAlts>
365
using __variant_index_t = decltype(std::__choose_index_type<_NumAlts>());
366

367
template <class _IndexType>
368
constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
369

370
template <class... _Types>
371
class _LIBCPP_TEMPLATE_VIS variant;
372

373
template <class... _Types>
374
_LIBCPP_HIDE_FROM_ABI constexpr variant<_Types...>& __as_variant(variant<_Types...>& __vs) noexcept {
375
  return __vs;
376
}
377

378
template <class... _Types>
379
_LIBCPP_HIDE_FROM_ABI constexpr const variant<_Types...>& __as_variant(const variant<_Types...>& __vs) noexcept {
380
  return __vs;
381
}
382

383
template <class... _Types>
384
_LIBCPP_HIDE_FROM_ABI constexpr variant<_Types...>&& __as_variant(variant<_Types...>&& __vs) noexcept {
385
  return std::move(__vs);
386
}
387

388
template <class... _Types>
389
_LIBCPP_HIDE_FROM_ABI constexpr const variant<_Types...>&& __as_variant(const variant<_Types...>&& __vs) noexcept {
390
  return std::move(__vs);
391
}
392

393
namespace __find_detail {
394

395
template <class _Tp, class... _Types>
396
_LIBCPP_HIDE_FROM_ABI constexpr size_t __find_index() {
397
  constexpr bool __matches[] = {is_same_v<_Tp, _Types>...};
398
  size_t __result            = __not_found;
399
  for (size_t __i = 0; __i < sizeof...(_Types); ++__i) {
400
    if (__matches[__i]) {
401
      if (__result != __not_found) {
402
        return __ambiguous;
403
      }
404
      __result = __i;
405
    }
406
  }
407
  return __result;
408
}
409

410
template <size_t _Index>
411
struct __find_unambiguous_index_sfinae_impl : integral_constant<size_t, _Index> {};
412

413
template <>
414
struct __find_unambiguous_index_sfinae_impl<__not_found> {};
415

416
template <>
417
struct __find_unambiguous_index_sfinae_impl<__ambiguous> {};
418

419
template <class _Tp, class... _Types>
420
struct __find_unambiguous_index_sfinae : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {};
421

422
} // namespace __find_detail
423

424
namespace __variant_detail {
425

426
struct __valueless_t {};
427

428
enum class _Trait { _TriviallyAvailable, _Available, _Unavailable };
429

430
template <typename _Tp, template <typename> class _IsTriviallyAvailable, template <typename> class _IsAvailable>
431
constexpr _Trait __trait =
432
    _IsTriviallyAvailable<_Tp>::value ? _Trait::_TriviallyAvailable
433
    : _IsAvailable<_Tp>::value
434
        ? _Trait::_Available
435
        : _Trait::_Unavailable;
436

437
_LIBCPP_HIDE_FROM_ABI constexpr _Trait __common_trait(initializer_list<_Trait> __traits) {
438
  _Trait __result = _Trait::_TriviallyAvailable;
439
  for (_Trait __t : __traits) {
440
    if (static_cast<int>(__t) > static_cast<int>(__result)) {
441
      __result = __t;
442
    }
443
  }
444
  return __result;
445
}
446

447
template <typename... _Types>
448
struct __traits {
449
  static constexpr _Trait __copy_constructible_trait =
450
      __variant_detail::__common_trait({__trait<_Types, is_trivially_copy_constructible, is_copy_constructible>...});
451

452
  static constexpr _Trait __move_constructible_trait =
453
      __variant_detail::__common_trait({__trait<_Types, is_trivially_move_constructible, is_move_constructible>...});
454

455
  static constexpr _Trait __copy_assignable_trait = __variant_detail::__common_trait(
456
      {__copy_constructible_trait, __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...});
457

458
  static constexpr _Trait __move_assignable_trait = __variant_detail::__common_trait(
459
      {__move_constructible_trait, __trait<_Types, is_trivially_move_assignable, is_move_assignable>...});
460

461
  static constexpr _Trait __destructible_trait =
462
      __variant_detail::__common_trait({__trait<_Types, is_trivially_destructible, is_destructible>...});
463
};
464

465
namespace __access {
466

467
struct __union {
468
  template <class _Vp>
469
  _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) {
470
    return std::forward<_Vp>(__v).__head;
471
  }
472

473
  template <class _Vp, size_t _Ip>
474
  _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) {
475
    return __get_alt(std::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>);
476
  }
477
};
478

479
struct __base {
480
  template <size_t _Ip, class _Vp>
481
  _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v) {
482
    return __union::__get_alt(std::forward<_Vp>(__v).__data, in_place_index<_Ip>);
483
  }
484
};
485

486
struct __variant {
487
  template <size_t _Ip, class _Vp>
488
  _LIBCPP_HIDE_FROM_ABI static constexpr auto&& __get_alt(_Vp&& __v) {
489
    return __base::__get_alt<_Ip>(std::forward<_Vp>(__v).__impl_);
490
  }
491
};
492

493
} // namespace __access
494

495
namespace __visitation {
496

497
struct __base {
498
  template <class _Visitor, class... _Vs>
499
  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
500
  __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
501
    constexpr auto __fdiagonal = __make_fdiagonal<_Visitor&&, decltype(std::forward<_Vs>(__vs).__as_base())...>();
502
    return __fdiagonal[__index](std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__as_base()...);
503
  }
504

505
  template <class _Visitor, class... _Vs>
506
  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, _Vs&&... __vs) {
507
    constexpr auto __fmatrix = __make_fmatrix<_Visitor&&, decltype(std::forward<_Vs>(__vs).__as_base())...>();
508
    return __at(__fmatrix, __vs.index()...)(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__as_base()...);
509
  }
510

511
private:
512
  template <class _Tp>
513
  _LIBCPP_HIDE_FROM_ABI static constexpr const _Tp& __at(const _Tp& __elem) {
514
    return __elem;
515
  }
516

517
  template <class _Tp, size_t _Np, typename... _Indices>
518
  _LIBCPP_HIDE_FROM_ABI static constexpr auto&&
519
  __at(const __farray<_Tp, _Np>& __elems, size_t __index, _Indices... __indices) {
520
    return __at(__elems[__index], __indices...);
521
  }
522

523
  template <class _Fp, class... _Fs>
524
  static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_visitor_return_type_check() {
525
    static_assert(
526
        __all<is_same_v<_Fp, _Fs>...>::value, "`std::visit` requires the visitor to have a single return type.");
527
  }
528

529
  template <class... _Fs>
530
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_farray(_Fs&&... __fs) {
531
    __std_visit_visitor_return_type_check<__remove_cvref_t<_Fs>...>();
532
    using __result = __farray<common_type_t<__remove_cvref_t<_Fs>...>, sizeof...(_Fs)>;
533
    return __result{{std::forward<_Fs>(__fs)...}};
534
  }
535

536
  template <size_t... _Is>
537
  struct __dispatcher {
538
    template <class _Fp, class... _Vs>
539
    _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) {
540
      return std::__invoke(static_cast<_Fp>(__f), __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...);
541
    }
542
  };
543

544
  template <class _Fp, class... _Vs, size_t... _Is>
545
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_dispatch(index_sequence<_Is...>) {
546
    return __dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
547
  }
548

549
  template <size_t _Ip, class _Fp, class... _Vs>
550
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal_impl() {
551
    return __make_dispatch<_Fp, _Vs...>(index_sequence<((void)__type_identity<_Vs>{}, _Ip)...>{});
552
  }
553

554
  template <class _Fp, class... _Vs, size_t... _Is>
555
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) {
556
    return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
557
  }
558

559
  template <class _Fp, class _Vp, class... _Vs>
560
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fdiagonal() {
561
    constexpr size_t __np = __remove_cvref_t<_Vp>::__size();
562
    static_assert(__all<(__np == __remove_cvref_t<_Vs>::__size())...>::value);
563
    return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<__np>{});
564
  }
565

566
  template <class _Fp, class... _Vs, size_t... _Is>
567
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) {
568
    return __make_dispatch<_Fp, _Vs...>(__is);
569
  }
570

571
  template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls>
572
  _LIBCPP_HIDE_FROM_ABI static constexpr auto
573
  __make_fmatrix_impl(index_sequence<_Is...>, index_sequence<_Js...>, _Ls... __ls) {
574
    return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>(index_sequence<_Is..., _Js>{}, __ls...)...);
575
  }
576

577
  template <class _Fp, class... _Vs>
578
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_fmatrix() {
579
    return __make_fmatrix_impl<_Fp, _Vs...>(
580
        index_sequence<>{}, make_index_sequence<__remove_cvref_t<_Vs>::__size()>{}...);
581
  }
582
};
583

584
struct __variant {
585
  template <class _Visitor, class... _Vs>
586
  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
587
  __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
588
    return __base::__visit_alt_at(__index, std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs).__impl_...);
589
  }
590

591
  template <class _Visitor, class... _Vs>
592
  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, _Vs&&... __vs) {
593
    return __base::__visit_alt(
594
        std::forward<_Visitor>(__visitor), std::__as_variant(std::forward<_Vs>(__vs)).__impl_...);
595
  }
596

597
  template <class _Visitor, class... _Vs>
598
  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto)
599
  __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) {
600
    return __visit_alt_at(__index, __make_value_visitor(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...);
601
  }
602

603
  template <class _Visitor, class... _Vs>
604
  _LIBCPP_HIDE_FROM_ABI static constexpr decltype(auto) __visit_value(_Visitor&& __visitor, _Vs&&... __vs) {
605
    return __visit_alt(__make_value_visitor(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...);
606
  }
607

608
#  if _LIBCPP_STD_VER >= 20
609
  template <class _Rp, class _Visitor, class... _Vs>
610
  _LIBCPP_HIDE_FROM_ABI static constexpr _Rp __visit_value(_Visitor&& __visitor, _Vs&&... __vs) {
611
    return __visit_alt(__make_value_visitor<_Rp>(std::forward<_Visitor>(__visitor)), std::forward<_Vs>(__vs)...);
612
  }
613
#  endif
614

615
private:
616
  template <class _Visitor, class... _Values>
617
  static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_exhaustive_visitor_check() {
618
    static_assert(is_invocable_v<_Visitor, _Values...>, "`std::visit` requires the visitor to be exhaustive.");
619
  }
620

621
  template <class _Visitor>
622
  struct __value_visitor {
623
    template <class... _Alts>
624
    _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Alts&&... __alts) const {
625
      __std_visit_exhaustive_visitor_check< _Visitor, decltype((std::forward<_Alts>(__alts).__value))...>();
626
      return std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...);
627
    }
628
    _Visitor&& __visitor;
629
  };
630

631
#  if _LIBCPP_STD_VER >= 20
632
  template <class _Rp, class _Visitor>
633
  struct __value_visitor_return_type {
634
    template <class... _Alts>
635
    _LIBCPP_HIDE_FROM_ABI constexpr _Rp operator()(_Alts&&... __alts) const {
636
      __std_visit_exhaustive_visitor_check< _Visitor, decltype((std::forward<_Alts>(__alts).__value))...>();
637
      if constexpr (is_void_v<_Rp>) {
638
        std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...);
639
      } else {
640
        return std::__invoke(std::forward<_Visitor>(__visitor), std::forward<_Alts>(__alts).__value...);
641
      }
642
    }
643

644
    _Visitor&& __visitor;
645
  };
646
#  endif
647

648
  template <class _Visitor>
649
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
650
    return __value_visitor<_Visitor>{std::forward<_Visitor>(__visitor)};
651
  }
652

653
#  if _LIBCPP_STD_VER >= 20
654
  template <class _Rp, class _Visitor>
655
  _LIBCPP_HIDE_FROM_ABI static constexpr auto __make_value_visitor(_Visitor&& __visitor) {
656
    return __value_visitor_return_type<_Rp, _Visitor>{std::forward<_Visitor>(__visitor)};
657
  }
658
#  endif
659
};
660

661
} // namespace __visitation
662

663
// Adding semi-colons in macro expansions helps clang-format to do a better job.
664
// This macro is used to avoid compilation errors due to "stray" semi-colons.
665
#  define _LIBCPP_EAT_SEMICOLON static_assert(true, "")
666

667
template <size_t _Index, class _Tp>
668
struct _LIBCPP_TEMPLATE_VIS __alt {
669
  using __value_type              = _Tp;
670
  static constexpr size_t __index = _Index;
671

672
  template <class... _Args>
673
  _LIBCPP_HIDE_FROM_ABI explicit constexpr __alt(in_place_t, _Args&&... __args)
674
      : __value(std::forward<_Args>(__args)...) {}
675

676
  __value_type __value;
677
};
678

679
template <_Trait _DestructibleTrait, size_t _Index, class... _Types>
680
union _LIBCPP_TEMPLATE_VIS __union;
681

682
template <_Trait _DestructibleTrait, size_t _Index>
683
union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
684

685
#  define _LIBCPP_VARIANT_UNION(destructible_trait, destructor_definition)                                             \
686
    template <size_t _Index, class _Tp, class... _Types>                                                               \
687
    union _LIBCPP_TEMPLATE_VIS __union<destructible_trait, _Index, _Tp, _Types...> {                                   \
688
    public:                                                                                                            \
689
      _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(__valueless_t) noexcept : __dummy{} {}                          \
690
                                                                                                                       \
691
      template <class... _Args>                                                                                        \
692
      _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(in_place_index_t<0>, _Args&&... __args)                         \
693
          : __head(in_place, std::forward<_Args>(__args)...) {}                                                        \
694
                                                                                                                       \
695
      template <size_t _Ip, class... _Args>                                                                            \
696
      _LIBCPP_HIDE_FROM_ABI explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args)                       \
697
          : __tail(in_place_index<_Ip - 1>, std::forward<_Args>(__args)...) {}                                         \
698
                                                                                                                       \
699
      _LIBCPP_HIDE_FROM_ABI __union(const __union&)            = default;                                              \
700
      _LIBCPP_HIDE_FROM_ABI __union(__union&&)                 = default;                                              \
701
      _LIBCPP_HIDE_FROM_ABI __union& operator=(const __union&) = default;                                              \
702
      _LIBCPP_HIDE_FROM_ABI __union& operator=(__union&&)      = default;                                              \
703
      destructor_definition;                                                                                           \
704
                                                                                                                       \
705
    private:                                                                                                           \
706
      char __dummy;                                                                                                    \
707
      __alt<_Index, _Tp> __head;                                                                                       \
708
      __union<destructible_trait, _Index + 1, _Types...> __tail;                                                       \
709
                                                                                                                       \
710
      friend struct __access::__union;                                                                                 \
711
    }
712

713
_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable,
714
                      _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = default);
715
_LIBCPP_VARIANT_UNION(
716
    _Trait::_Available, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() {} _LIBCPP_EAT_SEMICOLON);
717
_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__union() = delete);
718

719
#  undef _LIBCPP_VARIANT_UNION
720

721
template <_Trait _DestructibleTrait, class... _Types>
722
class _LIBCPP_TEMPLATE_VIS __base {
723
public:
724
  using __index_t = __variant_index_t<sizeof...(_Types)>;
725

726
  _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(__valueless_t __tag) noexcept
727
      : __data(__tag), __index(__variant_npos<__index_t>) {}
728

729
  template <size_t _Ip, class... _Args>
730
  _LIBCPP_HIDE_FROM_ABI explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args)
731
      : __data(in_place_index<_Ip>, std::forward<_Args>(__args)...), __index(_Ip) {}
732

733
  _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept { return index() == variant_npos; }
734

735
  _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept {
736
    return __index == __variant_npos<__index_t> ? variant_npos : __index;
737
  }
738

739
protected:
740
  _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() & { return *this; }
741

742
  _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() && { return std::move(*this); }
743

744
  _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() const& { return *this; }
745

746
  _LIBCPP_HIDE_FROM_ABI constexpr auto&& __as_base() const&& { return std::move(*this); }
747

748
  _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Types); }
749

750
  __union<_DestructibleTrait, 0, _Types...> __data;
751
  __index_t __index;
752

753
  friend struct __access::__base;
754
  friend struct __visitation::__base;
755
};
756

757
template <class _Traits, _Trait = _Traits::__destructible_trait>
758
class _LIBCPP_TEMPLATE_VIS __dtor;
759

760
#  define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor_definition, destroy)                               \
761
    template <class... _Types>                                                                                         \
762
    class _LIBCPP_TEMPLATE_VIS __dtor<__traits<_Types...>, destructible_trait>                                         \
763
        : public __base<destructible_trait, _Types...> {                                                               \
764
      using __base_type = __base<destructible_trait, _Types...>;                                                       \
765
      using __index_t   = typename __base_type::__index_t;                                                             \
766
                                                                                                                       \
767
    public:                                                                                                            \
768
      using __base_type::__base_type;                                                                                  \
769
      using __base_type::operator=;                                                                                    \
770
      _LIBCPP_HIDE_FROM_ABI __dtor(const __dtor&)            = default;                                                \
771
      _LIBCPP_HIDE_FROM_ABI __dtor(__dtor&&)                 = default;                                                \
772
      _LIBCPP_HIDE_FROM_ABI __dtor& operator=(const __dtor&) = default;                                                \
773
      _LIBCPP_HIDE_FROM_ABI __dtor& operator=(__dtor&&)      = default;                                                \
774
      destructor_definition;                                                                                           \
775
                                                                                                                       \
776
    protected:                                                                                                         \
777
      destroy;                                                                                                         \
778
    }
779

780
_LIBCPP_VARIANT_DESTRUCTOR(
781
    _Trait::_TriviallyAvailable,
782
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = default,
783
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept {
784
      this->__index = __variant_npos<__index_t>;
785
    } _LIBCPP_EAT_SEMICOLON);
786

787
_LIBCPP_VARIANT_DESTRUCTOR(
788
    _Trait::_Available,
789
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() { __destroy(); } _LIBCPP_EAT_SEMICOLON,
790
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept {
791
      if (!this->valueless_by_exception()) {
792
        __visitation::__base::__visit_alt(
793
            [](auto& __alt) noexcept {
794
              using __alt_type = __remove_cvref_t<decltype(__alt)>;
795
              __alt.~__alt_type();
796
            },
797
            *this);
798
      }
799
      this->__index = __variant_npos<__index_t>;
800
    } _LIBCPP_EAT_SEMICOLON);
801

802
_LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable,
803
                           _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor()                 = delete,
804
                           _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept = delete);
805

806
#  undef _LIBCPP_VARIANT_DESTRUCTOR
807

808
template <class _Traits>
809
class _LIBCPP_TEMPLATE_VIS __ctor : public __dtor<_Traits> {
810
  using __base_type = __dtor<_Traits>;
811

812
public:
813
  using __base_type::__base_type;
814
  using __base_type::operator=;
815

816
protected:
817
  template <class _Rhs>
818
  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_construct(__ctor& __lhs, _Rhs&& __rhs) {
819
    __lhs.__destroy();
820
    if (!__rhs.valueless_by_exception()) {
821
      auto __rhs_index = __rhs.index();
822
      __visitation::__base::__visit_alt_at(
823
          __rhs_index,
824
          [&__lhs](auto&& __rhs_alt) {
825
            std::__construct_at(std::addressof(__lhs.__data),
826
                                in_place_index<__decay_t<decltype(__rhs_alt)>::__index>,
827
                                std::forward<decltype(__rhs_alt)>(__rhs_alt).__value);
828
          },
829
          std::forward<_Rhs>(__rhs));
830
      __lhs.__index = __rhs_index;
831
    }
832
  }
833
};
834

835
template <class _Traits, _Trait = _Traits::__move_constructible_trait>
836
class _LIBCPP_TEMPLATE_VIS __move_constructor;
837

838
#  define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, move_constructor_definition)                      \
839
    template <class... _Types>                                                                                         \
840
    class _LIBCPP_TEMPLATE_VIS __move_constructor<__traits<_Types...>, move_constructible_trait>                       \
841
        : public __ctor<__traits<_Types...>> {                                                                         \
842
      using __base_type = __ctor<__traits<_Types...>>;                                                                 \
843
                                                                                                                       \
844
    public:                                                                                                            \
845
      using __base_type::__base_type;                                                                                  \
846
      using __base_type::operator=;                                                                                    \
847
                                                                                                                       \
848
      _LIBCPP_HIDE_FROM_ABI __move_constructor(const __move_constructor&)            = default;                        \
849
      _LIBCPP_HIDE_FROM_ABI ~__move_constructor()                                    = default;                        \
850
      _LIBCPP_HIDE_FROM_ABI __move_constructor& operator=(const __move_constructor&) = default;                        \
851
      _LIBCPP_HIDE_FROM_ABI __move_constructor& operator=(__move_constructor&&)      = default;                        \
852
      move_constructor_definition;                                                                                     \
853
    }
854

855
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
856
    _Trait::_TriviallyAvailable,
857
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) = default);
858

859
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
860
    _Trait::_Available,
861
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) noexcept(
862
        __all<is_nothrow_move_constructible_v<_Types>...>::value)
863
    : __move_constructor(__valueless_t{}) {
864
      this->__generic_construct(*this, std::move(__that));
865
    } _LIBCPP_EAT_SEMICOLON);
866

867
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
868
    _Trait::_Unavailable,
869
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&&) = delete);
870

871
#  undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
872

873
template <class _Traits, _Trait = _Traits::__copy_constructible_trait>
874
class _LIBCPP_TEMPLATE_VIS __copy_constructor;
875

876
#  define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, copy_constructor_definition)                      \
877
    template <class... _Types>                                                                                         \
878
    class _LIBCPP_TEMPLATE_VIS __copy_constructor<__traits<_Types...>, copy_constructible_trait>                       \
879
        : public __move_constructor<__traits<_Types...>> {                                                             \
880
      using __base_type = __move_constructor<__traits<_Types...>>;                                                     \
881
                                                                                                                       \
882
    public:                                                                                                            \
883
      using __base_type::__base_type;                                                                                  \
884
      using __base_type::operator=;                                                                                    \
885
                                                                                                                       \
886
      _LIBCPP_HIDE_FROM_ABI __copy_constructor(__copy_constructor&&)                 = default;                        \
887
      _LIBCPP_HIDE_FROM_ABI ~__copy_constructor()                                    = default;                        \
888
      _LIBCPP_HIDE_FROM_ABI __copy_constructor& operator=(const __copy_constructor&) = default;                        \
889
      _LIBCPP_HIDE_FROM_ABI __copy_constructor& operator=(__copy_constructor&&)      = default;                        \
890
      copy_constructor_definition;                                                                                     \
891
    }
892

893
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
894
    _Trait::_TriviallyAvailable,
895
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) = default);
896

897
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
898
    _Trait::_Available,
899
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that)
900
    : __copy_constructor(__valueless_t{}) { this->__generic_construct(*this, __that); } _LIBCPP_EAT_SEMICOLON);
901

902
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
903
    _Trait::_Unavailable,
904
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor&) = delete);
905

906
#  undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
907

908
template <class _Traits>
909
class _LIBCPP_TEMPLATE_VIS __assignment : public __copy_constructor<_Traits> {
910
  using __base_type = __copy_constructor<_Traits>;
911

912
public:
913
  using __base_type::__base_type;
914
  using __base_type::operator=;
915

916
  template <size_t _Ip, class... _Args>
917
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto& __emplace(_Args&&... __args) {
918
    this->__destroy();
919
    std::__construct_at(std::addressof(this->__data), in_place_index<_Ip>, std::forward<_Args>(__args)...);
920
    this->__index = _Ip;
921
    return __access::__base::__get_alt<_Ip>(*this).__value;
922
  }
923

924
protected:
925
  template <size_t _Ip, class _Tp, class _Arg>
926
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_alt(__alt<_Ip, _Tp>& __a, _Arg&& __arg) {
927
    if (this->index() == _Ip) {
928
      __a.__value = std::forward<_Arg>(__arg);
929
    } else {
930
      struct {
931
        _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(true_type) const {
932
          __this->__emplace<_Ip>(std::forward<_Arg>(__arg));
933
        }
934
        _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()(false_type) const {
935
          __this->__emplace<_Ip>(_Tp(std::forward<_Arg>(__arg)));
936
        }
937
        __assignment* __this;
938
        _Arg&& __arg;
939
      } __impl{this, std::forward<_Arg>(__arg)};
940
      __impl(bool_constant < is_nothrow_constructible_v<_Tp, _Arg> || !is_nothrow_move_constructible_v < _Tp >> {});
941
    }
942
  }
943

944
  template <class _That>
945
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __generic_assign(_That&& __that) {
946
    if (this->valueless_by_exception() && __that.valueless_by_exception()) {
947
      // do nothing.
948
    } else if (__that.valueless_by_exception()) {
949
      this->__destroy();
950
    } else {
951
      __visitation::__base::__visit_alt_at(
952
          __that.index(),
953
          [this](auto& __this_alt, auto&& __that_alt) {
954
            this->__assign_alt(__this_alt, std::forward<decltype(__that_alt)>(__that_alt).__value);
955
          },
956
          *this,
957
          std::forward<_That>(__that));
958
    }
959
  }
960
};
961

962
template <class _Traits, _Trait = _Traits::__move_assignable_trait>
963
class _LIBCPP_TEMPLATE_VIS __move_assignment;
964

965
#  define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, move_assignment_definition)                           \
966
    template <class... _Types>                                                                                         \
967
    class _LIBCPP_TEMPLATE_VIS __move_assignment<__traits<_Types...>, move_assignable_trait>                           \
968
        : public __assignment<__traits<_Types...>> {                                                                   \
969
      using __base_type = __assignment<__traits<_Types...>>;                                                           \
970
                                                                                                                       \
971
    public:                                                                                                            \
972
      using __base_type::__base_type;                                                                                  \
973
      using __base_type::operator=;                                                                                    \
974
                                                                                                                       \
975
      _LIBCPP_HIDE_FROM_ABI __move_assignment(const __move_assignment&)            = default;                          \
976
      _LIBCPP_HIDE_FROM_ABI __move_assignment(__move_assignment&&)                 = default;                          \
977
      _LIBCPP_HIDE_FROM_ABI ~__move_assignment()                                   = default;                          \
978
      _LIBCPP_HIDE_FROM_ABI __move_assignment& operator=(const __move_assignment&) = default;                          \
979
      move_assignment_definition;                                                                                      \
980
    }
981

982
_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_TriviallyAvailable,
983
                                _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=(
984
                                    __move_assignment&& __that) = default);
985

986
_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
987
    _Trait::_Available,
988
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment&
989
    operator=(__move_assignment&& __that) noexcept(
990
        __all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_move_assignable_v<_Types>)...>::value) {
991
      this->__generic_assign(std::move(__that));
992
      return *this;
993
    } _LIBCPP_EAT_SEMICOLON);
994

995
_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
996
    _Trait::_Unavailable,
997
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_assignment& operator=(__move_assignment&&) = delete);
998

999
#  undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
1000

1001
template <class _Traits, _Trait = _Traits::__copy_assignable_trait>
1002
class _LIBCPP_TEMPLATE_VIS __copy_assignment;
1003

1004
#  define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, copy_assignment_definition)                           \
1005
    template <class... _Types>                                                                                         \
1006
    class _LIBCPP_TEMPLATE_VIS __copy_assignment<__traits<_Types...>, copy_assignable_trait>                           \
1007
        : public __move_assignment<__traits<_Types...>> {                                                              \
1008
      using __base_type = __move_assignment<__traits<_Types...>>;                                                      \
1009
                                                                                                                       \
1010
    public:                                                                                                            \
1011
      using __base_type::__base_type;                                                                                  \
1012
      using __base_type::operator=;                                                                                    \
1013
                                                                                                                       \
1014
      _LIBCPP_HIDE_FROM_ABI __copy_assignment(const __copy_assignment&)       = default;                               \
1015
      _LIBCPP_HIDE_FROM_ABI __copy_assignment(__copy_assignment&&)            = default;                               \
1016
      _LIBCPP_HIDE_FROM_ABI ~__copy_assignment()                              = default;                               \
1017
      _LIBCPP_HIDE_FROM_ABI __copy_assignment& operator=(__copy_assignment&&) = default;                               \
1018
      copy_assignment_definition;                                                                                      \
1019
    }
1020

1021
_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_TriviallyAvailable,
1022
                                _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=(
1023
                                    const __copy_assignment& __that) = default);
1024

1025
_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1026
    _Trait::_Available,
1027
    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment&
1028
    operator=(const __copy_assignment& __that) {
1029
      this->__generic_assign(__that);
1030
      return *this;
1031
    } _LIBCPP_EAT_SEMICOLON);
1032

1033
_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_Unavailable,
1034
                                _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_assignment& operator=(
1035
                                    const __copy_assignment&) = delete);
1036

1037
#  undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
1038

1039
template <class... _Types>
1040
class _LIBCPP_TEMPLATE_VIS __impl : public __copy_assignment<__traits<_Types...>> {
1041
  using __base_type = __copy_assignment<__traits<_Types...>>;
1042

1043
public:
1044
  using __base_type::__base_type; // get in_place_index_t constructor & friends
1045
  _LIBCPP_HIDE_FROM_ABI __impl(__impl const&)            = default;
1046
  _LIBCPP_HIDE_FROM_ABI __impl(__impl&&)                 = default;
1047
  _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl const&) = default;
1048
  _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl&&)      = default;
1049

1050
  template <size_t _Ip, class _Arg>
1051
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign(_Arg&& __arg) {
1052
    this->__assign_alt(__access::__base::__get_alt<_Ip>(*this), std::forward<_Arg>(__arg));
1053
  }
1054

1055
  inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__impl& __that) {
1056
    if (this->valueless_by_exception() && __that.valueless_by_exception()) {
1057
      // do nothing.
1058
    } else if (this->index() == __that.index()) {
1059
      __visitation::__base::__visit_alt_at(
1060
          this->index(),
1061
          [](auto& __this_alt, auto& __that_alt) {
1062
            using std::swap;
1063
            swap(__this_alt.__value, __that_alt.__value);
1064
          },
1065
          *this,
1066
          __that);
1067
    } else {
1068
      __impl* __lhs = this;
1069
      __impl* __rhs = std::addressof(__that);
1070
      if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) {
1071
        std::swap(__lhs, __rhs);
1072
      }
1073
      __impl __tmp(std::move(*__rhs));
1074
#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
1075
      if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
1076
        this->__generic_construct(*__rhs, std::move(*__lhs));
1077
      } else {
1078
        // EXTENSION: When the move construction of `__lhs` into `__rhs` throws
1079
        // and `__tmp` is nothrow move constructible then we move `__tmp` back
1080
        // into `__rhs` and provide the strong exception safety guarantee.
1081
        try {
1082
          this->__generic_construct(*__rhs, std::move(*__lhs));
1083
        } catch (...) {
1084
          if (__tmp.__move_nothrow()) {
1085
            this->__generic_construct(*__rhs, std::move(__tmp));
1086
          }
1087
          throw;
1088
        }
1089
      }
1090
#  else
1091
      // this isn't consolidated with the `if constexpr` branch above due to
1092
      // `throw` being ill-formed with exceptions disabled even when discarded.
1093
      this->__generic_construct(*__rhs, std::move(*__lhs));
1094
#  endif
1095
      this->__generic_construct(*__lhs, std::move(__tmp));
1096
    }
1097
  }
1098

1099
private:
1100
  constexpr inline _LIBCPP_HIDE_FROM_ABI bool __move_nothrow() const {
1101
    constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...};
1102
    return this->valueless_by_exception() || __results[this->index()];
1103
  }
1104
};
1105

1106
struct __no_narrowing_check {
1107
  template <class _Dest, class _Source>
1108
  using _Apply = __type_identity<_Dest>;
1109
};
1110

1111
struct __narrowing_check {
1112
  template <class _Dest>
1113
  static auto __test_impl(_Dest (&&)[1]) -> __type_identity<_Dest>;
1114
  template <class _Dest, class _Source>
1115
  using _Apply _LIBCPP_NODEBUG = decltype(__test_impl<_Dest>({std::declval<_Source>()}));
1116
};
1117

1118
template <class _Dest, class _Source>
1119
using __check_for_narrowing _LIBCPP_NODEBUG =
1120
    typename _If< is_arithmetic<_Dest>::value, __narrowing_check, __no_narrowing_check >::template _Apply<_Dest,
1121
                                                                                                          _Source>;
1122

1123
template <class _Tp, size_t _Idx>
1124
struct __overload {
1125
  template <class _Up>
1126
  auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
1127
};
1128

1129
template <class... _Bases>
1130
struct __all_overloads : _Bases... {
1131
  void operator()() const;
1132
  using _Bases::operator()...;
1133
};
1134

1135
template <class _IdxSeq>
1136
struct __make_overloads_imp;
1137

1138
template <size_t... _Idx>
1139
struct __make_overloads_imp<__tuple_indices<_Idx...> > {
1140
  template <class... _Types>
1141
  using _Apply _LIBCPP_NODEBUG = __all_overloads<__overload<_Types, _Idx>...>;
1142
};
1143

1144
template <class... _Types>
1145
using _MakeOverloads _LIBCPP_NODEBUG =
1146
    typename __make_overloads_imp< __make_indices_imp<sizeof...(_Types), 0> >::template _Apply<_Types...>;
1147

1148
template <class _Tp, class... _Types>
1149
using __best_match_t = typename invoke_result_t<_MakeOverloads<_Types...>, _Tp, _Tp>::type;
1150

1151
} // namespace __variant_detail
1152

1153
template <class _Visitor, class... _Vs, typename = void_t<decltype(std::__as_variant(std::declval<_Vs>()))...>>
1154
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr decltype(auto)
1155
visit(_Visitor&& __visitor, _Vs&&... __vs);
1156

1157
#  if _LIBCPP_STD_VER >= 20
1158
template <class _Rp,
1159
          class _Visitor,
1160
          class... _Vs,
1161
          typename = void_t<decltype(std::__as_variant(std::declval<_Vs>()))...>>
1162
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp
1163
visit(_Visitor&& __visitor, _Vs&&... __vs);
1164
#  endif
1165

1166
template <class... _Types>
1167
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant
1168
    : private __sfinae_ctor_base< __all<is_copy_constructible_v<_Types>...>::value,
1169
                                  __all<is_move_constructible_v<_Types>...>::value>,
1170
      private __sfinae_assign_base<
1171
          __all<(is_copy_constructible_v<_Types> && is_copy_assignable_v<_Types>)...>::value,
1172
          __all<(is_move_constructible_v<_Types> && is_move_assignable_v<_Types>)...>::value> {
1173
  static_assert(0 < sizeof...(_Types), "variant must consist of at least one alternative.");
1174

1175
  static_assert(__all<!is_array_v<_Types>...>::value, "variant can not have an array type as an alternative.");
1176

1177
  static_assert(__all<!is_reference_v<_Types>...>::value, "variant can not have a reference type as an alternative.");
1178

1179
  static_assert(__all<!is_void_v<_Types>...>::value, "variant can not have a void type as an alternative.");
1180

1181
  using __first_type = variant_alternative_t<0, variant>;
1182

1183
public:
1184
  using __trivially_relocatable =
1185
      conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>;
1186

1187
  template <bool _Dummy                                                                               = true,
1188
            enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0>
1189
  _LIBCPP_HIDE_FROM_ABI constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)
1190
      : __impl_(in_place_index<0>) {}
1191

1192
  _LIBCPP_HIDE_FROM_ABI constexpr variant(const variant&) = default;
1193
  _LIBCPP_HIDE_FROM_ABI constexpr variant(variant&&)      = default;
1194

1195
  template < class _Arg,
1196
             enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int>        = 0,
1197
             enable_if_t<!__is_inplace_type<__remove_cvref_t<_Arg>>::value, int>  = 0,
1198
             enable_if_t<!__is_inplace_index<__remove_cvref_t<_Arg>>::value, int> = 0,
1199
             class _Tp  = __variant_detail::__best_match_t<_Arg, _Types...>,
1200
             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1201
             enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0>
1202
  _LIBCPP_HIDE_FROM_ABI constexpr variant(_Arg&& __arg) noexcept(is_nothrow_constructible_v<_Tp, _Arg>)
1203
      : __impl_(in_place_index<_Ip>, std::forward<_Arg>(__arg)) {}
1204

1205
  template <size_t _Ip,
1206
            class... _Args,
1207
            class                                               = enable_if_t<(_Ip < sizeof...(_Types)), int>,
1208
            class _Tp                                           = variant_alternative_t<_Ip, variant<_Types...>>,
1209
            enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1210
  _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(in_place_index_t<_Ip>, _Args&&... __args) noexcept(
1211
      is_nothrow_constructible_v<_Tp, _Args...>)
1212
      : __impl_(in_place_index<_Ip>, std::forward<_Args>(__args)...) {}
1213

1214
  template < size_t _Ip,
1215
             class _Up,
1216
             class... _Args,
1217
             enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1218
             class _Tp                                   = variant_alternative_t<_Ip, variant<_Types...>>,
1219
             enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
1220
  _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(
1221
      in_place_index_t<_Ip>,
1222
      initializer_list<_Up> __il,
1223
      _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>)
1224
      : __impl_(in_place_index<_Ip>, __il, std::forward<_Args>(__args)...) {}
1225

1226
  template < class _Tp,
1227
             class... _Args,
1228
             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1229
             enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1230
  _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept(
1231
      is_nothrow_constructible_v<_Tp, _Args...>)
1232
      : __impl_(in_place_index<_Ip>, std::forward<_Args>(__args)...) {}
1233

1234
  template < class _Tp,
1235
             class _Up,
1236
             class... _Args,
1237
             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1238
             enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
1239
  _LIBCPP_HIDE_FROM_ABI explicit constexpr variant(
1240
      in_place_type_t<_Tp>,
1241
      initializer_list<_Up> __il,
1242
      _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>)
1243
      : __impl_(in_place_index<_Ip>, __il, std::forward<_Args>(__args)...) {}
1244

1245
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~variant() = default;
1246

1247
  _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(const variant&) = default;
1248
  _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(variant&&)      = default;
1249

1250
  template < class _Arg,
1251
             enable_if_t<!is_same_v<__remove_cvref_t<_Arg>, variant>, int> = 0,
1252
             class _Tp  = __variant_detail::__best_match_t<_Arg, _Types...>,
1253
             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1254
             enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>, int> = 0>
1255
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 variant&
1256
  operator=(_Arg&& __arg) noexcept(is_nothrow_assignable_v<_Tp&, _Arg> && is_nothrow_constructible_v<_Tp, _Arg>) {
1257
    __impl_.template __assign<_Ip>(std::forward<_Arg>(__arg));
1258
    return *this;
1259
  }
1260

1261
  template < size_t _Ip,
1262
             class... _Args,
1263
             enable_if_t<(_Ip < sizeof...(_Types)), int>         = 0,
1264
             class _Tp                                           = variant_alternative_t<_Ip, variant<_Types...>>,
1265
             enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1266
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
1267
    return __impl_.template __emplace<_Ip>(std::forward<_Args>(__args)...);
1268
  }
1269

1270
  template < size_t _Ip,
1271
             class _Up,
1272
             class... _Args,
1273
             enable_if_t<(_Ip < sizeof...(_Types)), int> = 0,
1274
             class _Tp                                   = variant_alternative_t<_Ip, variant<_Types...>>,
1275
             enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
1276
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1277
    return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...);
1278
  }
1279

1280
  template < class _Tp,
1281
             class... _Args,
1282
             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1283
             enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0>
1284
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
1285
    return __impl_.template __emplace<_Ip>(std::forward<_Args>(__args)...);
1286
  }
1287

1288
  template < class _Tp,
1289
             class _Up,
1290
             class... _Args,
1291
             size_t _Ip = __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value,
1292
             enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, int> = 0>
1293
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
1294
    return __impl_.template __emplace<_Ip>(__il, std::forward<_Args>(__args)...);
1295
  }
1296

1297
  _LIBCPP_HIDE_FROM_ABI constexpr bool valueless_by_exception() const noexcept {
1298
    return __impl_.valueless_by_exception();
1299
  }
1300

1301
  _LIBCPP_HIDE_FROM_ABI constexpr size_t index() const noexcept { return __impl_.index(); }
1302

1303
  template < bool _Dummy       = true,
1304
             enable_if_t< __all<(__dependent_type<is_move_constructible<_Types>, _Dummy>::value &&
1305
                                 __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value,
1306
                          int> = 0>
1307
  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(variant& __that) noexcept(
1308
      __all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_swappable_v<_Types>)...>::value) {
1309
    __impl_.__swap(__that.__impl_);
1310
  }
1311

1312
#  if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
1313
  // Helper class to implement [variant.visit]/10
1314
  //   Constraints: The call to visit does not use an explicit template-argument-list
1315
  //   that begins with a type template-argument.
1316
  struct __variant_visit_barrier_tag {
1317
    _LIBCPP_HIDE_FROM_ABI explicit __variant_visit_barrier_tag() = default;
1318
  };
1319

1320
  template <__variant_visit_barrier_tag = __variant_visit_barrier_tag{}, class _Self, class _Visitor>
1321
  _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) visit(this _Self&& __self, _Visitor&& __visitor) {
1322
    using _VariantT = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>;
1323
    return std::visit(std::forward<_Visitor>(__visitor), (_VariantT)__self);
1324
  }
1325

1326
  template <class _Rp, class _Self, class _Visitor>
1327
  _LIBCPP_HIDE_FROM_ABI constexpr _Rp visit(this _Self&& __self, _Visitor&& __visitor) {
1328
    using _VariantT = _OverrideRef<_Self&&, _CopyConst<remove_reference_t<_Self>, variant>>;
1329
    return std::visit<_Rp>(std::forward<_Visitor>(__visitor), (_VariantT)__self);
1330
  }
1331
#  endif
1332

1333
private:
1334
  __variant_detail::__impl<_Types...> __impl_;
1335

1336
  friend struct __variant_detail::__access::__variant;
1337
  friend struct __variant_detail::__visitation::__variant;
1338
};
1339

1340
template <size_t _Ip, class... _Types>
1341
_LIBCPP_HIDE_FROM_ABI constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept {
1342
  return __v.index() == _Ip;
1343
}
1344

1345
template <class _Tp, class... _Types>
1346
_LIBCPP_HIDE_FROM_ABI constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept {
1347
  return std::__holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1348
}
1349

1350
template <size_t _Ip, class _Vp>
1351
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr auto&& __generic_get(_Vp&& __v) {
1352
  using __variant_detail::__access::__variant;
1353
  if (!std::__holds_alternative<_Ip>(__v)) {
1354
    __throw_bad_variant_access();
1355
  }
1356
  return __variant::__get_alt<_Ip>(std::forward<_Vp>(__v)).__value;
1357
}
1358

1359
template <size_t _Ip, class... _Types>
1360
_LIBCPP_HIDE_FROM_ABI
1361
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr variant_alternative_t<_Ip, variant<_Types...>>&
1362
get(variant<_Types...>& __v) {
1363
  static_assert(_Ip < sizeof...(_Types));
1364
  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1365
  return std::__generic_get<_Ip>(__v);
1366
}
1367

1368
template <size_t _Ip, class... _Types>
1369
_LIBCPP_HIDE_FROM_ABI
1370
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr variant_alternative_t<_Ip, variant<_Types...>>&&
1371
get(variant<_Types...>&& __v) {
1372
  static_assert(_Ip < sizeof...(_Types));
1373
  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1374
  return std::__generic_get<_Ip>(std::move(__v));
1375
}
1376

1377
template <size_t _Ip, class... _Types>
1378
_LIBCPP_HIDE_FROM_ABI
1379
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const variant_alternative_t<_Ip, variant<_Types...>>&
1380
get(const variant<_Types...>& __v) {
1381
  static_assert(_Ip < sizeof...(_Types));
1382
  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1383
  return std::__generic_get<_Ip>(__v);
1384
}
1385

1386
template <size_t _Ip, class... _Types>
1387
_LIBCPP_HIDE_FROM_ABI
1388
_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const variant_alternative_t<_Ip, variant<_Types...>>&&
1389
get(const variant<_Types...>&& __v) {
1390
  static_assert(_Ip < sizeof...(_Types));
1391
  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1392
  return std::__generic_get<_Ip>(std::move(__v));
1393
}
1394

1395
template <class _Tp, class... _Types>
1396
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Tp& get(variant<_Types...>& __v) {
1397
  static_assert(!is_void_v<_Tp>);
1398
  return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1399
}
1400

1401
template <class _Tp, class... _Types>
1402
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Tp&& get(variant<_Types...>&& __v) {
1403
  static_assert(!is_void_v<_Tp>);
1404
  return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(std::move(__v));
1405
}
1406

1407
template <class _Tp, class... _Types>
1408
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const _Tp&
1409
get(const variant<_Types...>& __v) {
1410
  static_assert(!is_void_v<_Tp>);
1411
  return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1412
}
1413

1414
template <class _Tp, class... _Types>
1415
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const _Tp&&
1416
get(const variant<_Types...>&& __v) {
1417
  static_assert(!is_void_v<_Tp>);
1418
  return std::get<__find_exactly_one_t<_Tp, _Types...>::value>(std::move(__v));
1419
}
1420

1421
template <size_t _Ip, class _Vp>
1422
_LIBCPP_HIDE_FROM_ABI constexpr auto* __generic_get_if(_Vp* __v) noexcept {
1423
  using __variant_detail::__access::__variant;
1424
  return __v && std::__holds_alternative<_Ip>(*__v) ? std::addressof(__variant::__get_alt<_Ip>(*__v).__value) : nullptr;
1425
}
1426

1427
template <size_t _Ip, class... _Types>
1428
_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>>
1429
get_if(variant<_Types...>* __v) noexcept {
1430
  static_assert(_Ip < sizeof...(_Types));
1431
  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1432
  return std::__generic_get_if<_Ip>(__v);
1433
}
1434

1435
template <size_t _Ip, class... _Types>
1436
_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>>
1437
get_if(const variant<_Types...>* __v) noexcept {
1438
  static_assert(_Ip < sizeof...(_Types));
1439
  static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>);
1440
  return std::__generic_get_if<_Ip>(__v);
1441
}
1442

1443
template <class _Tp, class... _Types>
1444
_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __v) noexcept {
1445
  static_assert(!is_void_v<_Tp>);
1446
  return std::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1447
}
1448

1449
template <class _Tp, class... _Types>
1450
_LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<const _Tp> get_if(const variant<_Types...>* __v) noexcept {
1451
  static_assert(!is_void_v<_Tp>);
1452
  return std::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1453
}
1454

1455
template <class _Operator>
1456
struct __convert_to_bool {
1457
  template <class _T1, class _T2>
1458
  _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_T1&& __t1, _T2&& __t2) const {
1459
    static_assert(is_convertible<decltype(_Operator{}(std::forward<_T1>(__t1), std::forward<_T2>(__t2))), bool>::value,
1460
                  "the relational operator does not return a type which is implicitly convertible to bool");
1461
    return _Operator{}(std::forward<_T1>(__t1), std::forward<_T2>(__t2));
1462
  }
1463
};
1464

1465
template <class... _Types>
1466
_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1467
  using __variant_detail::__visitation::__variant;
1468
  if (__lhs.index() != __rhs.index())
1469
    return false;
1470
  if (__lhs.valueless_by_exception())
1471
    return true;
1472
  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs);
1473
}
1474

1475
#  if _LIBCPP_STD_VER >= 20
1476

1477
template <class... _Types>
1478
  requires(three_way_comparable<_Types> && ...)
1479
_LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...>
1480
operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1481
  using __variant_detail::__visitation::__variant;
1482
  using __result_t = common_comparison_category_t<compare_three_way_result_t<_Types>...>;
1483
  if (__lhs.valueless_by_exception() && __rhs.valueless_by_exception())
1484
    return strong_ordering::equal;
1485
  if (__lhs.valueless_by_exception())
1486
    return strong_ordering::less;
1487
  if (__rhs.valueless_by_exception())
1488
    return strong_ordering::greater;
1489
  if (auto __c = __lhs.index() <=> __rhs.index(); __c != 0)
1490
    return __c;
1491
  auto __three_way = []<class _Type>(const _Type& __v, const _Type& __w) -> __result_t { return __v <=> __w; };
1492
  return __variant::__visit_value_at(__lhs.index(), __three_way, __lhs, __rhs);
1493
}
1494

1495
#  endif // _LIBCPP_STD_VER >= 20
1496

1497
template <class... _Types>
1498
_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1499
  using __variant_detail::__visitation::__variant;
1500
  if (__lhs.index() != __rhs.index())
1501
    return true;
1502
  if (__lhs.valueless_by_exception())
1503
    return false;
1504
  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs);
1505
}
1506

1507
template <class... _Types>
1508
_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1509
  using __variant_detail::__visitation::__variant;
1510
  if (__rhs.valueless_by_exception())
1511
    return false;
1512
  if (__lhs.valueless_by_exception())
1513
    return true;
1514
  if (__lhs.index() < __rhs.index())
1515
    return true;
1516
  if (__lhs.index() > __rhs.index())
1517
    return false;
1518
  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs);
1519
}
1520

1521
template <class... _Types>
1522
_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1523
  using __variant_detail::__visitation::__variant;
1524
  if (__lhs.valueless_by_exception())
1525
    return false;
1526
  if (__rhs.valueless_by_exception())
1527
    return true;
1528
  if (__lhs.index() > __rhs.index())
1529
    return true;
1530
  if (__lhs.index() < __rhs.index())
1531
    return false;
1532
  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs);
1533
}
1534

1535
template <class... _Types>
1536
_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1537
  using __variant_detail::__visitation::__variant;
1538
  if (__lhs.valueless_by_exception())
1539
    return true;
1540
  if (__rhs.valueless_by_exception())
1541
    return false;
1542
  if (__lhs.index() < __rhs.index())
1543
    return true;
1544
  if (__lhs.index() > __rhs.index())
1545
    return false;
1546
  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs);
1547
}
1548

1549
template <class... _Types>
1550
_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) {
1551
  using __variant_detail::__visitation::__variant;
1552
  if (__rhs.valueless_by_exception())
1553
    return true;
1554
  if (__lhs.valueless_by_exception())
1555
    return false;
1556
  if (__lhs.index() > __rhs.index())
1557
    return true;
1558
  if (__lhs.index() < __rhs.index())
1559
    return false;
1560
  return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs);
1561
}
1562

1563
template <class... _Vs>
1564
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr void __throw_if_valueless(_Vs&&... __vs) {
1565
  const bool __valueless = (... || std::__as_variant(__vs).valueless_by_exception());
1566
  if (__valueless) {
1567
    __throw_bad_variant_access();
1568
  }
1569
}
1570

1571
template < class _Visitor, class... _Vs, typename>
1572
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr decltype(auto)
1573
visit(_Visitor&& __visitor, _Vs&&... __vs) {
1574
  using __variant_detail::__visitation::__variant;
1575
  std::__throw_if_valueless(std::forward<_Vs>(__vs)...);
1576
  return __variant::__visit_value(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...);
1577
}
1578

1579
#  if _LIBCPP_STD_VER >= 20
1580
template < class _Rp, class _Visitor, class... _Vs, typename>
1581
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Rp
1582
visit(_Visitor&& __visitor, _Vs&&... __vs) {
1583
  using __variant_detail::__visitation::__variant;
1584
  std::__throw_if_valueless(std::forward<_Vs>(__vs)...);
1585
  return __variant::__visit_value<_Rp>(std::forward<_Visitor>(__visitor), std::forward<_Vs>(__vs)...);
1586
}
1587
#  endif
1588

1589
template <class... _Types>
1590
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto
1591
swap(variant<_Types...>& __lhs,
1592
     variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) -> decltype(__lhs.swap(__rhs)) {
1593
  return __lhs.swap(__rhs);
1594
}
1595

1596
template <class... _Types>
1597
struct _LIBCPP_TEMPLATE_VIS hash< __enable_hash_helper<variant<_Types...>, remove_const_t<_Types>...>> {
1598
  using argument_type = variant<_Types...>;
1599
  using result_type   = size_t;
1600

1601
  _LIBCPP_HIDE_FROM_ABI result_type operator()(const argument_type& __v) const {
1602
    using __variant_detail::__visitation::__variant;
1603
    size_t __res =
1604
        __v.valueless_by_exception()
1605
            ? 299792458 // Random value chosen by the universe upon creation
1606
            : __variant::__visit_alt(
1607
                  [](const auto& __alt) {
1608
                    using __alt_type   = __remove_cvref_t<decltype(__alt)>;
1609
                    using __value_type = remove_const_t< typename __alt_type::__value_type>;
1610
                    return hash<__value_type>{}(__alt.__value);
1611
                  },
1612
                  __v);
1613
    return std::__hash_combine(__res, hash<size_t>{}(__v.index()));
1614
  }
1615
};
1616

1617
// __unchecked_get is the same as std::get, except, it is UB to use it with the wrong
1618
// type whereas std::get will throw or returning nullptr. This makes it faster than
1619
// std::get.
1620
template <size_t _Ip, class _Vp>
1621
_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(_Vp&& __v) noexcept {
1622
  using __variant_detail::__access::__variant;
1623
  return __variant::__get_alt<_Ip>(std::forward<_Vp>(__v)).__value;
1624
}
1625

1626
template <class _Tp, class... _Types>
1627
_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(const variant<_Types...>& __v) noexcept {
1628
  return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1629
}
1630

1631
template <class _Tp, class... _Types>
1632
_LIBCPP_HIDE_FROM_ABI constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept {
1633
  return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v);
1634
}
1635

1636
#endif // _LIBCPP_STD_VER >= 17
1637

1638
_LIBCPP_END_NAMESPACE_STD
1639

1640
_LIBCPP_POP_MACROS
1641

1642
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1643
#  include <exception>
1644
#  include <tuple>
1645
#  include <type_traits>
1646
#  include <typeinfo>
1647
#  include <utility>
1648
#endif
1649

1650
#endif // _LIBCPP_VARIANT
1651

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.