29#ifndef _GLIBCXX_VARIANT
30#define _GLIBCXX_VARIANT 1
32#pragma GCC system_header
34#define __glibcxx_want_freestanding_variant
35#define __glibcxx_want_variant
36#define __glibcxx_want_constrained_equality
39#ifdef __cpp_lib_variant
50#if __cplusplus >= 202002L
56#if __cpp_lib_variant < 202106L
60namespace std _GLIBCXX_VISIBILITY(default)
62_GLIBCXX_BEGIN_NAMESPACE_VERSION
64 template<
typename... _Types>
class tuple;
65 template<
typename... _Types>
class variant;
66 template <
typename>
struct hash;
68 template<
typename _Variant>
71 template<
typename _Variant>
72 struct variant_size<const _Variant> : variant_size<_Variant> {};
74 template<
typename _Variant>
75 struct variant_size<volatile _Variant> : variant_size<_Variant> {};
77 template<
typename _Variant>
78 struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
80 template<
typename... _Types>
81 struct variant_size<variant<_Types...>>
84 template<
typename _Variant>
85 inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
87 template<
typename... _Types>
88 inline constexpr size_t
89 variant_size_v<variant<_Types...>> =
sizeof...(_Types);
91 template<
typename... _Types>
92 inline constexpr size_t
93 variant_size_v<
const variant<_Types...>> =
sizeof...(_Types);
95 template<
size_t _Np,
typename _Variant>
96 struct variant_alternative;
98 template<
size_t _Np,
typename... _Types>
99 struct variant_alternative<_Np, variant<_Types...>>
101 static_assert(_Np <
sizeof...(_Types));
103 using type =
typename _Nth_type<_Np, _Types...>::type;
106 template<
size_t _Np,
typename _Variant>
107 using variant_alternative_t =
108 typename variant_alternative<_Np, _Variant>::type;
110 template<
size_t _Np,
typename _Variant>
111 struct variant_alternative<_Np, const _Variant>
112 {
using type =
const variant_alternative_t<_Np, _Variant>; };
114 template<
size_t _Np,
typename _Variant>
115 struct variant_alternative<_Np, volatile _Variant>
116 {
using type =
volatile variant_alternative_t<_Np, _Variant>; };
118 template<
size_t _Np,
typename _Variant>
119 struct variant_alternative<_Np, const volatile _Variant>
120 {
using type =
const volatile variant_alternative_t<_Np, _Variant>; };
122 inline constexpr size_t variant_npos = -1;
124 template<
size_t _Np,
typename... _Types>
125 constexpr variant_alternative_t<_Np, variant<_Types...>>&
126 get(variant<_Types...>&);
128 template<
size_t _Np,
typename... _Types>
129 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
130 get(variant<_Types...>&&);
132 template<
size_t _Np,
typename... _Types>
133 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&
134 get(
const variant<_Types...>&);
136 template<
size_t _Np,
typename... _Types>
137 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&&
138 get(
const variant<_Types...>&&);
140 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
141 constexpr decltype(
auto)
142 __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
144 template <
typename... _Types,
typename _Tp>
147 __variant_cast(_Tp&& __rhs)
149 if constexpr (is_lvalue_reference_v<_Tp>)
151 if constexpr (is_const_v<remove_reference_t<_Tp>>)
152 return static_cast<const variant<_Types...
>&>(__rhs);
154 return static_cast<variant<_Types...
>&>(__rhs);
157 return static_cast<variant<_Types...
>&&>(__rhs);
165 struct __variant_cookie {};
167 struct __variant_idx_cookie {
using type = __variant_idx_cookie; };
169 template<
typename _Tp>
struct __deduce_visit_result {
using type = _Tp; };
172 template<
typename _Visitor,
typename... _Variants>
174 __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
176 std::__do_visit<__variant_cookie>(std::forward<_Visitor>(__visitor),
177 std::forward<_Variants>(__variants)...);
181 template<
typename _Visitor,
typename... _Variants>
183 __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
185 std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor),
186 std::forward<_Variants>(__variants)...);
191 template<
typename... _Types>
192 constexpr std::variant<_Types...>&
193 __as(std::variant<_Types...>& __v)
noexcept
196 template<
typename... _Types>
197 constexpr const std::variant<_Types...>&
198 __as(
const std::variant<_Types...>& __v)
noexcept
201 template<
typename... _Types>
202 constexpr std::variant<_Types...>&&
203 __as(std::variant<_Types...>&& __v)
noexcept
206 template<
typename... _Types>
207 constexpr const std::variant<_Types...>&&
208 __as(
const std::variant<_Types...>&& __v)
noexcept
211#if __cpp_lib_variant < 202106L
212 template<
typename _Type,
bool = std::is_trivially_destructible_v<_Type>>
213 struct _Uninitialized;
215 template<
typename _Type,
bool =
true>
216 struct _Uninitialized;
221 template<
typename _Type,
bool>
222 struct _Uninitialized
224 template<
typename... _Args>
226 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
230#if __cpp_lib_variant < 202106L
231 constexpr const _Type& _M_get() const & noexcept
232 {
return _M_storage; }
234 constexpr _Type& _M_get() &
noexcept
235 {
return _M_storage; }
237 constexpr const _Type&& _M_get() const && noexcept
240 constexpr _Type&& _M_get() &&
noexcept
247#if __cpp_lib_variant < 202106L
251 template<
typename _Type>
252 struct _Uninitialized<_Type, false>
254 template<
typename... _Args>
256 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
259 _Type(std::forward<_Args>(__args)...);
262 const _Type& _M_get() const & noexcept
263 {
return *_M_storage._M_ptr(); }
265 _Type& _M_get() &
noexcept
266 {
return *_M_storage._M_ptr(); }
268 const _Type&& _M_get() const && noexcept
269 {
return std::move(*_M_storage._M_ptr()); }
271 _Type&& _M_get() &&
noexcept
272 {
return std::move(*_M_storage._M_ptr()); }
274 __gnu_cxx::__aligned_membuf<_Type> _M_storage;
277 template<
size_t _Np,
typename _Union>
278 constexpr decltype(
auto)
279 __get_n(_Union&& __u)
noexcept
281 if constexpr (_Np == 0)
282 return std::forward<_Union>(__u)._M_first._M_get();
283 else if constexpr (_Np == 1)
284 return std::forward<_Union>(__u)._M_rest._M_first._M_get();
285 else if constexpr (_Np == 2)
286 return std::forward<_Union>(__u)._M_rest._M_rest._M_first._M_get();
288 return __variant::__get_n<_Np - 3>(
289 std::forward<_Union>(__u)._M_rest._M_rest._M_rest);
292 template<
size_t _Np,
typename _Union>
294 __get_n(_Union&& __u)
noexcept
296 if constexpr (_Np == 0)
297 return std::forward<_Union>(__u)._M_first._M_storage;
298 else if constexpr (_Np == 1)
299 return std::forward<_Union>(__u)._M_rest._M_first._M_storage;
300 else if constexpr (_Np == 2)
301 return std::forward<_Union>(__u)._M_rest._M_rest._M_first._M_storage;
303 return __variant::__get_n<_Np - 3>(
304 std::forward<_Union>(__u)._M_rest._M_rest._M_rest);
309 template<
size_t _Np,
typename _Variant>
310 constexpr decltype(
auto)
311 __get(_Variant&& __v)
noexcept
312 {
return __variant::__get_n<_Np>(std::forward<_Variant>(__v)._M_u); }
315 template<
size_t _Np,
typename _Union>
316 constexpr decltype(
auto)
317 __construct_n(_Union& __u)
noexcept
319 if constexpr (_Np == 0)
320 return &__u._M_first;
321 else if constexpr (_Np == 1)
324 return &__u._M_rest._M_first;
326 else if constexpr (_Np == 2)
330 return &__u._M_rest._M_rest._M_first;
337 return __variant::__construct_n<_Np - 3>(__u._M_rest._M_rest._M_rest);
341 template<
typename... _Types>
344 static constexpr bool _S_default_ctor =
345 is_default_constructible_v<
typename _Nth_type<0, _Types...>::type>;
346 static constexpr bool _S_copy_ctor =
347 (is_copy_constructible_v<_Types> && ...);
348 static constexpr bool _S_move_ctor =
349 (is_move_constructible_v<_Types> && ...);
350 static constexpr bool _S_copy_assign =
352 && (is_copy_assignable_v<_Types> && ...);
353 static constexpr bool _S_move_assign =
355 && (is_move_assignable_v<_Types> && ...);
357 static constexpr bool _S_trivial_dtor =
358 (is_trivially_destructible_v<_Types> && ...);
359 static constexpr bool _S_trivial_copy_ctor =
360 (is_trivially_copy_constructible_v<_Types> && ...);
361 static constexpr bool _S_trivial_move_ctor =
362 (is_trivially_move_constructible_v<_Types> && ...);
363 static constexpr bool _S_trivial_copy_assign =
364 _S_trivial_dtor && _S_trivial_copy_ctor
365 && (is_trivially_copy_assignable_v<_Types> && ...);
366 static constexpr bool _S_trivial_move_assign =
367 _S_trivial_dtor && _S_trivial_move_ctor
368 && (is_trivially_move_assignable_v<_Types> && ...);
372 static constexpr bool _S_nothrow_default_ctor =
373 is_nothrow_default_constructible_v<
374 typename _Nth_type<0, _Types...>::type>;
375 static constexpr bool _S_nothrow_copy_ctor =
false;
376 static constexpr bool _S_nothrow_move_ctor =
377 (is_nothrow_move_constructible_v<_Types> && ...);
378 static constexpr bool _S_nothrow_copy_assign =
false;
379 static constexpr bool _S_nothrow_move_assign =
381 && (is_nothrow_move_assignable_v<_Types> && ...);
385 template<
bool __trivially_destructible,
typename... _Types>
386 union _Variadic_union
388 _Variadic_union() =
default;
390 template<
size_t _Np,
typename... _Args>
391 _Variadic_union(in_place_index_t<_Np>, _Args&&...) =
delete;
394 template<
bool __trivially_destructible,
typename _First,
typename... _Rest>
395 union _Variadic_union<__trivially_destructible, _First, _Rest...>
397 constexpr _Variadic_union() : _M_rest() { }
399 template<
typename... _Args>
401 _Variadic_union(in_place_index_t<0>, _Args&&... __args)
402 : _M_first(in_place_index<0>,
std::
forward<_Args>(__args)...)
405 template<
size_t _Np,
typename... _Args>
407 _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
408 : _M_rest(in_place_index<_Np-1>,
std::
forward<_Args>(__args)...)
411#if __cpp_lib_variant >= 202106L
412 _Variadic_union(
const _Variadic_union&) =
default;
413 _Variadic_union(_Variadic_union&&) =
default;
414 _Variadic_union& operator=(
const _Variadic_union&) =
default;
415 _Variadic_union& operator=(_Variadic_union&&) =
default;
417 ~_Variadic_union() =
default;
422 constexpr ~_Variadic_union()
423 requires (!__trivially_destructible)
427 _Uninitialized<_First> _M_first;
428 _Variadic_union<__trivially_destructible, _Rest...> _M_rest;
436 template<
typename _Tp>
437 struct _Never_valueless_alt
438 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
451 template <typename... _Types>
452 constexpr bool __never_valueless()
454 return _Traits<_Types...>::_S_move_assign
455 && (_Never_valueless_alt<_Types>::value && ...);
459 template<bool __trivially_destructible, typename... _Types>
460 struct _Variant_storage;
462 template <typename... _Types>
463 using __select_index =
464 typename __select_int::_Select_int_base<sizeof...(_Types),
466 unsigned short>::type::value_type;
468 template<typename... _Types>
469 struct _Variant_storage<false, _Types...>
473 : _M_index(static_cast<__index_type>(variant_npos))
476 template<size_t _Np, typename... _Args>
478 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
479 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
486 if (!_M_valid()) [[__unlikely__]]
489 std::__do_visit<void>([](auto&& __this_mem) mutable
491 std::_Destroy(std::__addressof(__this_mem));
492 }, __variant_cast<_Types...>(*this));
494 _M_index = static_cast<__index_type>(variant_npos);
502 _M_valid() const noexcept
504 if constexpr (__variant::__never_valueless<_Types...>())
506 return this->_M_index != __index_type(variant_npos);
509 _Variadic_union<false, _Types...> _M_u;
510 using __index_type = __select_index<_Types...>;
511 __index_type _M_index;
514 template<typename... _Types>
515 struct _Variant_storage<true, _Types...>
519 : _M_index(static_cast<__index_type>(variant_npos))
522 template<
size_t _Np,
typename... _Args>
524 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
525 : _M_u(in_place_index<_Np>,
std::
forward<_Args>(__args)...),
531 { _M_index =
static_cast<__index_type
>(variant_npos); }
534 _M_valid() const noexcept
536 if constexpr (__variant::__never_valueless<_Types...>())
544 return this->_M_index !=
static_cast<__index_type
>(variant_npos);
547 _Variadic_union<
true, _Types...> _M_u;
548 using __index_type = __select_index<_Types...>;
549 __index_type _M_index;
553 template<
size_t _Np,
bool _Triv,
typename... _Types,
typename... _Args>
556 __emplace(_Variant_storage<_Triv, _Types...>& __v, _Args&&... __args)
559 auto* __addr = __variant::__construct_n<_Np>(__v._M_u);
561 std::forward<_Args>(__args)...);
566 template<
typename... _Types>
567 using _Variant_storage_alias =
568 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
573 template<bool,
typename... _Types>
574 struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
576 using _Base = _Variant_storage_alias<_Types...>;
580 _Copy_ctor_base(
const _Copy_ctor_base& __rhs)
581 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
583 __variant::__raw_idx_visit(
584 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
586 constexpr size_t __j = __rhs_index;
587 if constexpr (__j != variant_npos)
589 in_place_index<__j>, __rhs_mem);
590 }, __variant_cast<_Types...>(__rhs));
591 this->_M_index = __rhs._M_index;
594 _Copy_ctor_base(_Copy_ctor_base&&) =
default;
595 _Copy_ctor_base& operator=(
const _Copy_ctor_base&) =
default;
596 _Copy_ctor_base& operator=(_Copy_ctor_base&&) =
default;
599 template<
typename... _Types>
600 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
602 using _Base = _Variant_storage_alias<_Types...>;
606 template<
typename... _Types>
607 using _Copy_ctor_alias =
608 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
610 template<bool,
typename... _Types>
611 struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
613 using _Base = _Copy_ctor_alias<_Types...>;
617 _Move_ctor_base(_Move_ctor_base&& __rhs)
618 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
620 __variant::__raw_idx_visit(
621 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
623 constexpr size_t __j = __rhs_index;
624 if constexpr (__j != variant_npos)
628 }, __variant_cast<_Types...>(
std::move(__rhs)));
629 this->_M_index = __rhs._M_index;
632 _Move_ctor_base(
const _Move_ctor_base&) =
default;
633 _Move_ctor_base& operator=(
const _Move_ctor_base&) =
default;
634 _Move_ctor_base& operator=(_Move_ctor_base&&) =
default;
637 template<
typename... _Types>
638 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
640 using _Base = _Copy_ctor_alias<_Types...>;
644 template<
typename... _Types>
645 using _Move_ctor_alias =
646 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
648 template<bool,
typename... _Types>
649 struct _Copy_assign_base : _Move_ctor_alias<_Types...>
651 using _Base = _Move_ctor_alias<_Types...>;
656 operator=(
const _Copy_assign_base& __rhs)
657 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
659 __variant::__raw_idx_visit(
660 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
662 constexpr size_t __j = __rhs_index;
663 if constexpr (__j == variant_npos)
665 else if (this->_M_index == __j)
666 __variant::__get<__j>(*
this) = __rhs_mem;
669 using _Tj =
typename _Nth_type<__j, _Types...>::type;
670 if constexpr (is_nothrow_copy_constructible_v<_Tj>
671 || !is_nothrow_move_constructible_v<_Tj>)
672 __variant::__emplace<__j>(*
this, __rhs_mem);
675 using _Variant = variant<_Types...>;
676 _Variant& __self = __variant_cast<_Types...>(*this);
677 __self = _Variant(in_place_index<__j>, __rhs_mem);
680 }, __variant_cast<_Types...>(__rhs));
684 _Copy_assign_base(
const _Copy_assign_base&) =
default;
685 _Copy_assign_base(_Copy_assign_base&&) =
default;
686 _Copy_assign_base& operator=(_Copy_assign_base&&) =
default;
689 template<
typename... _Types>
690 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
692 using _Base = _Move_ctor_alias<_Types...>;
696 template<
typename... _Types>
697 using _Copy_assign_alias =
698 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
700 template<bool,
typename... _Types>
701 struct _Move_assign_base : _Copy_assign_alias<_Types...>
703 using _Base = _Copy_assign_alias<_Types...>;
708 operator=(_Move_assign_base&& __rhs)
709 noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
711 __variant::__raw_idx_visit(
712 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
714 constexpr size_t __j = __rhs_index;
715 if constexpr (__j != variant_npos)
717 if (this->_M_index == __j)
718 __variant::__get<__j>(*
this) =
std::move(__rhs_mem);
721 using _Tj =
typename _Nth_type<__j, _Types...>::type;
722 if constexpr (is_nothrow_move_constructible_v<_Tj>)
723 __variant::__emplace<__j>(*
this,
std::move(__rhs_mem));
726 using _Variant = variant<_Types...>;
727 _Variant& __self = __variant_cast<_Types...>(*this);
728 __self.template emplace<__j>(
std::move(__rhs_mem));
734 }, __variant_cast<_Types...>(__rhs));
738 _Move_assign_base(
const _Move_assign_base&) =
default;
739 _Move_assign_base(_Move_assign_base&&) =
default;
740 _Move_assign_base& operator=(
const _Move_assign_base&) =
default;
743 template<
typename... _Types>
744 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
746 using _Base = _Copy_assign_alias<_Types...>;
750 template<
typename... _Types>
751 using _Move_assign_alias =
752 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
754 template<
typename... _Types>
755 struct _Variant_base : _Move_assign_alias<_Types...>
757 using _Base = _Move_assign_alias<_Types...>;
760 _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
761 : _Variant_base(in_place_index<0>) { }
763 template<
size_t _Np,
typename... _Args>
765 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
769 _Variant_base(
const _Variant_base&) =
default;
770 _Variant_base(_Variant_base&&) =
default;
771 _Variant_base& operator=(
const _Variant_base&) =
default;
772 _Variant_base& operator=(_Variant_base&&) =
default;
775 template<
typename _Tp,
typename... _Types>
776 inline constexpr bool __exactly_once
777 = std::__find_uniq_type_in_pack<_Tp, _Types...>() <
sizeof...(_Types);
780 template<
typename _Ti>
struct _Arr { _Ti _M_x[1]; };
783 template<
size_t _Ind,
typename _Tp,
typename _Ti,
typename =
void>
788 void _S_fun() =
delete;
792 template<
size_t _Ind,
typename _Tp,
typename _Ti>
793 struct _Build_FUN<_Ind, _Tp, _Ti,
794 void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>>
797 static integral_constant<size_t, _Ind> _S_fun(_Ti);
800 template<
typename _Tp,
typename _Variant,
801 typename = make_index_sequence<variant_size_v<_Variant>>>
804 template<
typename _Tp,
typename... _Ti,
size_t... _Ind>
806 : _Build_FUN<_Ind, _Tp, _Ti>...
808 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
813 template<
typename _Tp,
typename _Variant>
815 =
decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>()));
818 template<
typename _Tp,
typename _Variant,
typename =
void>
819 inline constexpr size_t
820 __accepted_index = variant_npos;
822 template<
typename _Tp,
typename _Variant>
823 inline constexpr size_t
824 __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
825 = _FUN_type<_Tp, _Variant>::value;
827 template<
typename _Maybe_variant_cookie,
typename _Variant,
828 typename = __remove_cvref_t<_Variant>>
829 inline constexpr bool
830 __extra_visit_slot_needed =
false;
832 template<
typename _Var,
typename... _Types>
833 inline constexpr bool
834 __extra_visit_slot_needed<__variant_cookie, _Var, variant<_Types...>>
835 = !__variant::__never_valueless<_Types...>();
837 template<
typename _Var,
typename... _Types>
838 inline constexpr bool
839 __extra_visit_slot_needed<__variant_idx_cookie, _Var, variant<_Types...>>
840 = !__variant::__never_valueless<_Types...>();
843 template<
typename _Tp,
size_t... _Dimensions>
847 template<
typename _Tp>
848 struct _Multi_array<_Tp>
851 struct __untag_result
853 {
using element_type = _Tp; };
855#pragma GCC diagnostic push
856#pragma GCC diagnostic ignored "-Wignored-qualifiers"
857 template <
typename... _Args>
858 struct __untag_result<const void(*)(_Args...)>
860 {
using element_type = void(*)(_Args...); };
861#pragma GCC diagnostic pop
863 template <
typename... _Args>
864 struct __untag_result<__variant_cookie(*)(_Args...)>
866 {
using element_type = void(*)(_Args...); };
868 template <
typename... _Args>
869 struct __untag_result<__variant_idx_cookie(*)(_Args...)>
871 {
using element_type = void(*)(_Args...); };
873 template <
typename _Res,
typename... _Args>
874 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
876 {
using element_type = _Res(*)(_Args...); };
878 using __result_is_deduced = __untag_result<_Tp>;
880 constexpr const typename __untag_result<_Tp>::element_type&
884 typename __untag_result<_Tp>::element_type _M_data;
888 template<
typename _Ret,
890 typename... _Variants,
891 size_t __first,
size_t... __rest>
892 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
894 static constexpr size_t __index =
895 sizeof...(_Variants) -
sizeof...(__rest) - 1;
897 using _Variant =
typename _Nth_type<__index, _Variants...>::type;
899 static constexpr int __do_cookie =
900 __extra_visit_slot_needed<_Ret, _Variant> ? 1 : 0;
902 using _Tp = _Ret(*)(_Visitor, _Variants...);
904 template<
typename... _Args>
905 constexpr decltype(
auto)
906 _M_access(
size_t __first_index, _Args... __rest_indices)
const
908 return _M_arr[__first_index + __do_cookie]
909 ._M_access(__rest_indices...);
912 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
942 template<
typename _Array_type,
typename _Index_seq>
943 struct __gen_vtable_impl;
952 template<
typename _Result_type,
typename _Visitor,
size_t... __dimensions,
953 typename... _Variants,
size_t... __indices>
954 struct __gen_vtable_impl<
955 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
960 _Variants...>::type>;
962 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
965 static constexpr _Array_type
968 _Array_type __vtable{};
974 template<
size_t... __var_indices>
975 static constexpr void
976 _S_apply_all_alts(_Array_type& __vtable,
979 if constexpr (__extra_visit_slot_needed<_Result_type, _Next>)
980 (_S_apply_single_alt<true, __var_indices>(
981 __vtable._M_arr[__var_indices + 1],
982 &(__vtable._M_arr[0])), ...);
984 (_S_apply_single_alt<false, __var_indices>(
985 __vtable._M_arr[__var_indices]), ...);
988 template<
bool __do_cookie,
size_t __index,
typename _Tp>
989 static constexpr void
990 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element =
nullptr)
992 if constexpr (__do_cookie)
994 __element = __gen_vtable_impl<
997 *__cookie_element = __gen_vtable_impl<
1003 auto __tmp_element = __gen_vtable_impl<
1006 static_assert(is_same_v<_Tp,
decltype(__tmp_element)>,
1007 "std::visit requires the visitor to have the same "
1008 "return type for all alternatives of a variant");
1009 __element = __tmp_element;
1017 template<
typename _Result_type,
typename _Visitor,
typename... _Variants,
1018 size_t... __indices>
1019 struct __gen_vtable_impl<
1020 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
1024 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
1026 template<
size_t __index,
typename _Variant>
1027 static constexpr decltype(
auto)
1028 __element_by_index_or_cookie(_Variant&& __var)
noexcept
1030 if constexpr (__index != variant_npos)
1031 return __variant::__get<__index>(std::forward<_Variant>(__var));
1033 return __variant_cookie{};
1036 static constexpr decltype(
auto)
1037 __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1039 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1043 __element_by_index_or_cookie<__indices>(
1044 std::forward<_Variants>(__vars))...,
1045 integral_constant<size_t, __indices>()...);
1046 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1049 __element_by_index_or_cookie<__indices>(
1050 std::forward<_Variants>(__vars))...);
1051 else if constexpr (_Array_type::__result_is_deduced::value)
1054 __element_by_index_or_cookie<__indices>(
1055 std::forward<_Variants>(__vars))...);
1057 return std::__invoke_r<_Result_type>(
1058 std::forward<_Visitor>(__visitor),
1059 __variant::__get<__indices>(std::forward<_Variants>(__vars))...);
1062 static constexpr auto
1065 if constexpr (_Array_type::__result_is_deduced::value)
1067 constexpr bool __visit_ret_type_mismatch =
1068 !is_same_v<
typename _Result_type::type,
1069 decltype(__visit_invoke(std::declval<_Visitor>(),
1070 std::declval<_Variants>()...))>;
1071 if constexpr (__visit_ret_type_mismatch)
1073 struct __cannot_match {};
1074 return __cannot_match{};
1077 return _Array_type{&__visit_invoke};
1080 return _Array_type{&__visit_invoke};
1084 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1088 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1089 variant_size_v<remove_reference_t<_Variants>>...>;
1091 static constexpr _Array_type _S_vtable
1092 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1095 template<
size_t _Np,
typename _Tp>
1096 struct _Base_dedup :
public _Tp { };
1098 template<
typename _Variant,
typename __indices>
1099 struct _Variant_hash_base;
1101 template<
typename... _Types,
size_t... __indices>
1102 struct _Variant_hash_base<variant<_Types...>,
1104 : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
1107 template<
size_t _Np,
typename _Variant,
1108 typename _AsV =
decltype(__variant::__as(std::declval<_Variant>())),
1109 typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>>
1111 = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1114 template<
typename _Visitor,
typename... _Variants>
1115 using __visit_result_t
1116 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1118 template<
typename _Tp,
typename... _Types>
1119 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1121 template <
typename _Visitor,
typename _Variant,
size_t... _Idxs>
1124 return __same_types<
1125 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1132 template<
typename _Tp,
typename... _Types>
1134 holds_alternative(
const variant<_Types...>& __v)
noexcept
1136 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1137 "T must occur exactly once in alternatives");
1138 return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>();
1141 template<
typename _Tp,
typename... _Types>
1143 get(variant<_Types...>& __v)
1145 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1146 "T must occur exactly once in alternatives");
1147 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1148 return std::get<__n>(__v);
1151 template<
typename _Tp,
typename... _Types>
1153 get(variant<_Types...>&& __v)
1155 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1156 "T must occur exactly once in alternatives");
1157 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1161 template<
typename _Tp,
typename... _Types>
1162 constexpr const _Tp&
1163 get(
const variant<_Types...>& __v)
1165 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1166 "T must occur exactly once in alternatives");
1167 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1168 return std::get<__n>(__v);
1171 template<
typename _Tp,
typename... _Types>
1172 constexpr const _Tp&&
1173 get(
const variant<_Types...>&& __v)
1175 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1176 "T must occur exactly once in alternatives");
1177 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1181 template<
size_t _Np,
typename... _Types>
1182 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1183 get_if(variant<_Types...>* __ptr)
noexcept
1185 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1186 static_assert(_Np <
sizeof...(_Types),
1187 "The index must be in [0, number of alternatives)");
1188 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1189 if (__ptr && __ptr->index() == _Np)
1194 template<
size_t _Np,
typename... _Types>
1196 add_pointer_t<
const variant_alternative_t<_Np, variant<_Types...>>>
1197 get_if(
const variant<_Types...>* __ptr)
noexcept
1199 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1200 static_assert(_Np <
sizeof...(_Types),
1201 "The index must be in [0, number of alternatives)");
1202 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1203 if (__ptr && __ptr->index() == _Np)
1208 template<
typename _Tp,
typename... _Types>
1209 constexpr add_pointer_t<_Tp>
1210 get_if(variant<_Types...>* __ptr)
noexcept
1212 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1213 "T must occur exactly once in alternatives");
1214 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1215 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1216 return std::get_if<__n>(__ptr);
1219 template<
typename _Tp,
typename... _Types>
1220 constexpr add_pointer_t<const _Tp>
1221 get_if(
const variant<_Types...>* __ptr)
noexcept
1223 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1224 "T must occur exactly once in alternatives");
1225 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1226 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1227 return std::get_if<__n>(__ptr);
1230 struct monostate { };
1232namespace __detail::__variant
1234 template<
typename _Ret,
typename _Vp,
typename _Op>
1236 __compare(_Ret __ret,
const _Vp& __lhs,
const _Vp& __rhs, _Op __op)
1238 __variant::__raw_idx_visit(
1239 [&__ret, &__lhs, __op] (
auto&& __rhs_mem,
auto __rhs_index)
mutable
1241 if constexpr (__rhs_index != variant_npos)
1243 if (__lhs.index() == __rhs_index.value)
1245 auto& __this_mem = std::get<__rhs_index>(__lhs);
1246 __ret = __op(__this_mem, __rhs_mem);
1250 __ret = __op(__lhs.index() + 1, __rhs_index + 1);
1256 template<
typename... _Types>
1257#if __cpp_lib_concepts
1258 requires ((
requires (
const _Types& __t) {
1259 { __t == __t } -> convertible_to<bool>; }) && ...)
1262 operator== [[nodiscard]] (
const variant<_Types...>& __lhs,
1263 const variant<_Types...>& __rhs)
1265 namespace __variant = __detail::__variant;
1266 return __variant::__compare(
true, __lhs, __rhs,
1267 [](
auto&& __l,
auto&& __r) ->
bool {
1272 template<
typename... _Types>
1273#if __cpp_lib_concepts
1274 requires ((
requires (
const _Types& __t) {
1275 { __t != __t } -> convertible_to<bool>; }) && ...)
1278 operator!= [[nodiscard]] (
const variant<_Types...>& __lhs,
1279 const variant<_Types...>& __rhs)
1281 namespace __variant = __detail::__variant;
1282 return __variant::__compare(
true, __lhs, __rhs,
1283 [](
auto&& __l,
auto&& __r) ->
bool {
1288 template<
typename... _Types>
1289#if __cpp_lib_concepts
1290 requires ((
requires (
const _Types& __t) {
1291 { __t < __t } -> convertible_to<bool>; }) && ...)
1294 operator< [[nodiscard]] (
const variant<_Types...>& __lhs,
1295 const variant<_Types...>& __rhs)
1297 namespace __variant = __detail::__variant;
1298 return __variant::__compare(
true, __lhs, __rhs,
1299 [](
auto&& __l,
auto&& __r) ->
bool {
1304 template<
typename... _Types>
1305#if __cpp_lib_concepts
1306 requires ((
requires (
const _Types& __t) {
1307 { __t <= __t } -> convertible_to<bool>; }) && ...)
1310 operator<= [[nodiscard]] (
const variant<_Types...>& __lhs,
1311 const variant<_Types...>& __rhs)
1313 namespace __variant = __detail::__variant;
1314 return __variant::__compare(
true, __lhs, __rhs,
1315 [](
auto&& __l,
auto&& __r) ->
bool {
1320 template<
typename... _Types>
1321#if __cpp_lib_concepts
1322 requires ((
requires (
const _Types& __t) {
1323 { __t > __t } -> convertible_to<bool>; }) && ...)
1326 operator> [[nodiscard]] (
const variant<_Types...>& __lhs,
1327 const variant<_Types...>& __rhs)
1329 namespace __variant = __detail::__variant;
1330 return __variant::__compare(
true, __lhs, __rhs,
1331 [](
auto&& __l,
auto&& __r) ->
bool {
1336 template<
typename... _Types>
1337#if __cpp_lib_concepts
1338 requires ((
requires (
const _Types& __t) {
1339 { __t >= __t } -> convertible_to<bool>; }) && ...)
1342 operator>= [[nodiscard]] (
const variant<_Types...>& __lhs,
1343 const variant<_Types...>& __rhs)
1345 namespace __variant = __detail::__variant;
1346 return __variant::__compare(
true, __lhs, __rhs,
1347 [](
auto&& __l,
auto&& __r) ->
bool {
1352 constexpr bool operator==(monostate, monostate)
noexcept {
return true; }
1354#ifdef __cpp_lib_three_way_comparison
1355 template<
typename... _Types>
1356 requires (three_way_comparable<_Types> && ...)
1358 common_comparison_category_t<compare_three_way_result_t<_Types>...>
1359 operator<=>(
const variant<_Types...>& __v,
const variant<_Types...>& __w)
1361 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1362 = strong_ordering::equal;
1363 namespace __variant = __detail::__variant;
1364 return __variant::__compare(__ret, __v, __w,
1365 [](
auto&& __l,
auto&& __r) {
1370 constexpr strong_ordering
1371 operator<=>(monostate, monostate)
noexcept {
return strong_ordering::equal; }
1373 constexpr bool operator!=(monostate, monostate)
noexcept {
return false; }
1374 constexpr bool operator<(monostate, monostate)
noexcept {
return false; }
1375 constexpr bool operator>(monostate, monostate)
noexcept {
return false; }
1376 constexpr bool operator<=(monostate, monostate)
noexcept {
return true; }
1377 constexpr bool operator>=(monostate, monostate)
noexcept {
return true; }
1380 template<
typename _Visitor,
typename... _Variants>
1381 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1382 visit(_Visitor&&, _Variants&&...);
1384#if __cplusplus > 201703L
1385 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1387 visit(_Visitor&&, _Variants&&...);
1390 template<
typename... _Types>
1391 _GLIBCXX20_CONSTEXPR
1392 inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1393 && (is_swappable_v<_Types> && ...)>
1394 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1395 noexcept(
noexcept(__lhs.swap(__rhs)))
1396 { __lhs.swap(__rhs); }
1398 template<
typename... _Types>
1399 enable_if_t<!((is_move_constructible_v<_Types> && ...)
1400 && (is_swappable_v<_Types> && ...))>
1401 swap(variant<_Types...>&, variant<_Types...>&) =
delete;
1403 class bad_variant_access :
public exception
1406 bad_variant_access() noexcept { }
1408 const char* what() const noexcept
override
1409 {
return _M_reason; }
1412 bad_variant_access(
const char* __reason) noexcept : _M_reason(__reason) { }
1415 const char* _M_reason =
"bad variant access";
1417 friend void __throw_bad_variant_access(
const char* __what);
1422 __throw_bad_variant_access(
const char* __what)
1423 { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1426 __throw_bad_variant_access(
bool __valueless)
1428 if (__valueless) [[__unlikely__]]
1429 __throw_bad_variant_access(
"std::get: variant is valueless");
1431 __throw_bad_variant_access(
"std::get: wrong index for variant");
1434 template<
typename... _Types>
1436 :
private __detail::__variant::_Variant_base<_Types...>,
1437 private _Enable_copy_move<
1438 __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1439 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1440 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1441 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1445 template <
typename... _UTypes,
typename _Tp>
1446 friend _GLIBCXX20_CONSTEXPR
decltype(
auto)
1447 __variant_cast(_Tp&&);
1449 static_assert(
sizeof...(_Types) > 0,
1450 "variant must have at least one alternative");
1451 static_assert(((std::is_object_v<_Types> && !is_array_v<_Types>) && ...),
1452 "variant alternatives must be non-array object types");
1454 using _Base = __detail::__variant::_Variant_base<_Types...>;
1456 template<
typename _Tp>
1457 static constexpr bool __not_self
1458 = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1460 template<
typename _Tp>
1461 static constexpr bool
1462 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1464 template<
typename _Tp>
1465 static constexpr size_t __accepted_index
1466 = __detail::__variant::__accepted_index<_Tp, variant>;
1468 template<
size_t _Np,
typename =
enable_if_t<(_Np <
sizeof...(_Types))>>
1469 using __to_type =
typename _Nth_type<_Np, _Types...>::type;
1471 template<
typename _Tp,
typename = enable_if_t<__not_self<_Tp>>>
1472 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1474 template<
typename _Tp>
1475 static constexpr size_t __index_of
1476 = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1478 using _Traits = __detail::__variant::_Traits<_Types...>;
1480 template<
typename _Tp>
1481 static constexpr bool __not_in_place_tag
1482 = !__is_in_place_type_v<__remove_cvref_t<_Tp>>
1483 && !__is_in_place_index_v<__remove_cvref_t<_Tp>>;
1487 variant()
requires is_default_constructible_v<__to_type<0>> = default;
1489 template<
typename _Tp0 = __to_type<0>,
1490 typename = enable_if_t<is_default_constructible_v<_Tp0>>>
1492 variant() noexcept(is_nothrow_default_constructible_v<__to_type<0>>)
1496 variant(
const variant& __rhs) =
default;
1497 variant(variant&&) =
default;
1498 variant& operator=(
const variant&) =
default;
1499 variant& operator=(variant&&) =
default;
1500 _GLIBCXX20_CONSTEXPR ~variant() =
default;
1502 template<
typename _Tp,
1504 typename = enable_if_t<__not_in_place_tag<_Tp>>,
1505 typename _Tj = __accepted_type<_Tp&&>,
1506 typename = enable_if_t<__exactly_once<_Tj>
1507 && is_constructible_v<_Tj, _Tp>>>
1510 noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1511 : variant(in_place_index<__accepted_index<_Tp>>,
1515 template<
typename _Tp,
typename... _Args,
1516 typename = enable_if_t<__exactly_once<_Tp>
1517 && is_constructible_v<_Tp, _Args...>>>
1519 variant(in_place_type_t<_Tp>, _Args&&... __args)
1520 : variant(in_place_index<__index_of<_Tp>>,
1524 template<
typename _Tp,
typename _Up,
typename... _Args,
1525 typename = enable_if_t<__exactly_once<_Tp>
1526 && is_constructible_v<_Tp,
1527 initializer_list<_Up>&, _Args...>>>
1529 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1531 : variant(in_place_index<__index_of<_Tp>>, __il,
1535 template<
size_t _Np,
typename... _Args,
1536 typename _Tp = __to_type<_Np>,
1537 typename =
enable_if_t<is_constructible_v<_Tp, _Args...>>>
1539 variant(in_place_index_t<_Np>, _Args&&... __args)
1540 : _Base(in_place_index<_Np>,
std::
forward<_Args>(__args)...)
1543 template<
size_t _Np,
typename _Up,
typename... _Args,
1544 typename _Tp = __to_type<_Np>,
1546 initializer_list<_Up>&,
1549 variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1551 : _Base(in_place_index<_Np>, __il,
std::
forward<_Args>(__args)...)
1554 template<
typename _Tp>
1555 _GLIBCXX20_CONSTEXPR
1556 enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1557 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1558 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1560 operator=(_Tp&& __rhs)
1561 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1562 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1564 constexpr auto __index = __accepted_index<_Tp>;
1565 if (index() == __index)
1566 std::get<__index>(*
this) = std::forward<_Tp>(__rhs);
1569 using _Tj = __accepted_type<_Tp&&>;
1570 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1571 || !is_nothrow_move_constructible_v<_Tj>)
1572 this->emplace<__index>(std::forward<_Tp>(__rhs));
1576 this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs)));
1581 template<
typename _Tp,
typename... _Args>
1582 _GLIBCXX20_CONSTEXPR
1583 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1585 emplace(_Args&&... __args)
1587 constexpr size_t __index = __index_of<_Tp>;
1588 return this->emplace<__index>(std::forward<_Args>(__args)...);
1591 template<
typename _Tp,
typename _Up,
typename... _Args>
1592 _GLIBCXX20_CONSTEXPR
1593 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1594 && __exactly_once<_Tp>,
1596 emplace(initializer_list<_Up> __il, _Args&&... __args)
1598 constexpr size_t __index = __index_of<_Tp>;
1599 return this->emplace<__index>(__il, std::forward<_Args>(__args)...);
1602 template<
size_t _Np,
typename... _Args>
1603 _GLIBCXX20_CONSTEXPR
1604 enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>,
1606 emplace(_Args&&... __args)
1608 namespace __variant = std::__detail::__variant;
1609 using type =
typename _Nth_type<_Np, _Types...>::type;
1612 if constexpr (is_nothrow_constructible_v<type, _Args...>)
1614 __variant::__emplace<_Np>(*
this, std::forward<_Args>(__args)...);
1616 else if constexpr (is_scalar_v<type>)
1619 const type __tmp(std::forward<_Args>(__args)...);
1621 __variant::__emplace<_Np>(*
this, __tmp);
1623 else if constexpr (__variant::_Never_valueless_alt<type>()
1624 && _Traits::_S_move_assign)
1627 variant __tmp(in_place_index<_Np>,
1628 std::forward<_Args>(__args)...);
1636 __variant::__emplace<_Np>(*
this, std::forward<_Args>(__args)...);
1638 return std::get<_Np>(*
this);
1641 template<
size_t _Np,
typename _Up,
typename... _Args>
1642 _GLIBCXX20_CONSTEXPR
1643 enable_if_t<is_constructible_v<__to_type<_Np>,
1644 initializer_list<_Up>&, _Args...>,
1646 emplace(initializer_list<_Up> __il, _Args&&... __args)
1648 namespace __variant = std::__detail::__variant;
1649 using type =
typename _Nth_type<_Np, _Types...>::type;
1652 if constexpr (is_nothrow_constructible_v<type,
1653 initializer_list<_Up>&,
1656 __variant::__emplace<_Np>(*
this, __il,
1657 std::forward<_Args>(__args)...);
1659 else if constexpr (__variant::_Never_valueless_alt<type>()
1660 && _Traits::_S_move_assign)
1663 variant __tmp(in_place_index<_Np>, __il,
1664 std::forward<_Args>(__args)...);
1672 __variant::__emplace<_Np>(*
this, __il,
1673 std::forward<_Args>(__args)...);
1675 return std::get<_Np>(*
this);
1678 template<
size_t _Np,
typename... _Args>
1679 enable_if_t<!(_Np <
sizeof...(_Types))> emplace(_Args&&...) =
delete;
1681 template<
typename _Tp,
typename... _Args>
1682 enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) =
delete;
1684 constexpr bool valueless_by_exception() const noexcept
1685 {
return !this->_M_valid(); }
1687 constexpr size_t index() const noexcept
1689 using __index_type =
typename _Base::__index_type;
1690 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1691 return this->_M_index;
1692 else if constexpr (
sizeof...(_Types) <= __index_type(-1) / 2)
1693 return make_signed_t<__index_type>(this->_M_index);
1695 return size_t(__index_type(this->_M_index + 1)) - 1;
1698 _GLIBCXX20_CONSTEXPR
1700 swap(variant& __rhs)
1701 noexcept((__is_nothrow_swappable<_Types>::value && ...)
1702 && is_nothrow_move_constructible_v<variant>)
1704 static_assert((is_move_constructible_v<_Types> && ...));
1707 if (__rhs.valueless_by_exception()) [[__unlikely__]]
1709 if (!this->valueless_by_exception()) [[__likely__]]
1714 namespace __variant = __detail::__variant;
1716 __variant::__raw_idx_visit(
1717 [
this, &__rhs](
auto&& __rhs_mem,
auto __rhs_index)
mutable
1719 constexpr size_t __j = __rhs_index;
1720 if constexpr (__j != variant_npos)
1722 if (this->index() == __j)
1725 swap(std::get<__j>(*
this), __rhs_mem);
1731 if constexpr (_Traits::_S_trivial_move_assign)
1734 __variant::__raw_idx_visit(
1735 [&__rhs](
auto&& __this_mem,
auto __this_index)
mutable
1737 constexpr size_t __k = __this_index;
1738 if constexpr (__k != variant_npos)
1739 __variant::__emplace<__k>(__rhs,
1743 __variant::__emplace<__j>(*
this,
std::move(__tmp));
1749#if __cpp_lib_variant >= 202306L
1759 template<
int = 0,
typename _Self,
typename _Visitor>
1760 constexpr decltype(
auto)
1761 visit(
this _Self&& __self, _Visitor&& __vis)
1763 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1764 const variant, variant>;
1765 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1767 return std::visit(std::forward<_Visitor>(__vis), (_Var)__self);
1777 template<
typename _Res,
typename _Self,
typename _Visitor>
1779 visit(
this _Self&& __self, _Visitor&& __vis)
1781 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1782 const variant, variant>;
1783 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1785 return std::visit<_Res>(std::forward<_Visitor>(__vis), (_Var)__self);
1790 template<
size_t _Np,
typename _Vp>
1791 friend constexpr decltype(
auto)
1792 __detail::__variant::__get(_Vp&& __v)
noexcept;
1795 template<
size_t _Np,
typename... _Types>
1796 constexpr variant_alternative_t<_Np, variant<_Types...>>&
1797 get(variant<_Types...>& __v)
1799 static_assert(_Np <
sizeof...(_Types),
1800 "The index must be in [0, number of alternatives)");
1801 if (__v.index() != _Np)
1802 __throw_bad_variant_access(__v.valueless_by_exception());
1803 return __detail::__variant::__get<_Np>(__v);
1806 template<
size_t _Np,
typename... _Types>
1807 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1808 get(variant<_Types...>&& __v)
1810 static_assert(_Np <
sizeof...(_Types),
1811 "The index must be in [0, number of alternatives)");
1812 if (__v.index() != _Np)
1813 __throw_bad_variant_access(__v.valueless_by_exception());
1814 return __detail::__variant::__get<_Np>(
std::move(__v));
1817 template<
size_t _Np,
typename... _Types>
1818 constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1819 get(
const variant<_Types...>& __v)
1821 static_assert(_Np <
sizeof...(_Types),
1822 "The index must be in [0, number of alternatives)");
1823 if (__v.index() != _Np)
1824 __throw_bad_variant_access(__v.valueless_by_exception());
1825 return __detail::__variant::__get<_Np>(__v);
1828 template<
size_t _Np,
typename... _Types>
1829 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1830 get(
const variant<_Types...>&& __v)
1832 static_assert(_Np <
sizeof...(_Types),
1833 "The index must be in [0, number of alternatives)");
1834 if (__v.index() != _Np)
1835 __throw_bad_variant_access(__v.valueless_by_exception());
1836 return __detail::__variant::__get<_Np>(
std::move(__v));
1840 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1841 constexpr decltype(
auto)
1842 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1845 if constexpr (
sizeof...(_Variants) == 0)
1847 if constexpr (is_void_v<_Result_type>)
1848 return (
void) std::forward<_Visitor>(__visitor)();
1850 return std::forward<_Visitor>(__visitor)();
1854 constexpr size_t __max = 11;
1857 using _V0 =
typename _Nth_type<0, _Variants...>::type;
1859 constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
1861 if constexpr (
sizeof...(_Variants) > 1 || __n > __max)
1864 constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1865 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1867 auto __func_ptr = __vtable._M_access(__variants.index()...);
1868 return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1869 std::forward<_Variants>(__variants)...);
1875 = [](_V0& __v, ...) -> _V0& {
return __v; }(__variants...);
1877 using __detail::__variant::_Multi_array;
1878 using __detail::__variant::__gen_vtable_impl;
1879 using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0&&)>;
1881#ifdef _GLIBCXX_DEBUG
1882# define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap
1884# define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable
1887#define _GLIBCXX_VISIT_CASE(N) \
1890 if constexpr (N < __n) \
1892 return __gen_vtable_impl<_Ma, index_sequence<N>>:: \
1893 __visit_invoke(std::forward<_Visitor>(__visitor), \
1894 std::forward<_V0>(__v0)); \
1896 else _GLIBCXX_VISIT_UNREACHABLE(); \
1899 switch (__v0.index())
1901 _GLIBCXX_VISIT_CASE(0)
1902 _GLIBCXX_VISIT_CASE(1)
1903 _GLIBCXX_VISIT_CASE(2)
1904 _GLIBCXX_VISIT_CASE(3)
1905 _GLIBCXX_VISIT_CASE(4)
1906 _GLIBCXX_VISIT_CASE(5)
1907 _GLIBCXX_VISIT_CASE(6)
1908 _GLIBCXX_VISIT_CASE(7)
1909 _GLIBCXX_VISIT_CASE(8)
1910 _GLIBCXX_VISIT_CASE(9)
1911 _GLIBCXX_VISIT_CASE(10)
1913 using __detail::__variant::__variant_idx_cookie;
1914 using __detail::__variant::__variant_cookie;
1915 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
1916 || is_same_v<_Result_type, __variant_cookie>)
1918 using _Npos = index_sequence<variant_npos>;
1919 return __gen_vtable_impl<_Ma, _Npos>::
1920 __visit_invoke(std::forward<_Visitor>(__visitor),
1921 std::forward<_V0>(__v0));
1924 _GLIBCXX_VISIT_UNREACHABLE();
1926 _GLIBCXX_VISIT_UNREACHABLE();
1928#undef _GLIBCXX_VISIT_CASE
1929#undef _GLIBCXX_VISIT_UNREACHABLE
1935 template<
typename _Visitor,
typename... _Variants>
1936 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1937 visit(_Visitor&& __visitor, _Variants&&... __variants)
1939 namespace __variant = std::__detail::__variant;
1941 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1942 __throw_bad_variant_access(
"std::visit: variant is valueless");
1945 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1947 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1949 if constexpr (
sizeof...(_Variants) == 1)
1951 using _Vp =
decltype(__variant::__as(std::declval<_Variants>()...));
1953 constexpr bool __visit_rettypes_match = __detail::__variant::
1954 __check_visitor_results<_Visitor, _Vp>(
1956 if constexpr (!__visit_rettypes_match)
1958 static_assert(__visit_rettypes_match,
1959 "std::visit requires the visitor to have the same "
1960 "return type for all alternatives of a variant");
1964 return std::__do_visit<_Tag>(
1965 std::forward<_Visitor>(__visitor),
1966 static_cast<_Vp
>(__variants)...);
1969 return std::__do_visit<_Tag>(
1970 std::forward<_Visitor>(__visitor),
1971 __variant::__as(std::forward<_Variants>(__variants))...);
1974#if __cplusplus > 201703L
1975 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1977 visit(_Visitor&& __visitor, _Variants&&... __variants)
1979 namespace __variant = std::__detail::__variant;
1981 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1982 __throw_bad_variant_access(
"std::visit<R>: variant is valueless");
1984 return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor),
1985 __variant::__as(std::forward<_Variants>(__variants))...);
1990 template<bool,
typename... _Types>
1991 struct __variant_hash_call_base_impl
1994 operator()(
const variant<_Types...>& __t)
const
1995 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1998 __detail::__variant::__raw_visit(
1999 [&__t, &__ret](
auto&& __t_mem)
mutable
2001 using _Type = __remove_cvref_t<
decltype(__t_mem)>;
2002 if constexpr (!is_same_v<_Type,
2003 __detail::__variant::__variant_cookie>)
2013 template<
typename... _Types>
2014 struct __variant_hash_call_base_impl<false, _Types...> {};
2016 template<
typename... _Types>
2017 using __variant_hash_call_base =
2018 __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
2019 __enable_hash_call &&...), _Types...>;
2022 template<
typename... _Types>
2023 struct hash<variant<_Types...>>
2024 :
private __detail::__variant::_Variant_hash_base<
2025 variant<_Types...>, std::index_sequence_for<_Types...>>,
2026 public __variant_hash_call_base<_Types...>
2028 using result_type [[__deprecated__]] = size_t;
2029 using argument_type [[__deprecated__]] = variant<_Types...>;
2033 struct hash<monostate>
2035 using result_type [[__deprecated__]] = size_t;
2036 using argument_type [[__deprecated__]] = monostate;
2039 operator()(
const monostate&)
const noexcept
2041 constexpr size_t __magic_monostate_hash = -7777;
2042 return __magic_monostate_hash;
2046 template<
typename... _Types>
2047 struct __is_fast_hash<hash<variant<_Types...>>>
2048 : bool_constant<(__is_fast_hash<_Types>::value && ...)>
2051_GLIBCXX_END_NAMESPACE_VERSION
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
typename remove_reference< _Tp >::type remove_reference_t
Alias template for remove_reference.
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
typename add_pointer< _Tp >::type add_pointer_t
Alias template for add_pointer.
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
constexpr _Tp * addressof(_Tp &__r) noexcept
Returns the actual address of the object or function referenced by r, even in the presence of an over...
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
void void_t
A metafunction that always yields void, used for detecting valid types.
ISO C++ entities toplevel namespace is std.
make_integer_sequence< size_t, _Num > make_index_sequence
Alias template make_index_sequence.
constexpr void _Construct(_Tp *__p, _Args &&... __args)
integer_sequence< size_t, _Idx... > index_sequence
Alias template index_sequence.
Primary class template hash.
Class template integer_sequence.