29#ifndef _GLIBCXX_VARIANT
30#define _GLIBCXX_VARIANT 1
33#pragma GCC system_header
36#define __glibcxx_want_freestanding_variant
37#define __glibcxx_want_variant
38#define __glibcxx_want_constrained_equality
41#ifdef __cpp_lib_variant
53#if __cplusplus >= 202002L
59#if __cpp_lib_variant < 202106L
63namespace std _GLIBCXX_VISIBILITY(default)
65_GLIBCXX_BEGIN_NAMESPACE_VERSION
67 template<
typename... _Types>
class tuple;
68 template<
typename... _Types>
class variant;
70 template<
typename _Variant>
73 template<
typename _Variant>
74 struct variant_size<const _Variant> : variant_size<_Variant> {};
76 template<
typename _Variant>
77 struct variant_size<volatile _Variant> : variant_size<_Variant> {};
79 template<
typename _Variant>
80 struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
82 template<
typename... _Types>
83 struct variant_size<variant<_Types...>>
84 : std::integral_constant<size_t, sizeof...(_Types)> {};
86 template<
typename _Variant>
87 inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
89 template<
typename... _Types>
90 inline constexpr size_t
91 variant_size_v<variant<_Types...>> =
sizeof...(_Types);
93 template<
typename... _Types>
94 inline constexpr size_t
95 variant_size_v<
const variant<_Types...>> =
sizeof...(_Types);
97 template<
size_t _Np,
typename _Variant>
98 struct variant_alternative;
100 template<
size_t _Np,
typename... _Types>
101 struct variant_alternative<_Np, variant<_Types...>>
103 static_assert(_Np <
sizeof...(_Types));
105 using type =
typename _Nth_type<_Np, _Types...>::type;
108 template<
size_t _Np,
typename _Variant>
109 using variant_alternative_t =
110 typename variant_alternative<_Np, _Variant>::type;
112 template<
size_t _Np,
typename _Variant>
113 struct variant_alternative<_Np, const _Variant>
114 {
using type =
const variant_alternative_t<_Np, _Variant>; };
116 template<
size_t _Np,
typename _Variant>
117 struct variant_alternative<_Np, volatile _Variant>
118 {
using type =
volatile variant_alternative_t<_Np, _Variant>; };
120 template<
size_t _Np,
typename _Variant>
121 struct variant_alternative<_Np, const volatile _Variant>
122 {
using type =
const volatile variant_alternative_t<_Np, _Variant>; };
124 inline constexpr size_t variant_npos = -1;
126 template<
size_t _Np,
typename... _Types>
127 constexpr variant_alternative_t<_Np, variant<_Types...>>&
128 get(variant<_Types...>&);
130 template<
size_t _Np,
typename... _Types>
131 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
132 get(variant<_Types...>&&);
134 template<
size_t _Np,
typename... _Types>
135 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&
136 get(
const variant<_Types...>&);
138 template<
size_t _Np,
typename... _Types>
139 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&&
140 get(
const variant<_Types...>&&);
142 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
143 constexpr decltype(
auto)
144 __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
146 template <
typename... _Types,
typename _Tp>
149 __variant_cast(_Tp&& __rhs)
151 if constexpr (is_lvalue_reference_v<_Tp>)
153 if constexpr (is_const_v<remove_reference_t<_Tp>>)
154 return static_cast<const variant<_Types...
>&>(__rhs);
156 return static_cast<variant<_Types...
>&>(__rhs);
159 return static_cast<variant<_Types...
>&&>(__rhs);
167 struct __variant_cookie {};
169 struct __variant_idx_cookie {
using type = __variant_idx_cookie; };
171 template<
typename _Tp>
struct __deduce_visit_result {
using type = _Tp; };
174 template<
typename _Visitor,
typename... _Variants>
176 __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
183 template<
typename _Visitor,
typename... _Variants>
185 __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
193 template<
typename... _Types>
194 constexpr std::variant<_Types...>&
195 __as(std::variant<_Types...>& __v)
noexcept
198 template<
typename... _Types>
199 constexpr const std::variant<_Types...>&
200 __as(
const std::variant<_Types...>& __v)
noexcept
203 template<
typename... _Types>
204 constexpr std::variant<_Types...>&&
205 __as(std::variant<_Types...>&& __v)
noexcept
208 template<
typename... _Types>
209 constexpr const std::variant<_Types...>&&
210 __as(
const std::variant<_Types...>&& __v)
noexcept
213#if __cpp_lib_variant < 202106L
214 template<
typename _Type,
bool = std::is_trivially_destructible_v<_Type>>
215 struct _Uninitialized;
217 template<
typename _Type,
bool =
true>
218 struct _Uninitialized;
223 template<
typename _Type,
bool>
224 struct _Uninitialized
226 template<
typename... _Args>
228 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
229 : _M_storage(std::
forward<_Args>(__args)...)
232#if __cpp_lib_variant < 202106L
233 constexpr const _Type& _M_get() const & noexcept
234 {
return _M_storage; }
236 constexpr _Type& _M_get() &
noexcept
237 {
return _M_storage; }
239 constexpr const _Type&& _M_get() const && noexcept
242 constexpr _Type&& _M_get() &&
noexcept
249#if __cpp_lib_variant < 202106L
253 template<
typename _Type>
254 struct _Uninitialized<_Type, false>
256 template<
typename... _Args>
258 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
264 const _Type& _M_get() const & noexcept
265 {
return *_M_storage._M_ptr(); }
267 _Type& _M_get() &
noexcept
268 {
return *_M_storage._M_ptr(); }
270 const _Type&& _M_get() const && noexcept
271 {
return std::move(*_M_storage._M_ptr()); }
273 _Type&& _M_get() &&
noexcept
274 {
return std::move(*_M_storage._M_ptr()); }
276 __gnu_cxx::__aligned_membuf<_Type> _M_storage;
279 template<
size_t _Np,
typename _Union>
280 constexpr decltype(
auto)
281 __get_n(_Union&& __u)
noexcept
283 if constexpr (_Np == 0)
285 else if constexpr (_Np == 1)
287 else if constexpr (_Np == 2)
290 return __variant::__get_n<_Np - 3>(
294 template<
size_t _Np,
typename _Union>
296 __get_n(_Union&& __u)
noexcept
298 if constexpr (_Np == 0)
300 else if constexpr (_Np == 1)
302 else if constexpr (_Np == 2)
305 return __variant::__get_n<_Np - 3>(
311 template<
size_t _Np,
typename _Variant>
312 constexpr decltype(
auto)
313 __get(_Variant&& __v)
noexcept
317 template<
size_t _Np,
typename _Union>
318 constexpr decltype(
auto)
319 __construct_n(_Union& __u)
noexcept
321 if constexpr (_Np == 0)
322 return &__u._M_first;
323 else if constexpr (_Np == 1)
326 return &__u._M_rest._M_first;
328 else if constexpr (_Np == 2)
332 return &__u._M_rest._M_rest._M_first;
339 return __variant::__construct_n<_Np - 3>(__u._M_rest._M_rest._M_rest);
343 template<
typename... _Types>
346 static constexpr bool _S_default_ctor =
347 is_default_constructible_v<
typename _Nth_type<0, _Types...>::type>;
348 static constexpr bool _S_copy_ctor =
349 (is_copy_constructible_v<_Types> && ...);
350 static constexpr bool _S_move_ctor =
351 (is_move_constructible_v<_Types> && ...);
352 static constexpr bool _S_copy_assign =
354 && (is_copy_assignable_v<_Types> && ...);
355 static constexpr bool _S_move_assign =
357 && (is_move_assignable_v<_Types> && ...);
359 static constexpr bool _S_trivial_dtor =
360 (is_trivially_destructible_v<_Types> && ...);
361 static constexpr bool _S_trivial_copy_ctor =
362 (is_trivially_copy_constructible_v<_Types> && ...);
363 static constexpr bool _S_trivial_move_ctor =
364 (is_trivially_move_constructible_v<_Types> && ...);
365 static constexpr bool _S_trivial_copy_assign =
366 _S_trivial_dtor && _S_trivial_copy_ctor
367 && (is_trivially_copy_assignable_v<_Types> && ...);
368 static constexpr bool _S_trivial_move_assign =
369 _S_trivial_dtor && _S_trivial_move_ctor
370 && (is_trivially_move_assignable_v<_Types> && ...);
374 static constexpr bool _S_nothrow_default_ctor =
375 is_nothrow_default_constructible_v<
376 typename _Nth_type<0, _Types...>::type>;
377 static constexpr bool _S_nothrow_copy_ctor =
false;
378 static constexpr bool _S_nothrow_move_ctor =
379 (is_nothrow_move_constructible_v<_Types> && ...);
380 static constexpr bool _S_nothrow_copy_assign =
false;
381 static constexpr bool _S_nothrow_move_assign =
383 && (is_nothrow_move_assignable_v<_Types> && ...);
387 template<
bool __trivially_destructible,
typename... _Types>
388 union _Variadic_union
390 _Variadic_union() =
default;
392 template<
size_t _Np,
typename... _Args>
393 _Variadic_union(in_place_index_t<_Np>, _Args&&...) =
delete;
396 template<
bool __trivially_destructible,
typename _First,
typename... _Rest>
397 union _Variadic_union<__trivially_destructible, _First, _Rest...>
399 constexpr _Variadic_union() : _M_rest() { }
401 template<
typename... _Args>
403 _Variadic_union(in_place_index_t<0>, _Args&&... __args)
404 : _M_first(in_place_index<0>, std::
forward<_Args>(__args)...)
407 template<
size_t _Np,
typename... _Args>
409 _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
410 : _M_rest(in_place_index<_Np-1>, std::
forward<_Args>(__args)...)
413#if __cpp_lib_variant >= 202106L
414 _Variadic_union(
const _Variadic_union&) =
default;
415 _Variadic_union(_Variadic_union&&) =
default;
416 _Variadic_union& operator=(
const _Variadic_union&) =
default;
417 _Variadic_union& operator=(_Variadic_union&&) =
default;
419 ~_Variadic_union() =
default;
424 constexpr ~_Variadic_union()
425 requires (!__trivially_destructible)
429 _Uninitialized<_First> _M_first;
430 _Variadic_union<__trivially_destructible, _Rest...> _M_rest;
438 template<
typename _Tp>
439 struct _Never_valueless_alt
440 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
453 template <typename... _Types>
454 constexpr bool __never_valueless()
456 return _Traits<_Types...>::_S_move_assign
457 && (_Never_valueless_alt<_Types>::value && ...);
461 template<bool __trivially_destructible, typename... _Types>
462 struct _Variant_storage;
464 template <typename... _Types>
465 using __select_index =
466 typename __select_int::_Select_int_base<sizeof...(_Types),
468 unsigned short>::type::value_type;
470 template<typename... _Types>
471 struct _Variant_storage<false, _Types...>
475 : _M_index(static_cast<__index_type>(variant_npos))
478 template<size_t _Np, typename... _Args>
480 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
481 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
488 if (!_M_valid()) [[__unlikely__]]
491 std::__do_visit<void>([](auto&& __this_mem) mutable
493 std::_Destroy(std::__addressof(__this_mem));
494 }, __variant_cast<_Types...>(*this));
496 _M_index = static_cast<__index_type>(variant_npos);
504 _M_valid() const noexcept
506 if constexpr (__variant::__never_valueless<_Types...>())
508 return this->_M_index != __index_type(variant_npos);
511 _Variadic_union<false, _Types...> _M_u;
512 using __index_type = __select_index<_Types...>;
513 __index_type _M_index;
516 template<typename... _Types>
517 struct _Variant_storage<true, _Types...>
521 : _M_index(static_cast<__index_type>(variant_npos))
524 template<
size_t _Np,
typename... _Args>
526 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
527 : _M_u(in_place_index<_Np>, std::
forward<_Args>(__args)...),
533 { _M_index =
static_cast<__index_type
>(variant_npos); }
536 _M_valid() const noexcept
538 if constexpr (__variant::__never_valueless<_Types...>())
546 return this->_M_index !=
static_cast<__index_type
>(variant_npos);
549 _Variadic_union<
true, _Types...> _M_u;
550 using __index_type = __select_index<_Types...>;
551 __index_type _M_index;
555 template<
size_t _Np,
bool _Triv,
typename... _Types,
typename... _Args>
558 __emplace(_Variant_storage<_Triv, _Types...>& __v, _Args&&... __args)
561 auto* __addr = __variant::__construct_n<_Np>(__v._M_u);
568 template<
typename... _Types>
569 using _Variant_storage_alias =
570 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
575 template<bool,
typename... _Types>
576 struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
578 using _Base = _Variant_storage_alias<_Types...>;
582 _Copy_ctor_base(
const _Copy_ctor_base& __rhs)
583 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
585 __variant::__raw_idx_visit(
586 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
588 constexpr size_t __j = __rhs_index;
589 if constexpr (__j != variant_npos)
591 in_place_index<__j>, __rhs_mem);
592 }, __variant_cast<_Types...>(__rhs));
593 this->_M_index = __rhs._M_index;
596 _Copy_ctor_base(_Copy_ctor_base&&) =
default;
597 _Copy_ctor_base& operator=(
const _Copy_ctor_base&) =
default;
598 _Copy_ctor_base& operator=(_Copy_ctor_base&&) =
default;
601 template<
typename... _Types>
602 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
604 using _Base = _Variant_storage_alias<_Types...>;
608 template<
typename... _Types>
609 using _Copy_ctor_alias =
610 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
612 template<bool,
typename... _Types>
613 struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
615 using _Base = _Copy_ctor_alias<_Types...>;
619 _Move_ctor_base(_Move_ctor_base&& __rhs)
620 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
622 __variant::__raw_idx_visit(
623 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
625 constexpr size_t __j = __rhs_index;
626 if constexpr (__j != variant_npos)
630 }, __variant_cast<_Types...>(
std::move(__rhs)));
631 this->_M_index = __rhs._M_index;
634 _Move_ctor_base(
const _Move_ctor_base&) =
default;
635 _Move_ctor_base& operator=(
const _Move_ctor_base&) =
default;
636 _Move_ctor_base& operator=(_Move_ctor_base&&) =
default;
639 template<
typename... _Types>
640 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
642 using _Base = _Copy_ctor_alias<_Types...>;
646 template<
typename... _Types>
647 using _Move_ctor_alias =
648 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
650 template<bool,
typename... _Types>
651 struct _Copy_assign_base : _Move_ctor_alias<_Types...>
653 using _Base = _Move_ctor_alias<_Types...>;
658 operator=(
const _Copy_assign_base& __rhs)
659 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
661 __variant::__raw_idx_visit(
662 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
664 constexpr size_t __j = __rhs_index;
665 if constexpr (__j == variant_npos)
667 else if (this->_M_index == __j)
668 __variant::__get<__j>(*
this) = __rhs_mem;
671 using _Tj =
typename _Nth_type<__j, _Types...>::type;
672 if constexpr (is_nothrow_copy_constructible_v<_Tj>
673 || !is_nothrow_move_constructible_v<_Tj>)
674 __variant::__emplace<__j>(*
this, __rhs_mem);
677 using _Variant = variant<_Types...>;
678 _Variant& __self = __variant_cast<_Types...>(*this);
679 __self = _Variant(in_place_index<__j>, __rhs_mem);
682 }, __variant_cast<_Types...>(__rhs));
686 _Copy_assign_base(
const _Copy_assign_base&) =
default;
687 _Copy_assign_base(_Copy_assign_base&&) =
default;
688 _Copy_assign_base& operator=(_Copy_assign_base&&) =
default;
691 template<
typename... _Types>
692 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
694 using _Base = _Move_ctor_alias<_Types...>;
698 template<
typename... _Types>
699 using _Copy_assign_alias =
700 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
702 template<bool,
typename... _Types>
703 struct _Move_assign_base : _Copy_assign_alias<_Types...>
705 using _Base = _Copy_assign_alias<_Types...>;
710 operator=(_Move_assign_base&& __rhs)
711 noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
713 __variant::__raw_idx_visit(
714 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
716 constexpr size_t __j = __rhs_index;
717 if constexpr (__j != variant_npos)
719 if (this->_M_index == __j)
720 __variant::__get<__j>(*
this) =
std::move(__rhs_mem);
723 using _Tj =
typename _Nth_type<__j, _Types...>::type;
724 if constexpr (is_nothrow_move_constructible_v<_Tj>)
725 __variant::__emplace<__j>(*
this,
std::move(__rhs_mem));
728 using _Variant = variant<_Types...>;
729 _Variant& __self = __variant_cast<_Types...>(*this);
730 __self.template emplace<__j>(
std::move(__rhs_mem));
736 }, __variant_cast<_Types...>(__rhs));
740 _Move_assign_base(
const _Move_assign_base&) =
default;
741 _Move_assign_base(_Move_assign_base&&) =
default;
742 _Move_assign_base& operator=(
const _Move_assign_base&) =
default;
745 template<
typename... _Types>
746 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
748 using _Base = _Copy_assign_alias<_Types...>;
752 template<
typename... _Types>
753 using _Move_assign_alias =
754 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
756 template<
typename... _Types>
757 struct _Variant_base : _Move_assign_alias<_Types...>
759 using _Base = _Move_assign_alias<_Types...>;
762 _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
763 : _Variant_base(in_place_index<0>) { }
765 template<
size_t _Np,
typename... _Args>
767 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
768 : _Base(__i, std::
forward<_Args>(__args)...)
771 _Variant_base(
const _Variant_base&) =
default;
772 _Variant_base(_Variant_base&&) =
default;
773 _Variant_base& operator=(
const _Variant_base&) =
default;
774 _Variant_base& operator=(_Variant_base&&) =
default;
777 template<
typename _Tp,
typename... _Types>
778 inline constexpr bool __exactly_once
779 = std::__find_uniq_type_in_pack<_Tp, _Types...>() <
sizeof...(_Types);
782 template<
typename _Ti>
struct _Arr { _Ti _M_x[1]; };
785 template<
size_t _Ind,
typename _Tp,
typename _Ti,
typename =
void>
790 void _S_fun() =
delete;
794 template<
size_t _Ind,
typename _Tp,
typename _Ti>
795 struct _Build_FUN<_Ind, _Tp, _Ti,
799 static integral_constant<size_t, _Ind> _S_fun(_Ti);
802 template<
typename _Tp,
typename _Variant,
806 template<
typename _Tp,
typename... _Ti,
size_t... _Ind>
808 : _Build_FUN<_Ind, _Tp, _Ti>...
810 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
815 template<
typename _Tp,
typename _Variant>
820 template<
typename _Tp,
typename _Variant,
typename =
void>
821 inline constexpr size_t
822 __accepted_index = variant_npos;
824 template<
typename _Tp,
typename _Variant>
825 inline constexpr size_t
826 __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
827 = _FUN_type<_Tp, _Variant>::value;
829 template<
typename _Maybe_variant_cookie,
typename _Variant,
830 typename = __remove_cvref_t<_Variant>>
831 inline constexpr bool
832 __extra_visit_slot_needed =
false;
834 template<
typename _Var,
typename... _Types>
835 inline constexpr bool
836 __extra_visit_slot_needed<__variant_cookie, _Var, variant<_Types...>>
837 = !__variant::__never_valueless<_Types...>();
839 template<
typename _Var,
typename... _Types>
840 inline constexpr bool
841 __extra_visit_slot_needed<__variant_idx_cookie, _Var, variant<_Types...>>
842 = !__variant::__never_valueless<_Types...>();
845 template<
typename _Tp,
size_t... _Dimensions>
849 template<
typename _Tp>
850 struct _Multi_array<_Tp>
853 struct __untag_result
855 {
using element_type = _Tp; };
857#pragma GCC diagnostic push
858#pragma GCC diagnostic ignored "-Wignored-qualifiers"
859 template <
typename... _Args>
860 struct __untag_result<const void(*)(_Args...)>
862 {
using element_type = void(*)(_Args...); };
863#pragma GCC diagnostic pop
865 template <
typename... _Args>
866 struct __untag_result<__variant_cookie(*)(_Args...)>
868 {
using element_type = void(*)(_Args...); };
870 template <
typename... _Args>
871 struct __untag_result<__variant_idx_cookie(*)(_Args...)>
873 {
using element_type = void(*)(_Args...); };
875 template <
typename _Res,
typename... _Args>
876 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
878 {
using element_type = _Res(*)(_Args...); };
880 using __result_is_deduced = __untag_result<_Tp>;
882 constexpr const typename __untag_result<_Tp>::element_type&
886 typename __untag_result<_Tp>::element_type _M_data;
890 template<
typename _Ret,
892 typename... _Variants,
893 size_t __first,
size_t... __rest>
894 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
896 static constexpr size_t __index =
897 sizeof...(_Variants) -
sizeof...(__rest) - 1;
899 using _Variant =
typename _Nth_type<__index, _Variants...>::type;
901 static constexpr int __do_cookie =
902 __extra_visit_slot_needed<_Ret, _Variant> ? 1 : 0;
904 using _Tp = _Ret(*)(_Visitor, _Variants...);
906 template<
typename... _Args>
907 constexpr decltype(
auto)
908 _M_access(
size_t __first_index, _Args... __rest_indices)
const
910 return _M_arr[__first_index + __do_cookie]
911 ._M_access(__rest_indices...);
914 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
944 template<
typename _Array_type,
typename _Index_seq>
945 struct __gen_vtable_impl;
954 template<
typename _Result_type,
typename _Visitor,
size_t... __dimensions,
955 typename... _Variants,
size_t... __indices>
956 struct __gen_vtable_impl<
957 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
962 _Variants...>::type>;
964 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
967 static constexpr _Array_type
970 _Array_type __vtable{};
976 template<
size_t... __var_indices>
977 static constexpr void
978 _S_apply_all_alts(_Array_type& __vtable,
981 if constexpr (__extra_visit_slot_needed<_Result_type, _Next>)
982 (_S_apply_single_alt<true, __var_indices>(
983 __vtable._M_arr[__var_indices + 1],
984 &(__vtable._M_arr[0])), ...);
986 (_S_apply_single_alt<false, __var_indices>(
987 __vtable._M_arr[__var_indices]), ...);
990 template<
bool __do_cookie,
size_t __index,
typename _Tp>
991 static constexpr void
992 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element =
nullptr)
994 if constexpr (__do_cookie)
996 __element = __gen_vtable_impl<
999 *__cookie_element = __gen_vtable_impl<
1005 auto __tmp_element = __gen_vtable_impl<
1008 static_assert(is_same_v<_Tp,
decltype(__tmp_element)>,
1009 "std::visit requires the visitor to have the same "
1010 "return type for all alternatives of a variant");
1011 __element = __tmp_element;
1019 template<
typename _Result_type,
typename _Visitor,
typename... _Variants,
1020 size_t... __indices>
1021 struct __gen_vtable_impl<
1022 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
1026 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
1028 template<
size_t __index,
typename _Variant>
1029 static constexpr decltype(
auto)
1030 __element_by_index_or_cookie(_Variant&& __var)
noexcept
1032 if constexpr (__index != variant_npos)
1035 return __variant_cookie{};
1038 static constexpr decltype(
auto)
1039 __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1041 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1045 __element_by_index_or_cookie<__indices>(
1047 integral_constant<size_t, __indices>()...);
1048 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1051 __element_by_index_or_cookie<__indices>(
1053 else if constexpr (_Array_type::__result_is_deduced::value)
1056 __element_by_index_or_cookie<__indices>(
1059 return std::__invoke_r<_Result_type>(
1064 static constexpr auto
1067 if constexpr (_Array_type::__result_is_deduced::value)
1069 constexpr bool __visit_ret_type_mismatch =
1070 !is_same_v<
typename _Result_type::type,
1073 if constexpr (__visit_ret_type_mismatch)
1075 struct __cannot_match {};
1076 return __cannot_match{};
1079 return _Array_type{&__visit_invoke};
1082 return _Array_type{&__visit_invoke};
1086 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1090 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1091 variant_size_v<remove_reference_t<_Variants>>...>;
1093 static constexpr _Array_type _S_vtable
1094 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1097#if ! _GLIBCXX_INLINE_VERSION
1098 template<
size_t _Nm,
typename _Tp>
1099 struct _Base_dedup :
public _Tp { };
1101 template<
typename _Variant,
typename __indices>
1102 struct _Variant_hash_base;
1104 template<
typename... _Types,
size_t... __indices>
1105 struct _Variant_hash_base<variant<_Types...>,
1107 : _Base_dedup<__indices, __hash_empty_base<remove_const_t<_Types>>>...
1112 template<
size_t _Np,
typename _Variant,
1116 = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1119 template<
typename _Visitor,
typename... _Variants>
1120 using __visit_result_t
1121 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1123 template<
typename _Tp,
typename... _Types>
1124 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1126 template <
typename _Visitor,
typename _Variant,
size_t... _Idxs>
1129 return __same_types<
1130 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1137 template<
typename _Tp,
typename... _Types>
1139 holds_alternative(
const variant<_Types...>& __v)
noexcept
1141 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1142 "T must occur exactly once in alternatives");
1143 return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>();
1146 template<
typename _Tp,
typename... _Types>
1148 get(variant<_Types...>& __v)
1150 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1151 "T must occur exactly once in alternatives");
1152 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1153 return std::get<__n>(__v);
1156 template<
typename _Tp,
typename... _Types>
1158 get(variant<_Types...>&& __v)
1160 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1161 "T must occur exactly once in alternatives");
1162 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1166 template<
typename _Tp,
typename... _Types>
1167 constexpr const _Tp&
1168 get(
const variant<_Types...>& __v)
1170 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1171 "T must occur exactly once in alternatives");
1172 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1173 return std::get<__n>(__v);
1176 template<
typename _Tp,
typename... _Types>
1177 constexpr const _Tp&&
1178 get(
const variant<_Types...>&& __v)
1180 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1181 "T must occur exactly once in alternatives");
1182 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1186 template<
size_t _Np,
typename... _Types>
1187 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1188 get_if(variant<_Types...>* __ptr)
noexcept
1190 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1191 static_assert(_Np <
sizeof...(_Types),
1192 "The index must be in [0, number of alternatives)");
1193 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1194 if (__ptr && __ptr->index() == _Np)
1199 template<
size_t _Np,
typename... _Types>
1201 add_pointer_t<
const variant_alternative_t<_Np, variant<_Types...>>>
1202 get_if(
const variant<_Types...>* __ptr)
noexcept
1204 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1205 static_assert(_Np <
sizeof...(_Types),
1206 "The index must be in [0, number of alternatives)");
1207 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1208 if (__ptr && __ptr->index() == _Np)
1213 template<
typename _Tp,
typename... _Types>
1215 get_if(variant<_Types...>* __ptr)
noexcept
1217 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1218 "T must occur exactly once in alternatives");
1219 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1220 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1221 return std::get_if<__n>(__ptr);
1224 template<
typename _Tp,
typename... _Types>
1226 get_if(
const variant<_Types...>* __ptr)
noexcept
1228 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1229 "T must occur exactly once in alternatives");
1230 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1231 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1232 return std::get_if<__n>(__ptr);
1235namespace __detail::__variant
1237 template<
typename _Ret,
typename _Vp,
typename _Op>
1239 __compare(_Ret __ret,
const _Vp& __lhs,
const _Vp& __rhs, _Op __op)
1241 __variant::__raw_idx_visit(
1242 [&__ret, &__lhs, __op] (
auto&& __rhs_mem,
auto __rhs_index)
mutable
1244 if constexpr (__rhs_index != variant_npos)
1246 if (__lhs.index() == __rhs_index.value)
1248 auto& __this_mem = std::get<__rhs_index>(__lhs);
1249 __ret = __op(__this_mem, __rhs_mem);
1253 __ret = __op(__lhs.index() + 1, __rhs_index + 1);
1259 template<
typename... _Types>
1260#if __cpp_lib_concepts
1261 requires ((
requires (
const _Types& __t) {
1262 { __t == __t } -> convertible_to<bool>; }) && ...)
1265 operator== [[nodiscard]] (
const variant<_Types...>& __lhs,
1266 const variant<_Types...>& __rhs)
1268 namespace __variant = __detail::__variant;
1269 return __variant::__compare(
true, __lhs, __rhs,
1270 [](
auto&& __l,
auto&& __r) ->
bool {
1275 template<
typename... _Types>
1276#if __cpp_lib_concepts
1277 requires ((
requires (
const _Types& __t) {
1278 { __t != __t } -> convertible_to<bool>; }) && ...)
1281 operator!= [[nodiscard]] (
const variant<_Types...>& __lhs,
1282 const variant<_Types...>& __rhs)
1284 namespace __variant = __detail::__variant;
1285 return __variant::__compare(
true, __lhs, __rhs,
1286 [](
auto&& __l,
auto&& __r) ->
bool {
1291 template<
typename... _Types>
1292#if __cpp_lib_concepts
1293 requires ((
requires (
const _Types& __t) {
1294 { __t < __t } -> convertible_to<bool>; }) && ...)
1297 operator< [[nodiscard]] (
const variant<_Types...>& __lhs,
1298 const variant<_Types...>& __rhs)
1300 namespace __variant = __detail::__variant;
1301 return __variant::__compare(
true, __lhs, __rhs,
1302 [](
auto&& __l,
auto&& __r) ->
bool {
1307 template<
typename... _Types>
1308#if __cpp_lib_concepts
1309 requires ((
requires (
const _Types& __t) {
1310 { __t <= __t } -> convertible_to<bool>; }) && ...)
1313 operator<= [[nodiscard]] (
const variant<_Types...>& __lhs,
1314 const variant<_Types...>& __rhs)
1316 namespace __variant = __detail::__variant;
1317 return __variant::__compare(
true, __lhs, __rhs,
1318 [](
auto&& __l,
auto&& __r) ->
bool {
1323 template<
typename... _Types>
1324#if __cpp_lib_concepts
1325 requires ((
requires (
const _Types& __t) {
1326 { __t > __t } -> convertible_to<bool>; }) && ...)
1329 operator> [[nodiscard]] (
const variant<_Types...>& __lhs,
1330 const variant<_Types...>& __rhs)
1332 namespace __variant = __detail::__variant;
1333 return __variant::__compare(
true, __lhs, __rhs,
1334 [](
auto&& __l,
auto&& __r) ->
bool {
1339 template<
typename... _Types>
1340#if __cpp_lib_concepts
1341 requires ((
requires (
const _Types& __t) {
1342 { __t >= __t } -> convertible_to<bool>; }) && ...)
1345 operator>= [[nodiscard]] (
const variant<_Types...>& __lhs,
1346 const variant<_Types...>& __rhs)
1348 namespace __variant = __detail::__variant;
1349 return __variant::__compare(
true, __lhs, __rhs,
1350 [](
auto&& __l,
auto&& __r) ->
bool {
1355#ifdef __cpp_lib_three_way_comparison
1356 template<
typename... _Types>
1357 requires (three_way_comparable<_Types> && ...)
1359 common_comparison_category_t<compare_three_way_result_t<_Types>...>
1360 operator<=>(
const variant<_Types...>& __v,
const variant<_Types...>& __w)
1362 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1363 = strong_ordering::equal;
1364 namespace __variant = __detail::__variant;
1365 return __variant::__compare(__ret, __v, __w,
1366 [](
auto&& __l,
auto&& __r) {
1372 template<
typename _Visitor,
typename... _Variants>
1373 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1374 visit(_Visitor&&, _Variants&&...);
1376#if __cplusplus > 201703L
1377 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1379 visit(_Visitor&&, _Variants&&...);
1382 template<
typename... _Types>
1383 _GLIBCXX20_CONSTEXPR
1384 inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1385 && (is_swappable_v<_Types> && ...)>
1386 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1387 noexcept(
noexcept(__lhs.swap(__rhs)))
1388 { __lhs.swap(__rhs); }
1390 template<
typename... _Types>
1391 enable_if_t<!((is_move_constructible_v<_Types> && ...)
1392 && (is_swappable_v<_Types> && ...))>
1393 swap(variant<_Types...>&, variant<_Types...>&) =
delete;
1395 [[noreturn]]
void __throw_bad_variant_access(
unsigned);
1397 class bad_variant_access :
public exception
1400 bad_variant_access() noexcept { }
1402 const char* what() const noexcept
override
1403 {
return _M_reason; }
1407 bad_variant_access(
const char* __reason) noexcept : _M_reason(__reason) { }
1410 const char* _M_reason =
"bad variant access";
1412 friend void __throw_bad_variant_access([[maybe_unused]]
unsigned __n)
1414 [[maybe_unused]]
static constexpr const char* __reasons[] = {
1415 "std::get: wrong index for variant",
1416 "std::get: variant is valueless",
1417 "std::visit: variant is valueless",
1418 "std::visit<R>: variant is valueless",
1420 _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__reasons[__n % 4u]));
1424 template<
typename... _Types>
1426 :
private __detail::__variant::_Variant_base<_Types...>,
1427 private _Enable_copy_move<
1428 __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1429 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1430 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1431 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1435 template <
typename... _UTypes,
typename _Tp>
1436 friend _GLIBCXX20_CONSTEXPR
decltype(
auto)
1437 __variant_cast(_Tp&&);
1439 static_assert(
sizeof...(_Types) > 0,
1440 "variant must have at least one alternative");
1441 static_assert(((std::is_object_v<_Types> && !is_array_v<_Types>) && ...),
1442 "variant alternatives must be non-array object types");
1444 using _Base = __detail::__variant::_Variant_base<_Types...>;
1446 template<
typename _Tp>
1447 static constexpr bool __not_self
1448 = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1450 template<
typename _Tp>
1451 static constexpr bool
1452 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1454 template<
typename _Tp>
1455 static constexpr size_t __accepted_index
1456 = __detail::__variant::__accepted_index<_Tp, variant>;
1458 template<
size_t _Np,
typename =
enable_if_t<(_Np <
sizeof...(_Types))>>
1459 using __to_type =
typename _Nth_type<_Np, _Types...>::type;
1461 template<
typename _Tp,
typename = enable_if_t<__not_self<_Tp>>>
1462 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1464 template<
typename _Tp>
1465 static constexpr size_t __index_of
1466 = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1468 using _Traits = __detail::__variant::_Traits<_Types...>;
1470 template<
typename _Tp>
1471 static constexpr bool __not_in_place_tag
1472 = !__is_in_place_type_v<__remove_cvref_t<_Tp>>
1473 && !__is_in_place_index_v<__remove_cvref_t<_Tp>>;
1477 variant()
requires is_default_constructible_v<__to_type<0>> = default;
1479 template<
typename _Tp0 = __to_type<0>,
1480 typename = enable_if_t<is_default_constructible_v<_Tp0>>>
1482 variant() noexcept(is_nothrow_default_constructible_v<__to_type<0>>)
1486 variant(
const variant& __rhs) =
default;
1487 variant(variant&&) =
default;
1488 variant& operator=(
const variant&) =
default;
1489 variant& operator=(variant&&) =
default;
1490 _GLIBCXX20_CONSTEXPR ~variant() =
default;
1492 template<
typename _Tp,
1494 typename = enable_if_t<__not_in_place_tag<_Tp>>,
1495 typename _Tj = __accepted_type<_Tp&&>,
1496 typename = enable_if_t<__exactly_once<_Tj>
1497 && is_constructible_v<_Tj, _Tp>>>
1500 noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1501 : variant(in_place_index<__accepted_index<_Tp>>,
1505 template<
typename _Tp,
typename... _Args,
1506 typename = enable_if_t<__exactly_once<_Tp>
1507 && is_constructible_v<_Tp, _Args...>>>
1509 variant(in_place_type_t<_Tp>, _Args&&... __args)
1510 : variant(in_place_index<__index_of<_Tp>>,
1511 std::
forward<_Args>(__args)...)
1514 template<
typename _Tp,
typename _Up,
typename... _Args,
1515 typename = enable_if_t<__exactly_once<_Tp>
1516 && is_constructible_v<_Tp,
1517 initializer_list<_Up>&, _Args...>>>
1519 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1521 : variant(in_place_index<__index_of<_Tp>>, __il,
1522 std::
forward<_Args>(__args)...)
1525 template<
size_t _Np,
typename... _Args,
1526 typename _Tp = __to_type<_Np>,
1527 typename =
enable_if_t<is_constructible_v<_Tp, _Args...>>>
1529 variant(in_place_index_t<_Np>, _Args&&... __args)
1530 : _Base(in_place_index<_Np>, std::
forward<_Args>(__args)...)
1533 template<
size_t _Np,
typename _Up,
typename... _Args,
1534 typename _Tp = __to_type<_Np>,
1536 initializer_list<_Up>&,
1539 variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1541 : _Base(in_place_index<_Np>, __il, std::
forward<_Args>(__args)...)
1544 template<
typename _Tp>
1545 _GLIBCXX20_CONSTEXPR
1546 enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1547 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1548 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1550 operator=(_Tp&& __rhs)
1551 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1552 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1554 constexpr auto __index = __accepted_index<_Tp>;
1555 if (index() == __index)
1559 using _Tj = __accepted_type<_Tp&&>;
1560 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1561 || !is_nothrow_move_constructible_v<_Tj>)
1571 template<
typename _Tp,
typename... _Args>
1572 _GLIBCXX20_CONSTEXPR
1573 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1575 emplace(_Args&&... __args)
1577 constexpr size_t __index = __index_of<_Tp>;
1581 template<
typename _Tp,
typename _Up,
typename... _Args>
1582 _GLIBCXX20_CONSTEXPR
1583 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1584 && __exactly_once<_Tp>,
1586 emplace(initializer_list<_Up> __il, _Args&&... __args)
1588 constexpr size_t __index = __index_of<_Tp>;
1592 template<
size_t _Np,
typename... _Args>
1593 _GLIBCXX20_CONSTEXPR
1594 enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>,
1596 emplace(_Args&&... __args)
1598 namespace __variant = std::__detail::__variant;
1599 using type =
typename _Nth_type<_Np, _Types...>::type;
1602 if constexpr (is_nothrow_constructible_v<type, _Args...>)
1606 else if constexpr (is_scalar_v<type>)
1611 __variant::__emplace<_Np>(*
this, __tmp);
1613 else if constexpr (__variant::_Never_valueless_alt<type>()
1614 && _Traits::_S_move_assign)
1617 variant __tmp(in_place_index<_Np>,
1628 return std::get<_Np>(*
this);
1631 template<
size_t _Np,
typename _Up,
typename... _Args>
1632 _GLIBCXX20_CONSTEXPR
1633 enable_if_t<is_constructible_v<__to_type<_Np>,
1634 initializer_list<_Up>&, _Args...>,
1636 emplace(initializer_list<_Up> __il, _Args&&... __args)
1638 namespace __variant = std::__detail::__variant;
1639 using type =
typename _Nth_type<_Np, _Types...>::type;
1642 if constexpr (is_nothrow_constructible_v<type,
1643 initializer_list<_Up>&,
1646 __variant::__emplace<_Np>(*
this, __il,
1649 else if constexpr (__variant::_Never_valueless_alt<type>()
1650 && _Traits::_S_move_assign)
1653 variant __tmp(in_place_index<_Np>, __il,
1662 __variant::__emplace<_Np>(*
this, __il,
1665 return std::get<_Np>(*
this);
1668 template<
size_t _Np,
typename... _Args>
1669 enable_if_t<!(_Np <
sizeof...(_Types))> emplace(_Args&&...) =
delete;
1671 template<
typename _Tp,
typename... _Args>
1672 enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) =
delete;
1674 constexpr bool valueless_by_exception() const noexcept
1675 {
return !this->_M_valid(); }
1677 constexpr size_t index() const noexcept
1679 using __index_type =
typename _Base::__index_type;
1680 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1681 return this->_M_index;
1682 else if constexpr (
sizeof...(_Types) <= __index_type(-1) / 2)
1683 return make_signed_t<__index_type>(this->_M_index);
1685 return size_t(__index_type(this->_M_index + 1)) - 1;
1688 _GLIBCXX20_CONSTEXPR
1690 swap(variant& __rhs)
1691 noexcept((__is_nothrow_swappable<_Types>::value && ...)
1692 && is_nothrow_move_constructible_v<variant>)
1694 static_assert((is_move_constructible_v<_Types> && ...));
1697 if (__rhs.valueless_by_exception()) [[__unlikely__]]
1699 if (!this->valueless_by_exception()) [[__likely__]]
1704 namespace __variant = __detail::__variant;
1706 __variant::__raw_idx_visit(
1707 [
this, &__rhs](
auto&& __rhs_mem,
auto __rhs_index)
mutable
1709 constexpr size_t __j = __rhs_index;
1710 if constexpr (__j != variant_npos)
1712 if (this->index() == __j)
1715 swap(std::get<__j>(*
this), __rhs_mem);
1721 if constexpr (_Traits::_S_trivial_move_assign)
1724 __variant::__raw_idx_visit(
1725 [&__rhs](
auto&& __this_mem,
auto __this_index)
mutable
1727 constexpr size_t __k = __this_index;
1728 if constexpr (__k != variant_npos)
1729 __variant::__emplace<__k>(__rhs,
1733 __variant::__emplace<__j>(*
this,
std::move(__tmp));
1739#if __cpp_lib_variant >= 202306L
1749 template<
int = 0,
typename _Self,
typename _Visitor>
1750 constexpr decltype(
auto)
1751 visit(
this _Self&& __self, _Visitor&& __vis)
1753 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1754 const variant, variant>;
1755 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1767 template<
typename _Res,
typename _Self,
typename _Visitor>
1769 visit(
this _Self&& __self, _Visitor&& __vis)
1771 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1772 const variant, variant>;
1773 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1780 template<
size_t _Np,
typename _Vp>
1781 friend constexpr decltype(
auto)
1782 __detail::__variant::__get(_Vp&& __v)
noexcept;
1785 template<
size_t _Np,
typename... _Types>
1786 constexpr variant_alternative_t<_Np, variant<_Types...>>&
1787 get(variant<_Types...>& __v)
1789 static_assert(_Np <
sizeof...(_Types),
1790 "The index must be in [0, number of alternatives)");
1791 if (__v.index() != _Np)
1792 __throw_bad_variant_access(__v.valueless_by_exception());
1793 return __detail::__variant::__get<_Np>(__v);
1796 template<
size_t _Np,
typename... _Types>
1797 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1798 get(variant<_Types...>&& __v)
1800 static_assert(_Np <
sizeof...(_Types),
1801 "The index must be in [0, number of alternatives)");
1802 if (__v.index() != _Np)
1803 __throw_bad_variant_access(__v.valueless_by_exception());
1804 return __detail::__variant::__get<_Np>(
std::move(__v));
1807 template<
size_t _Np,
typename... _Types>
1808 constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1809 get(
const variant<_Types...>& __v)
1811 static_assert(_Np <
sizeof...(_Types),
1812 "The index must be in [0, number of alternatives)");
1813 if (__v.index() != _Np)
1814 __throw_bad_variant_access(__v.valueless_by_exception());
1815 return __detail::__variant::__get<_Np>(__v);
1818 template<
size_t _Np,
typename... _Types>
1819 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1820 get(
const variant<_Types...>&& __v)
1822 static_assert(_Np <
sizeof...(_Types),
1823 "The index must be in [0, number of alternatives)");
1824 if (__v.index() != _Np)
1825 __throw_bad_variant_access(__v.valueless_by_exception());
1826 return __detail::__variant::__get<_Np>(
std::move(__v));
1830 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1831 constexpr decltype(
auto)
1832 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1835 if constexpr (
sizeof...(_Variants) == 0)
1837 if constexpr (is_void_v<_Result_type>)
1844 constexpr size_t __max = 11;
1847 using _V0 =
typename _Nth_type<0, _Variants...>::type;
1849 constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
1851 if constexpr (
sizeof...(_Variants) > 1 || __n > __max)
1854 constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1855 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1857 auto __func_ptr = __vtable._M_access(__variants.index()...);
1865 = [](_V0& __v, ...) -> _V0& {
return __v; }(__variants...);
1867 using __detail::__variant::_Multi_array;
1868 using __detail::__variant::__gen_vtable_impl;
1869 using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0&&)>;
1871#ifdef _GLIBCXX_DEBUG
1872# define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap
1874# define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable
1877#define _GLIBCXX_VISIT_CASE(N) \
1880 if constexpr (N < __n) \
1882 return __gen_vtable_impl<_Ma, index_sequence<N>>:: \
1883 __visit_invoke(std::forward<_Visitor>(__visitor), \
1884 std::forward<_V0>(__v0)); \
1886 else _GLIBCXX_VISIT_UNREACHABLE(); \
1889 switch (__v0.index())
1891 _GLIBCXX_VISIT_CASE(0)
1892 _GLIBCXX_VISIT_CASE(1)
1893 _GLIBCXX_VISIT_CASE(2)
1894 _GLIBCXX_VISIT_CASE(3)
1895 _GLIBCXX_VISIT_CASE(4)
1896 _GLIBCXX_VISIT_CASE(5)
1897 _GLIBCXX_VISIT_CASE(6)
1898 _GLIBCXX_VISIT_CASE(7)
1899 _GLIBCXX_VISIT_CASE(8)
1900 _GLIBCXX_VISIT_CASE(9)
1901 _GLIBCXX_VISIT_CASE(10)
1903 using
__detail::__variant::__variant_idx_cookie;
1904 using
__detail::__variant::__variant_cookie;
1905 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
1906 || is_same_v<_Result_type, __variant_cookie>)
1909 return __gen_vtable_impl<_Ma, _Npos>::
1914 _GLIBCXX_VISIT_UNREACHABLE();
1916 _GLIBCXX_VISIT_UNREACHABLE();
1918#undef _GLIBCXX_VISIT_CASE
1919#undef _GLIBCXX_VISIT_UNREACHABLE
1925 template<
typename _Visitor,
typename... _Variants>
1926 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1927 visit(_Visitor&& __visitor, _Variants&&... __variants)
1929 namespace __variant = std::__detail::__variant;
1931 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1932 __throw_bad_variant_access(2);
1935 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1937 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1939 if constexpr (
sizeof...(_Variants) == 1)
1943 constexpr bool __visit_rettypes_match = __detail::__variant::
1944 __check_visitor_results<_Visitor, _Vp>(
1946 if constexpr (!__visit_rettypes_match)
1948 static_assert(__visit_rettypes_match,
1949 "std::visit requires the visitor to have the same "
1950 "return type for all alternatives of a variant");
1954 return std::__do_visit<_Tag>(
1956 static_cast<_Vp
>(__variants)...);
1959 return std::__do_visit<_Tag>(
1964#if __cplusplus > 201703L
1965 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1967 visit(_Visitor&& __visitor, _Variants&&... __variants)
1969 namespace __variant = std::__detail::__variant;
1971 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1972 __throw_bad_variant_access(3);
1980 template<
typename... _Types>
1981 struct __variant_hash
1983#if __cplusplus < 202002L
1984 using result_type [[__deprecated__]] = size_t;
1985 using argument_type [[__deprecated__]] = variant<_Types...>;
1989 operator()(
const variant<_Types...>& __t)
const
1990 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1993 __detail::__variant::__raw_visit(
1994 [&__t, &__ret](
auto&& __t_mem)
mutable
1996 using _Type = __remove_cvref_t<
decltype(__t_mem)>;
1997 if constexpr (!is_same_v<_Type,
1998 __detail::__variant::__variant_cookie>)
1999 __ret = std::hash<size_t>{}(__t.index())
2000 + std::hash<_Type>{}(__t_mem);
2002 __ret = std::hash<size_t>{}(__t.index());
2009 template<
typename... _Types>
2010 struct hash<variant<_Types...>>
2011 : __conditional_t<(__is_hash_enabled_for<remove_const_t<_Types>> && ...),
2012 __variant_hash<_Types...>,
2013 __hash_not_enabled<variant<_Types...>>>
2014#if ! _GLIBCXX_INLINE_VERSION
2015 , __detail::__variant::_Variant_hash_base<variant<_Types...>,
2016 index_sequence_for<_Types...>>
2020 template<
typename... _Types>
2022 : bool_constant<(__is_fast_hash<_Types>::value && ...)>
2025_GLIBCXX_END_NAMESPACE_VERSION
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
typename remove_reference< _Tp >::type remove_reference_t
Alias template for remove_reference.
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.
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
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.
integer_sequence< size_t, _Idx... > index_sequence
Alias template index_sequence.
constexpr void _Construct(_Tp *__p, _Args &&... __args)
Implementation details not part of the namespace std interface.
Primary class template hash.
Primary class template, tuple.
Base class for all library exceptions.