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<
typename _First,
typename... _Rest>
397 union _Variadic_union<true, _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 _Uninitialized<_First> _M_first;
414 _Variadic_union<
true, _Rest...> _M_rest;
417 template<
typename _First,
typename... _Rest>
418 union _Variadic_union<false, _First, _Rest...>
420 constexpr _Variadic_union() : _M_rest() { }
422 template<
typename... _Args>
424 _Variadic_union(in_place_index_t<0>, _Args&&... __args)
425 : _M_first(in_place_index<0>, std::
forward<_Args>(__args)...)
428 template<
size_t _Np,
typename... _Args>
430 _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
431 : _M_rest(in_place_index<_Np-1>, std::
forward<_Args>(__args)...)
434 _Variadic_union(
const _Variadic_union&) =
default;
435 _Variadic_union(_Variadic_union&&) =
default;
436 _Variadic_union& operator=(
const _Variadic_union&) =
default;
437 _Variadic_union& operator=(_Variadic_union&&) =
default;
442 _GLIBCXX20_CONSTEXPR ~_Variadic_union()
445 _Uninitialized<_First> _M_first;
446 _Variadic_union<(is_trivially_destructible_v<_Rest> && ...), _Rest...> _M_rest;
454 template<
typename _Tp>
455 struct _Never_valueless_alt
456 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
469 template <typename... _Types>
470 constexpr bool __never_valueless()
472 return _Traits<_Types...>::_S_move_assign
473 && (_Never_valueless_alt<_Types>::value && ...);
477 template<bool __trivially_destructible, typename... _Types>
478 struct _Variant_storage;
480 template <typename... _Types>
481 using __select_index =
482 typename __select_int::_Select_int_base<sizeof...(_Types),
484 unsigned short>::type::value_type;
486 template<typename... _Types>
487 struct _Variant_storage<false, _Types...>
491 : _M_index(static_cast<__index_type>(variant_npos))
494 template<size_t _Np, typename... _Args>
496 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
497 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
504 if (!_M_valid()) [[__unlikely__]]
507 std::__do_visit<void>([](auto&& __this_mem) mutable
509 std::_Destroy(std::__addressof(__this_mem));
510 }, __variant_cast<_Types...>(*this));
512 _M_index = static_cast<__index_type>(variant_npos);
520 _M_valid() const noexcept
522 if constexpr (__variant::__never_valueless<_Types...>())
524 return this->_M_index != __index_type(variant_npos);
527 _Variadic_union<false, _Types...> _M_u;
528 using __index_type = __select_index<_Types...>;
529 __index_type _M_index;
532 template<typename... _Types>
533 struct _Variant_storage<true, _Types...>
537 : _M_index(static_cast<__index_type>(variant_npos))
540 template<
size_t _Np,
typename... _Args>
542 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
543 : _M_u(in_place_index<_Np>, std::
forward<_Args>(__args)...),
549 { _M_index =
static_cast<__index_type
>(variant_npos); }
552 _M_valid() const noexcept
554 if constexpr (__variant::__never_valueless<_Types...>())
562 return this->_M_index !=
static_cast<__index_type
>(variant_npos);
565 _Variadic_union<
true, _Types...> _M_u;
566 using __index_type = __select_index<_Types...>;
567 __index_type _M_index;
571 template<
size_t _Np,
bool _Triv,
typename... _Types,
typename... _Args>
574 __emplace(_Variant_storage<_Triv, _Types...>& __v, _Args&&... __args)
577 auto* __addr = __variant::__construct_n<_Np>(__v._M_u);
584 template<
typename... _Types>
585 using _Variant_storage_alias =
586 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
591 template<bool,
typename... _Types>
592 struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
594 using _Base = _Variant_storage_alias<_Types...>;
598 _Copy_ctor_base(
const _Copy_ctor_base& __rhs)
599 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
601 __variant::__raw_idx_visit(
602 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
604 constexpr size_t __j = __rhs_index;
605 if constexpr (__j != variant_npos)
607 in_place_index<__j>, __rhs_mem);
608 }, __variant_cast<_Types...>(__rhs));
609 this->_M_index = __rhs._M_index;
612 _Copy_ctor_base(_Copy_ctor_base&&) =
default;
613 _Copy_ctor_base& operator=(
const _Copy_ctor_base&) =
default;
614 _Copy_ctor_base& operator=(_Copy_ctor_base&&) =
default;
617 template<
typename... _Types>
618 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
620 using _Base = _Variant_storage_alias<_Types...>;
624 template<
typename... _Types>
625 using _Copy_ctor_alias =
626 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
628 template<bool,
typename... _Types>
629 struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
631 using _Base = _Copy_ctor_alias<_Types...>;
635 _Move_ctor_base(_Move_ctor_base&& __rhs)
636 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
638 __variant::__raw_idx_visit(
639 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
641 constexpr size_t __j = __rhs_index;
642 if constexpr (__j != variant_npos)
646 }, __variant_cast<_Types...>(
std::move(__rhs)));
647 this->_M_index = __rhs._M_index;
650 _Move_ctor_base(
const _Move_ctor_base&) =
default;
651 _Move_ctor_base& operator=(
const _Move_ctor_base&) =
default;
652 _Move_ctor_base& operator=(_Move_ctor_base&&) =
default;
655 template<
typename... _Types>
656 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
658 using _Base = _Copy_ctor_alias<_Types...>;
662 template<
typename... _Types>
663 using _Move_ctor_alias =
664 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
666 template<bool,
typename... _Types>
667 struct _Copy_assign_base : _Move_ctor_alias<_Types...>
669 using _Base = _Move_ctor_alias<_Types...>;
674 operator=(
const _Copy_assign_base& __rhs)
675 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
677 __variant::__raw_idx_visit(
678 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
680 constexpr size_t __j = __rhs_index;
681 if constexpr (__j == variant_npos)
683 else if (this->_M_index == __j)
684 __variant::__get<__j>(*
this) = __rhs_mem;
687 using _Tj =
typename _Nth_type<__j, _Types...>::type;
688 if constexpr (is_nothrow_copy_constructible_v<_Tj>
689 || !is_nothrow_move_constructible_v<_Tj>)
690 __variant::__emplace<__j>(*
this, __rhs_mem);
693 using _Variant = variant<_Types...>;
694 _Variant& __self = __variant_cast<_Types...>(*this);
695 __self = _Variant(in_place_index<__j>, __rhs_mem);
698 }, __variant_cast<_Types...>(__rhs));
702 _Copy_assign_base(
const _Copy_assign_base&) =
default;
703 _Copy_assign_base(_Copy_assign_base&&) =
default;
704 _Copy_assign_base& operator=(_Copy_assign_base&&) =
default;
707 template<
typename... _Types>
708 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
710 using _Base = _Move_ctor_alias<_Types...>;
714 template<
typename... _Types>
715 using _Copy_assign_alias =
716 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
718 template<bool,
typename... _Types>
719 struct _Move_assign_base : _Copy_assign_alias<_Types...>
721 using _Base = _Copy_assign_alias<_Types...>;
726 operator=(_Move_assign_base&& __rhs)
727 noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
729 __variant::__raw_idx_visit(
730 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
732 constexpr size_t __j = __rhs_index;
733 if constexpr (__j != variant_npos)
735 if (this->_M_index == __j)
736 __variant::__get<__j>(*
this) =
std::move(__rhs_mem);
739 using _Tj =
typename _Nth_type<__j, _Types...>::type;
740 if constexpr (is_nothrow_move_constructible_v<_Tj>)
741 __variant::__emplace<__j>(*
this,
std::move(__rhs_mem));
744 using _Variant = variant<_Types...>;
745 _Variant& __self = __variant_cast<_Types...>(*this);
746 __self.template emplace<__j>(
std::move(__rhs_mem));
752 }, __variant_cast<_Types...>(__rhs));
756 _Move_assign_base(
const _Move_assign_base&) =
default;
757 _Move_assign_base(_Move_assign_base&&) =
default;
758 _Move_assign_base& operator=(
const _Move_assign_base&) =
default;
761 template<
typename... _Types>
762 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
764 using _Base = _Copy_assign_alias<_Types...>;
768 template<
typename... _Types>
769 using _Move_assign_alias =
770 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
772 template<
typename... _Types>
773 struct _Variant_base : _Move_assign_alias<_Types...>
775 using _Base = _Move_assign_alias<_Types...>;
778 _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
779 : _Variant_base(in_place_index<0>) { }
781 template<
size_t _Np,
typename... _Args>
783 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
784 : _Base(__i, std::
forward<_Args>(__args)...)
787 _Variant_base(
const _Variant_base&) =
default;
788 _Variant_base(_Variant_base&&) =
default;
789 _Variant_base& operator=(
const _Variant_base&) =
default;
790 _Variant_base& operator=(_Variant_base&&) =
default;
793 template<
typename _Tp,
typename... _Types>
794 inline constexpr bool __exactly_once
795 = std::__find_uniq_type_in_pack<_Tp, _Types...>() <
sizeof...(_Types);
798 template<
typename _Ti>
struct _Arr { _Ti _M_x[1]; };
801 template<
size_t _Ind,
typename _Tp,
typename _Ti,
typename =
void>
806 void _S_fun() =
delete;
810 template<
size_t _Ind,
typename _Tp,
typename _Ti>
811 struct _Build_FUN<_Ind, _Tp, _Ti,
815 static integral_constant<size_t, _Ind> _S_fun(_Ti);
818 template<
typename _Tp,
typename _Variant,
822 template<
typename _Tp,
typename... _Ti,
size_t... _Ind>
824 : _Build_FUN<_Ind, _Tp, _Ti>...
826 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
831 template<
typename _Tp,
typename _Variant>
836 template<
typename _Tp,
typename _Variant,
typename =
void>
837 inline constexpr size_t
838 __accepted_index = variant_npos;
840 template<
typename _Tp,
typename _Variant>
841 inline constexpr size_t
842 __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
843 = _FUN_type<_Tp, _Variant>::value;
845 template<
typename _Maybe_variant_cookie,
typename _Variant,
846 typename = __remove_cvref_t<_Variant>>
847 inline constexpr bool
848 __extra_visit_slot_needed =
false;
850 template<
typename _Var,
typename... _Types>
851 inline constexpr bool
852 __extra_visit_slot_needed<__variant_cookie, _Var, variant<_Types...>>
853 = !__variant::__never_valueless<_Types...>();
855 template<
typename _Var,
typename... _Types>
856 inline constexpr bool
857 __extra_visit_slot_needed<__variant_idx_cookie, _Var, variant<_Types...>>
858 = !__variant::__never_valueless<_Types...>();
861 template<
typename _Tp,
size_t... _Dimensions>
865 template<
typename _Tp>
866 struct _Multi_array<_Tp>
869 struct __untag_result
871 {
using element_type = _Tp; };
873#pragma GCC diagnostic push
874#pragma GCC diagnostic ignored "-Wignored-qualifiers"
875 template <
typename... _Args>
876 struct __untag_result<const void(*)(_Args...)>
878 {
using element_type = void(*)(_Args...); };
879#pragma GCC diagnostic pop
881 template <
typename... _Args>
882 struct __untag_result<__variant_cookie(*)(_Args...)>
884 {
using element_type = void(*)(_Args...); };
886 template <
typename... _Args>
887 struct __untag_result<__variant_idx_cookie(*)(_Args...)>
889 {
using element_type = void(*)(_Args...); };
891 template <
typename _Res,
typename... _Args>
892 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
894 {
using element_type = _Res(*)(_Args...); };
896 using __result_is_deduced = __untag_result<_Tp>;
898 constexpr const typename __untag_result<_Tp>::element_type&
902 typename __untag_result<_Tp>::element_type _M_data;
906 template<
typename _Ret,
908 typename... _Variants,
909 size_t __first,
size_t... __rest>
910 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
912 static constexpr size_t __index =
913 sizeof...(_Variants) -
sizeof...(__rest) - 1;
915 using _Variant =
typename _Nth_type<__index, _Variants...>::type;
917 static constexpr int __do_cookie =
918 __extra_visit_slot_needed<_Ret, _Variant> ? 1 : 0;
920 using _Tp = _Ret(*)(_Visitor, _Variants...);
922 template<
typename... _Args>
923 constexpr decltype(
auto)
924 _M_access(
size_t __first_index, _Args... __rest_indices)
const
926 return _M_arr[__first_index + __do_cookie]
927 ._M_access(__rest_indices...);
930 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
960 template<
typename _Array_type,
typename _Index_seq>
961 struct __gen_vtable_impl;
970 template<
typename _Result_type,
typename _Visitor,
size_t... __dimensions,
971 typename... _Variants,
size_t... __indices>
972 struct __gen_vtable_impl<
973 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
978 _Variants...>::type>;
980 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
983 static constexpr _Array_type
986 _Array_type __vtable{};
992 template<
size_t... __var_indices>
993 static constexpr void
994 _S_apply_all_alts(_Array_type& __vtable,
997 if constexpr (__extra_visit_slot_needed<_Result_type, _Next>)
998 (_S_apply_single_alt<true, __var_indices>(
999 __vtable._M_arr[__var_indices + 1],
1000 &(__vtable._M_arr[0])), ...);
1002 (_S_apply_single_alt<false, __var_indices>(
1003 __vtable._M_arr[__var_indices]), ...);
1006 template<
bool __do_cookie,
size_t __index,
typename _Tp>
1007 static constexpr void
1008 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element =
nullptr)
1010 if constexpr (__do_cookie)
1012 __element = __gen_vtable_impl<
1015 *__cookie_element = __gen_vtable_impl<
1021 auto __tmp_element = __gen_vtable_impl<
1024 static_assert(is_same_v<_Tp,
decltype(__tmp_element)>,
1025 "std::visit requires the visitor to have the same "
1026 "return type for all alternatives of a variant");
1027 __element = __tmp_element;
1035 template<
typename _Result_type,
typename _Visitor,
typename... _Variants,
1036 size_t... __indices>
1037 struct __gen_vtable_impl<
1038 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
1042 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
1044 template<
size_t __index,
typename _Variant>
1045 static constexpr decltype(
auto)
1046 __element_by_index_or_cookie(_Variant&& __var)
noexcept
1048 if constexpr (__index != variant_npos)
1051 return __variant_cookie{};
1054 static constexpr decltype(
auto)
1055 __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1057 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1061 __element_by_index_or_cookie<__indices>(
1063 integral_constant<size_t, __indices>()...);
1064 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1067 __element_by_index_or_cookie<__indices>(
1069 else if constexpr (_Array_type::__result_is_deduced::value)
1072 __element_by_index_or_cookie<__indices>(
1075 return std::__invoke_r<_Result_type>(
1080 static constexpr auto
1083 if constexpr (_Array_type::__result_is_deduced::value)
1085 constexpr bool __visit_ret_type_mismatch =
1086 !is_same_v<
typename _Result_type::type,
1089 if constexpr (__visit_ret_type_mismatch)
1091 struct __cannot_match {};
1092 return __cannot_match{};
1095 return _Array_type{&__visit_invoke};
1098 return _Array_type{&__visit_invoke};
1102 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1106 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1107 variant_size_v<remove_reference_t<_Variants>>...>;
1109 static constexpr _Array_type _S_vtable
1110 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1113#if ! _GLIBCXX_INLINE_VERSION
1114 template<
size_t _Nm,
typename _Tp>
1115 struct _Base_dedup :
public _Tp { };
1117 template<
typename _Variant,
typename __indices>
1118 struct _Variant_hash_base;
1120 template<
typename... _Types,
size_t... __indices>
1121 struct _Variant_hash_base<variant<_Types...>,
1123 : _Base_dedup<__indices, __hash_empty_base<remove_const_t<_Types>>>...
1128 template<
size_t _Np,
typename _Variant,
1132 = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1135 template<
typename _Visitor,
typename... _Variants>
1136 using __visit_result_t
1137 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1139 template<
typename _Tp,
typename... _Types>
1140 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1142 template <
typename _Visitor,
typename _Variant,
size_t... _Idxs>
1145 return __same_types<
1146 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1153 template<
typename _Tp,
typename... _Types>
1155 holds_alternative(
const variant<_Types...>& __v)
noexcept
1157 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1158 "T must occur exactly once in alternatives");
1159 return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>();
1162 template<
typename _Tp,
typename... _Types>
1164 get(variant<_Types...>& __v)
1166 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1167 "T must occur exactly once in alternatives");
1168 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1169 return std::get<__n>(__v);
1172 template<
typename _Tp,
typename... _Types>
1174 get(variant<_Types...>&& __v)
1176 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1177 "T must occur exactly once in alternatives");
1178 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1182 template<
typename _Tp,
typename... _Types>
1183 constexpr const _Tp&
1184 get(
const variant<_Types...>& __v)
1186 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1187 "T must occur exactly once in alternatives");
1188 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1189 return std::get<__n>(__v);
1192 template<
typename _Tp,
typename... _Types>
1193 constexpr const _Tp&&
1194 get(
const variant<_Types...>&& __v)
1196 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1197 "T must occur exactly once in alternatives");
1198 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1202 template<
size_t _Np,
typename... _Types>
1203 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1204 get_if(variant<_Types...>* __ptr)
noexcept
1206 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1207 static_assert(_Np <
sizeof...(_Types),
1208 "The index must be in [0, number of alternatives)");
1209 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1210 if (__ptr && __ptr->index() == _Np)
1215 template<
size_t _Np,
typename... _Types>
1217 add_pointer_t<
const variant_alternative_t<_Np, variant<_Types...>>>
1218 get_if(
const variant<_Types...>* __ptr)
noexcept
1220 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1221 static_assert(_Np <
sizeof...(_Types),
1222 "The index must be in [0, number of alternatives)");
1223 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1224 if (__ptr && __ptr->index() == _Np)
1229 template<
typename _Tp,
typename... _Types>
1231 get_if(variant<_Types...>* __ptr)
noexcept
1233 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1234 "T must occur exactly once in alternatives");
1235 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1236 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1237 return std::get_if<__n>(__ptr);
1240 template<
typename _Tp,
typename... _Types>
1242 get_if(
const variant<_Types...>* __ptr)
noexcept
1244 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1245 "T must occur exactly once in alternatives");
1246 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1247 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1248 return std::get_if<__n>(__ptr);
1251namespace __detail::__variant
1253 template<
typename _Ret,
typename _Vp,
typename _Op>
1255 __compare(_Ret __ret,
const _Vp& __lhs,
const _Vp& __rhs, _Op __op)
1257 __variant::__raw_idx_visit(
1258 [&__ret, &__lhs, __op] (
auto&& __rhs_mem,
auto __rhs_index)
mutable
1260 if constexpr (__rhs_index != variant_npos)
1262 if (__lhs.index() == __rhs_index.value)
1264 auto& __this_mem = std::get<__rhs_index>(__lhs);
1265 __ret = __op(__this_mem, __rhs_mem);
1269 __ret = __op(__lhs.index() + 1, __rhs_index + 1);
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 template<
typename... _Types>
1356#if __cpp_lib_concepts
1357 requires ((
requires (
const _Types& __t) {
1358 { __t >= __t } -> convertible_to<bool>; }) && ...)
1361 operator>= [[nodiscard]] (
const variant<_Types...>& __lhs,
1362 const variant<_Types...>& __rhs)
1364 namespace __variant = __detail::__variant;
1365 return __variant::__compare(
true, __lhs, __rhs,
1366 [](
auto&& __l,
auto&& __r) ->
bool {
1371#ifdef __cpp_lib_three_way_comparison
1372 template<
typename... _Types>
1373 requires (three_way_comparable<_Types> && ...)
1375 common_comparison_category_t<compare_three_way_result_t<_Types>...>
1376 operator<=>(
const variant<_Types...>& __v,
const variant<_Types...>& __w)
1378 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1379 = strong_ordering::equal;
1380 namespace __variant = __detail::__variant;
1381 return __variant::__compare(__ret, __v, __w,
1382 [](
auto&& __l,
auto&& __r) {
1388 template<
typename _Visitor,
typename... _Variants>
1389 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1390 visit(_Visitor&&, _Variants&&...);
1392#if __cplusplus > 201703L
1393 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1395 visit(_Visitor&&, _Variants&&...);
1398 template<
typename... _Types>
1399 _GLIBCXX20_CONSTEXPR
1400 inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1401 && (is_swappable_v<_Types> && ...)>
1402 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1403 noexcept(
noexcept(__lhs.swap(__rhs)))
1404 { __lhs.swap(__rhs); }
1408 template<
typename... _Types>
1409 enable_if_t<!((is_move_constructible_v<_Types> && ...)
1410 && (is_swappable_v<_Types> && ...))>
1411 swap(variant<_Types...>&, variant<_Types...>&) =
delete;
1413 [[noreturn]]
void __throw_bad_variant_access(
unsigned);
1415 class bad_variant_access :
public exception
1418 bad_variant_access() noexcept { }
1420 const char* what() const noexcept
override
1421 {
return _M_reason; }
1425 bad_variant_access(
const char* __reason) noexcept : _M_reason(__reason) { }
1428 const char* _M_reason =
"bad variant access";
1430 friend void __throw_bad_variant_access([[maybe_unused]]
unsigned __n)
1432 [[maybe_unused]]
static constexpr const char* __reasons[] = {
1433 "std::get: wrong index for variant",
1434 "std::get: variant is valueless",
1435 "std::visit: variant is valueless",
1436 "std::visit<R>: variant is valueless",
1438 _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__reasons[__n % 4u]));
1442 template<
typename... _Types>
1444 :
private __detail::__variant::_Variant_base<_Types...>,
1445 private _Enable_copy_move<
1446 __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1447 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1448 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1449 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1453 template <
typename... _UTypes,
typename _Tp>
1454 friend _GLIBCXX20_CONSTEXPR
decltype(
auto)
1455 __variant_cast(_Tp&&);
1457 static_assert(
sizeof...(_Types) > 0,
1458 "variant must have at least one alternative");
1459 static_assert(((std::is_object_v<_Types> && !is_array_v<_Types>) && ...),
1460 "variant alternatives must be non-array object types");
1462 using _Base = __detail::__variant::_Variant_base<_Types...>;
1464 template<
typename _Tp>
1465 static constexpr bool __not_self
1466 = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1468 template<
typename _Tp>
1469 static constexpr bool
1470 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1472 template<
typename _Tp>
1473 static constexpr size_t __accepted_index
1474 = __detail::__variant::__accepted_index<_Tp, variant>;
1476 template<
size_t _Np,
typename =
enable_if_t<(_Np <
sizeof...(_Types))>>
1477 using __to_type =
typename _Nth_type<_Np, _Types...>::type;
1479 template<
typename _Tp,
typename = enable_if_t<__not_self<_Tp>>>
1480 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1482 template<
typename _Tp>
1483 static constexpr size_t __index_of
1484 = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1486 using _Traits = __detail::__variant::_Traits<_Types...>;
1488 template<
typename _Tp>
1489 static constexpr bool __not_in_place_tag
1490 = !__is_in_place_type_v<__remove_cvref_t<_Tp>>
1491 && !__is_in_place_index_v<__remove_cvref_t<_Tp>>;
1495 variant()
requires is_default_constructible_v<__to_type<0>> = default;
1497 template<
typename _Tp0 = __to_type<0>,
1498 typename = enable_if_t<is_default_constructible_v<_Tp0>>>
1500 variant() noexcept(is_nothrow_default_constructible_v<__to_type<0>>)
1504 variant(
const variant& __rhs) =
default;
1505 variant(variant&&) =
default;
1506 variant& operator=(
const variant&) =
default;
1507 variant& operator=(variant&&) =
default;
1508 _GLIBCXX20_CONSTEXPR ~variant() =
default;
1510 template<
typename _Tp,
1512 typename = enable_if_t<__not_in_place_tag<_Tp>>,
1513 typename _Tj = __accepted_type<_Tp&&>,
1514 typename = enable_if_t<__exactly_once<_Tj>
1515 && is_constructible_v<_Tj, _Tp>>>
1518 noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1519 : variant(in_place_index<__accepted_index<_Tp>>,
1523 template<
typename _Tp,
typename... _Args,
1524 typename = enable_if_t<__exactly_once<_Tp>
1525 && is_constructible_v<_Tp, _Args...>>>
1527 variant(in_place_type_t<_Tp>, _Args&&... __args)
1528 : variant(in_place_index<__index_of<_Tp>>,
1529 std::
forward<_Args>(__args)...)
1532 template<
typename _Tp,
typename _Up,
typename... _Args,
1533 typename = enable_if_t<__exactly_once<_Tp>
1534 && is_constructible_v<_Tp,
1535 initializer_list<_Up>&, _Args...>>>
1537 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1539 : variant(in_place_index<__index_of<_Tp>>, __il,
1540 std::
forward<_Args>(__args)...)
1543 template<
size_t _Np,
typename... _Args,
1544 typename _Tp = __to_type<_Np>,
1545 typename =
enable_if_t<is_constructible_v<_Tp, _Args...>>>
1547 variant(in_place_index_t<_Np>, _Args&&... __args)
1548 : _Base(in_place_index<_Np>, std::
forward<_Args>(__args)...)
1551 template<
size_t _Np,
typename _Up,
typename... _Args,
1552 typename _Tp = __to_type<_Np>,
1554 initializer_list<_Up>&,
1557 variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1559 : _Base(in_place_index<_Np>, __il, std::
forward<_Args>(__args)...)
1562 template<
typename _Tp>
1563 _GLIBCXX20_CONSTEXPR
1564 enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1565 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1566 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1568 operator=(_Tp&& __rhs)
1569 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1570 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1572 constexpr auto __index = __accepted_index<_Tp>;
1573 if (index() == __index)
1577 using _Tj = __accepted_type<_Tp&&>;
1578 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1579 || !is_nothrow_move_constructible_v<_Tj>)
1589 template<
typename _Tp,
typename... _Args>
1590 _GLIBCXX20_CONSTEXPR
1591 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1593 emplace(_Args&&... __args)
1595 constexpr size_t __index = __index_of<_Tp>;
1599 template<
typename _Tp,
typename _Up,
typename... _Args>
1600 _GLIBCXX20_CONSTEXPR
1601 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1602 && __exactly_once<_Tp>,
1604 emplace(initializer_list<_Up> __il, _Args&&... __args)
1606 constexpr size_t __index = __index_of<_Tp>;
1610 template<
size_t _Np,
typename... _Args>
1611 _GLIBCXX20_CONSTEXPR
1612 enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>,
1614 emplace(_Args&&... __args)
1616 namespace __variant = std::__detail::__variant;
1617 using type =
typename _Nth_type<_Np, _Types...>::type;
1620 if constexpr (is_nothrow_constructible_v<type, _Args...>)
1624 else if constexpr (is_scalar_v<type>)
1629 __variant::__emplace<_Np>(*
this, __tmp);
1631 else if constexpr (__variant::_Never_valueless_alt<type>()
1632 && _Traits::_S_move_assign)
1635 variant __tmp(in_place_index<_Np>,
1646 return std::get<_Np>(*
this);
1649 template<
size_t _Np,
typename _Up,
typename... _Args>
1650 _GLIBCXX20_CONSTEXPR
1651 enable_if_t<is_constructible_v<__to_type<_Np>,
1652 initializer_list<_Up>&, _Args...>,
1654 emplace(initializer_list<_Up> __il, _Args&&... __args)
1656 namespace __variant = std::__detail::__variant;
1657 using type =
typename _Nth_type<_Np, _Types...>::type;
1660 if constexpr (is_nothrow_constructible_v<type,
1661 initializer_list<_Up>&,
1664 __variant::__emplace<_Np>(*
this, __il,
1667 else if constexpr (__variant::_Never_valueless_alt<type>()
1668 && _Traits::_S_move_assign)
1671 variant __tmp(in_place_index<_Np>, __il,
1680 __variant::__emplace<_Np>(*
this, __il,
1683 return std::get<_Np>(*
this);
1686 template<
size_t _Np,
typename... _Args>
1687 enable_if_t<!(_Np <
sizeof...(_Types))> emplace(_Args&&...) =
delete;
1689 template<
typename _Tp,
typename... _Args>
1690 enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) =
delete;
1692 constexpr bool valueless_by_exception() const noexcept
1693 {
return !this->_M_valid(); }
1695 constexpr size_t index() const noexcept
1697 using __index_type =
typename _Base::__index_type;
1698 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1699 return this->_M_index;
1700 else if constexpr (
sizeof...(_Types) <= __index_type(-1) / 2)
1701 return make_signed_t<__index_type>(this->_M_index);
1703 return size_t(__index_type(this->_M_index + 1)) - 1;
1706 _GLIBCXX20_CONSTEXPR
1708 swap(variant& __rhs)
1709 noexcept((__is_nothrow_swappable<_Types>::value && ...)
1710 && is_nothrow_move_constructible_v<variant>)
1712 static_assert((is_move_constructible_v<_Types> && ...));
1715 if (__rhs.valueless_by_exception()) [[__unlikely__]]
1717 if (!this->valueless_by_exception()) [[__likely__]]
1722 namespace __variant = __detail::__variant;
1724 __variant::__raw_idx_visit(
1725 [
this, &__rhs](
auto&& __rhs_mem,
auto __rhs_index)
mutable
1727 constexpr size_t __j = __rhs_index;
1728 if constexpr (__j != variant_npos)
1730 if (this->index() == __j)
1733 swap(std::get<__j>(*
this), __rhs_mem);
1739 if constexpr (_Traits::_S_trivial_move_assign)
1742 __variant::__raw_idx_visit(
1743 [&__rhs](
auto&& __this_mem,
auto __this_index)
mutable
1745 constexpr size_t __k = __this_index;
1746 if constexpr (__k != variant_npos)
1747 __variant::__emplace<__k>(__rhs,
1751 __variant::__emplace<__j>(*
this,
std::move(__tmp));
1757#if __cpp_lib_variant >= 202306L
1767 template<
int = 0,
typename _Self,
typename _Visitor>
1768 constexpr decltype(
auto)
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&&>,
1785 template<
typename _Res,
typename _Self,
typename _Visitor>
1787 visit(
this _Self&& __self, _Visitor&& __vis)
1789 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1790 const variant, variant>;
1791 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1798 template<
size_t _Np,
typename _Vp>
1799 friend constexpr decltype(
auto)
1800 __detail::__variant::__get(_Vp&& __v)
noexcept;
1803 template<
size_t _Np,
typename... _Types>
1804 constexpr variant_alternative_t<_Np, variant<_Types...>>&
1805 get(variant<_Types...>& __v)
1807 static_assert(_Np <
sizeof...(_Types),
1808 "The index must be in [0, number of alternatives)");
1809 if (__v.index() != _Np)
1810 __throw_bad_variant_access(__v.valueless_by_exception());
1811 return __detail::__variant::__get<_Np>(__v);
1814 template<
size_t _Np,
typename... _Types>
1815 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1816 get(variant<_Types...>&& __v)
1818 static_assert(_Np <
sizeof...(_Types),
1819 "The index must be in [0, number of alternatives)");
1820 if (__v.index() != _Np)
1821 __throw_bad_variant_access(__v.valueless_by_exception());
1822 return __detail::__variant::__get<_Np>(
std::move(__v));
1825 template<
size_t _Np,
typename... _Types>
1826 constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1827 get(
const variant<_Types...>& __v)
1829 static_assert(_Np <
sizeof...(_Types),
1830 "The index must be in [0, number of alternatives)");
1831 if (__v.index() != _Np)
1832 __throw_bad_variant_access(__v.valueless_by_exception());
1833 return __detail::__variant::__get<_Np>(__v);
1836 template<
size_t _Np,
typename... _Types>
1837 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1838 get(
const variant<_Types...>&& __v)
1840 static_assert(_Np <
sizeof...(_Types),
1841 "The index must be in [0, number of alternatives)");
1842 if (__v.index() != _Np)
1843 __throw_bad_variant_access(__v.valueless_by_exception());
1844 return __detail::__variant::__get<_Np>(
std::move(__v));
1848 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1849 constexpr decltype(
auto)
1850 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1853 if constexpr (
sizeof...(_Variants) == 0)
1855 if constexpr (is_void_v<_Result_type>)
1862 constexpr size_t __max = 11;
1865 using _V0 =
typename _Nth_type<0, _Variants...>::type;
1867 constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
1869 if constexpr (
sizeof...(_Variants) > 1 || __n > __max)
1872 constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1873 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1875 auto __func_ptr = __vtable._M_access(__variants.index()...);
1883 = [](_V0& __v, ...) -> _V0& {
return __v; }(__variants...);
1885 using __detail::__variant::_Multi_array;
1886 using __detail::__variant::__gen_vtable_impl;
1887 using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0&&)>;
1889#ifdef _GLIBCXX_DEBUG
1890# define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap
1892# define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable
1895#define _GLIBCXX_VISIT_CASE(N) \
1898 if constexpr (N < __n) \
1900 return __gen_vtable_impl<_Ma, index_sequence<N>>:: \
1901 __visit_invoke(std::forward<_Visitor>(__visitor), \
1902 std::forward<_V0>(__v0)); \
1904 else _GLIBCXX_VISIT_UNREACHABLE(); \
1907 switch (__v0.index())
1909 _GLIBCXX_VISIT_CASE(0)
1910 _GLIBCXX_VISIT_CASE(1)
1911 _GLIBCXX_VISIT_CASE(2)
1912 _GLIBCXX_VISIT_CASE(3)
1913 _GLIBCXX_VISIT_CASE(4)
1914 _GLIBCXX_VISIT_CASE(5)
1915 _GLIBCXX_VISIT_CASE(6)
1916 _GLIBCXX_VISIT_CASE(7)
1917 _GLIBCXX_VISIT_CASE(8)
1918 _GLIBCXX_VISIT_CASE(9)
1919 _GLIBCXX_VISIT_CASE(10)
1921 using
__detail::__variant::__variant_idx_cookie;
1922 using
__detail::__variant::__variant_cookie;
1923 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
1924 || is_same_v<_Result_type, __variant_cookie>)
1927 return __gen_vtable_impl<_Ma, _Npos>::
1932 _GLIBCXX_VISIT_UNREACHABLE();
1934 _GLIBCXX_VISIT_UNREACHABLE();
1936#undef _GLIBCXX_VISIT_CASE
1937#undef _GLIBCXX_VISIT_UNREACHABLE
1943 template<
typename _Visitor,
typename... _Variants>
1944 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1945 visit(_Visitor&& __visitor, _Variants&&... __variants)
1947 namespace __variant = std::__detail::__variant;
1949 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1950 __throw_bad_variant_access(2);
1953 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1955 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1957 if constexpr (
sizeof...(_Variants) == 1)
1961 constexpr bool __visit_rettypes_match = __detail::__variant::
1962 __check_visitor_results<_Visitor, _Vp>(
1964 if constexpr (!__visit_rettypes_match)
1966 static_assert(__visit_rettypes_match,
1967 "std::visit requires the visitor to have the same "
1968 "return type for all alternatives of a variant");
1972 return std::__do_visit<_Tag>(
1974 static_cast<_Vp
>(__variants)...);
1977 return std::__do_visit<_Tag>(
1982#if __cplusplus > 201703L
1983 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1985 visit(_Visitor&& __visitor, _Variants&&... __variants)
1987 namespace __variant = std::__detail::__variant;
1989 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1990 __throw_bad_variant_access(3);
1998 template<
typename... _Types>
1999 struct __variant_hash
2001#if __cplusplus < 202002L
2002 using result_type [[__deprecated__]] = size_t;
2003 using argument_type [[__deprecated__]] = variant<_Types...>;
2007 operator()(
const variant<_Types...>& __t)
const
2008 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
2011 __detail::__variant::__raw_visit(
2012 [&__t, &__ret](
auto&& __t_mem)
mutable
2014 using _Type = __remove_cvref_t<
decltype(__t_mem)>;
2015 if constexpr (!is_same_v<_Type,
2016 __detail::__variant::__variant_cookie>)
2017 __ret = std::hash<size_t>{}(__t.index())
2018 + std::hash<_Type>{}(__t_mem);
2020 __ret = std::hash<size_t>{}(__t.index());
2027 template<
typename... _Types>
2028 struct hash<variant<_Types...>>
2029 : __conditional_t<(__is_hash_enabled_for<remove_const_t<_Types>> && ...),
2030 __variant_hash<_Types...>,
2031 __hash_not_enabled<variant<_Types...>>>
2032#if ! _GLIBCXX_INLINE_VERSION
2033 , __detail::__variant::_Variant_hash_base<variant<_Types...>,
2034 index_sequence_for<_Types...>>
2038 template<
typename... _Types>
2040 : bool_constant<(__is_fast_hash<_Types>::value && ...)>
2043_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.