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
39#define __glibcxx_want_constexpr_exceptions
42#ifdef __cpp_lib_variant
54#if __cplusplus >= 202002L
60#if __cpp_lib_variant < 202106L
64namespace std _GLIBCXX_VISIBILITY(default)
66_GLIBCXX_BEGIN_NAMESPACE_VERSION
68 template<
typename... _Types>
class tuple;
69 template<
typename... _Types>
class variant;
71 template<
typename _Variant>
74 template<
typename _Variant>
75 struct variant_size<const _Variant> : variant_size<_Variant> {};
77 template<
typename _Variant>
78 struct variant_size<volatile _Variant> : variant_size<_Variant> {};
80 template<
typename _Variant>
81 struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
83 template<
typename... _Types>
84 struct variant_size<variant<_Types...>>
85 : std::integral_constant<size_t, sizeof...(_Types)> {};
87 template<
typename _Variant>
88 inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
90 template<
typename... _Types>
91 inline constexpr size_t
92 variant_size_v<variant<_Types...>> =
sizeof...(_Types);
94 template<
typename... _Types>
95 inline constexpr size_t
96 variant_size_v<
const variant<_Types...>> =
sizeof...(_Types);
98 template<
size_t _Np,
typename _Variant>
99 struct variant_alternative;
101 template<
size_t _Np,
typename... _Types>
102 struct variant_alternative<_Np, variant<_Types...>>
104 static_assert(_Np <
sizeof...(_Types));
106 using type =
typename _Nth_type<_Np, _Types...>::type;
109 template<
size_t _Np,
typename _Variant>
110 using variant_alternative_t =
111 typename variant_alternative<_Np, _Variant>::type;
113 template<
size_t _Np,
typename _Variant>
114 struct variant_alternative<_Np, const _Variant>
115 {
using type =
const variant_alternative_t<_Np, _Variant>; };
117 template<
size_t _Np,
typename _Variant>
118 struct variant_alternative<_Np, volatile _Variant>
119 {
using type =
volatile variant_alternative_t<_Np, _Variant>; };
121 template<
size_t _Np,
typename _Variant>
122 struct variant_alternative<_Np, const volatile _Variant>
123 {
using type =
const volatile variant_alternative_t<_Np, _Variant>; };
125 inline constexpr size_t variant_npos = -1;
127 template<
size_t _Np,
typename... _Types>
128 constexpr variant_alternative_t<_Np, variant<_Types...>>&
129 get(variant<_Types...>&);
131 template<
size_t _Np,
typename... _Types>
132 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
133 get(variant<_Types...>&&);
135 template<
size_t _Np,
typename... _Types>
136 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&
137 get(
const variant<_Types...>&);
139 template<
size_t _Np,
typename... _Types>
140 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&&
141 get(
const variant<_Types...>&&);
143 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
144 constexpr decltype(
auto)
145 __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
147 template <
typename... _Types,
typename _Tp>
150 __variant_cast(_Tp&& __rhs)
152 if constexpr (is_lvalue_reference_v<_Tp>)
154 if constexpr (is_const_v<remove_reference_t<_Tp>>)
155 return static_cast<const variant<_Types...
>&>(__rhs);
157 return static_cast<variant<_Types...
>&>(__rhs);
160 return static_cast<variant<_Types...
>&&>(__rhs);
168 struct __variant_cookie {};
170 struct __variant_idx_cookie {
using type = __variant_idx_cookie; };
172 template<
typename _Tp>
struct __deduce_visit_result {
using type = _Tp; };
175 template<
typename _Visitor,
typename... _Variants>
177 __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
184 template<
typename _Visitor,
typename... _Variants>
186 __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
194 template<
typename... _Types>
195 constexpr std::variant<_Types...>&
196 __as(std::variant<_Types...>& __v)
noexcept
199 template<
typename... _Types>
200 constexpr const std::variant<_Types...>&
201 __as(
const std::variant<_Types...>& __v)
noexcept
204 template<
typename... _Types>
205 constexpr std::variant<_Types...>&&
206 __as(std::variant<_Types...>&& __v)
noexcept
209 template<
typename... _Types>
210 constexpr const std::variant<_Types...>&&
211 __as(
const std::variant<_Types...>&& __v)
noexcept
214#if __cpp_lib_variant < 202106L
215 template<
typename _Type,
bool = std::is_trivially_destructible_v<_Type>>
216 struct _Uninitialized;
218 template<
typename _Type,
bool =
true>
219 struct _Uninitialized;
224 template<
typename _Type,
bool>
225 struct _Uninitialized
227 template<
typename... _Args>
229 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
230 : _M_storage(std::
forward<_Args>(__args)...)
233#if __cpp_lib_variant < 202106L
234 constexpr const _Type& _M_get() const & noexcept
235 {
return _M_storage; }
237 constexpr _Type& _M_get() &
noexcept
238 {
return _M_storage; }
240 constexpr const _Type&& _M_get() const && noexcept
243 constexpr _Type&& _M_get() &&
noexcept
250#if __cpp_lib_variant < 202106L
254 template<
typename _Type>
255 struct _Uninitialized<_Type, false>
257 template<
typename... _Args>
259 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
265 const _Type& _M_get() const & noexcept
266 {
return *_M_storage._M_ptr(); }
268 _Type& _M_get() &
noexcept
269 {
return *_M_storage._M_ptr(); }
271 const _Type&& _M_get() const && noexcept
272 {
return std::move(*_M_storage._M_ptr()); }
274 _Type&& _M_get() &&
noexcept
275 {
return std::move(*_M_storage._M_ptr()); }
277 __gnu_cxx::__aligned_membuf<_Type> _M_storage;
280 template<
size_t _Np,
typename _Union>
281 constexpr decltype(
auto)
282 __get_n(_Union&& __u)
noexcept
284 if constexpr (_Np == 0)
286 else if constexpr (_Np == 1)
288 else if constexpr (_Np == 2)
291 return __variant::__get_n<_Np - 3>(
295 template<
size_t _Np,
typename _Union>
297 __get_n(_Union&& __u)
noexcept
299 if constexpr (_Np == 0)
301 else if constexpr (_Np == 1)
303 else if constexpr (_Np == 2)
306 return __variant::__get_n<_Np - 3>(
312 template<
size_t _Np,
typename _Variant>
313 constexpr decltype(
auto)
314 __get(_Variant&& __v)
noexcept
318 template<
size_t _Np,
typename _Union>
319 constexpr decltype(
auto)
320 __construct_n(_Union& __u)
noexcept
322 if constexpr (_Np == 0)
323 return &__u._M_first;
324 else if constexpr (_Np == 1)
327 return &__u._M_rest._M_first;
329 else if constexpr (_Np == 2)
333 return &__u._M_rest._M_rest._M_first;
340 return __variant::__construct_n<_Np - 3>(__u._M_rest._M_rest._M_rest);
344 template<
typename... _Types>
347 static constexpr bool _S_default_ctor =
348 is_default_constructible_v<
typename _Nth_type<0, _Types...>::type>;
349 static constexpr bool _S_copy_ctor =
350 (is_copy_constructible_v<_Types> && ...);
351 static constexpr bool _S_move_ctor =
352 (is_move_constructible_v<_Types> && ...);
353 static constexpr bool _S_copy_assign =
355 && (is_copy_assignable_v<_Types> && ...);
356 static constexpr bool _S_move_assign =
358 && (is_move_assignable_v<_Types> && ...);
360 static constexpr bool _S_trivial_dtor =
361 (is_trivially_destructible_v<_Types> && ...);
362 static constexpr bool _S_trivial_copy_ctor =
363 (is_trivially_copy_constructible_v<_Types> && ...);
364 static constexpr bool _S_trivial_move_ctor =
365 (is_trivially_move_constructible_v<_Types> && ...);
366 static constexpr bool _S_trivial_copy_assign =
367 _S_trivial_dtor && _S_trivial_copy_ctor
368 && (is_trivially_copy_assignable_v<_Types> && ...);
369 static constexpr bool _S_trivial_move_assign =
370 _S_trivial_dtor && _S_trivial_move_ctor
371 && (is_trivially_move_assignable_v<_Types> && ...);
375 static constexpr bool _S_nothrow_default_ctor =
376 is_nothrow_default_constructible_v<
377 typename _Nth_type<0, _Types...>::type>;
378 static constexpr bool _S_nothrow_copy_ctor =
false;
379 static constexpr bool _S_nothrow_move_ctor =
380 (is_nothrow_move_constructible_v<_Types> && ...);
381 static constexpr bool _S_nothrow_copy_assign =
false;
382 static constexpr bool _S_nothrow_move_assign =
384 && (is_nothrow_move_assignable_v<_Types> && ...);
388 template<
bool __trivially_destructible,
typename... _Types>
389 union _Variadic_union
391 _Variadic_union() =
default;
393 template<
size_t _Np,
typename... _Args>
394 _Variadic_union(in_place_index_t<_Np>, _Args&&...) =
delete;
397 template<
typename _First,
typename... _Rest>
398 union _Variadic_union<true, _First, _Rest...>
400 constexpr _Variadic_union() : _M_rest() { }
402 template<
typename... _Args>
404 _Variadic_union(in_place_index_t<0>, _Args&&... __args)
405 : _M_first(in_place_index<0>, std::
forward<_Args>(__args)...)
408 template<
size_t _Np,
typename... _Args>
410 _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
411 : _M_rest(in_place_index<_Np-1>, std::
forward<_Args>(__args)...)
414 _Uninitialized<_First> _M_first;
415 _Variadic_union<
true, _Rest...> _M_rest;
418 template<
typename _First,
typename... _Rest>
419 union _Variadic_union<false, _First, _Rest...>
421 constexpr _Variadic_union() : _M_rest() { }
423 template<
typename... _Args>
425 _Variadic_union(in_place_index_t<0>, _Args&&... __args)
426 : _M_first(in_place_index<0>, std::
forward<_Args>(__args)...)
429 template<
size_t _Np,
typename... _Args>
431 _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
432 : _M_rest(in_place_index<_Np-1>, std::
forward<_Args>(__args)...)
435 _Variadic_union(
const _Variadic_union&) =
default;
436 _Variadic_union(_Variadic_union&&) =
default;
437 _Variadic_union& operator=(
const _Variadic_union&) =
default;
438 _Variadic_union& operator=(_Variadic_union&&) =
default;
443 _GLIBCXX20_CONSTEXPR ~_Variadic_union()
446 _Uninitialized<_First> _M_first;
447 _Variadic_union<(is_trivially_destructible_v<_Rest> && ...), _Rest...> _M_rest;
455 template<
typename _Tp>
456 struct _Never_valueless_alt
457 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
470 template <typename... _Types>
471 constexpr bool __never_valueless()
473 return _Traits<_Types...>::_S_move_assign
474 && (_Never_valueless_alt<_Types>::value && ...);
478 template<bool __trivially_destructible, typename... _Types>
479 struct _Variant_storage;
481 template <typename... _Types>
482 using __select_index =
483 typename __select_int::_Select_int_base<sizeof...(_Types),
485 unsigned short>::type::value_type;
487 template<typename... _Types>
488 struct _Variant_storage<false, _Types...>
492 : _M_index(static_cast<__index_type>(variant_npos))
495 template<size_t _Np, typename... _Args>
497 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
498 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
505 if (!_M_valid()) [[__unlikely__]]
508 std::__do_visit<void>([](auto&& __this_mem) mutable
510 std::_Destroy(std::__addressof(__this_mem));
511 }, __variant_cast<_Types...>(*this));
513 _M_index = static_cast<__index_type>(variant_npos);
521 _M_valid() const noexcept
523 if constexpr (__variant::__never_valueless<_Types...>())
525 return this->_M_index != __index_type(variant_npos);
528 _Variadic_union<false, _Types...> _M_u;
529 using __index_type = __select_index<_Types...>;
530 __index_type _M_index;
533 template<typename... _Types>
534 struct _Variant_storage<true, _Types...>
538 : _M_index(static_cast<__index_type>(variant_npos))
541 template<
size_t _Np,
typename... _Args>
543 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
544 : _M_u(in_place_index<_Np>, std::
forward<_Args>(__args)...),
550 { _M_index =
static_cast<__index_type
>(variant_npos); }
553 _M_valid() const noexcept
555 if constexpr (__variant::__never_valueless<_Types...>())
563 return this->_M_index !=
static_cast<__index_type
>(variant_npos);
566 _Variadic_union<
true, _Types...> _M_u;
567 using __index_type = __select_index<_Types...>;
568 __index_type _M_index;
572 template<
size_t _Np,
bool _Triv,
typename... _Types,
typename... _Args>
575 __emplace(_Variant_storage<_Triv, _Types...>& __v, _Args&&... __args)
578 auto* __addr = __variant::__construct_n<_Np>(__v._M_u);
585 template<
typename... _Types>
586 using _Variant_storage_alias =
587 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
592 template<bool,
typename... _Types>
593 struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
595 using _Base = _Variant_storage_alias<_Types...>;
599 _Copy_ctor_base(
const _Copy_ctor_base& __rhs)
600 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
602 __variant::__raw_idx_visit(
603 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
605 constexpr size_t __j = __rhs_index;
606 if constexpr (__j != variant_npos)
608 in_place_index<__j>, __rhs_mem);
609 }, __variant_cast<_Types...>(__rhs));
610 this->_M_index = __rhs._M_index;
613 _Copy_ctor_base(_Copy_ctor_base&&) =
default;
614 _Copy_ctor_base& operator=(
const _Copy_ctor_base&) =
default;
615 _Copy_ctor_base& operator=(_Copy_ctor_base&&) =
default;
618 template<
typename... _Types>
619 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
621 using _Base = _Variant_storage_alias<_Types...>;
625 template<
typename... _Types>
626 using _Copy_ctor_alias =
627 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
629 template<bool,
typename... _Types>
630 struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
632 using _Base = _Copy_ctor_alias<_Types...>;
636 _Move_ctor_base(_Move_ctor_base&& __rhs)
637 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
639 __variant::__raw_idx_visit(
640 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
642 constexpr size_t __j = __rhs_index;
643 if constexpr (__j != variant_npos)
647 }, __variant_cast<_Types...>(
std::move(__rhs)));
648 this->_M_index = __rhs._M_index;
651 _Move_ctor_base(
const _Move_ctor_base&) =
default;
652 _Move_ctor_base& operator=(
const _Move_ctor_base&) =
default;
653 _Move_ctor_base& operator=(_Move_ctor_base&&) =
default;
656 template<
typename... _Types>
657 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
659 using _Base = _Copy_ctor_alias<_Types...>;
663 template<
typename... _Types>
664 using _Move_ctor_alias =
665 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
667 template<bool,
typename... _Types>
668 struct _Copy_assign_base : _Move_ctor_alias<_Types...>
670 using _Base = _Move_ctor_alias<_Types...>;
675 operator=(
const _Copy_assign_base& __rhs)
676 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
678 __variant::__raw_idx_visit(
679 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
681 constexpr size_t __j = __rhs_index;
682 if constexpr (__j == variant_npos)
684 else if (this->_M_index == __j)
685 __variant::__get<__j>(*
this) = __rhs_mem;
688 using _Tj =
typename _Nth_type<__j, _Types...>::type;
689 if constexpr (is_nothrow_copy_constructible_v<_Tj>
690 || !is_nothrow_move_constructible_v<_Tj>)
691 __variant::__emplace<__j>(*
this, __rhs_mem);
694 using _Variant = variant<_Types...>;
695 _Variant& __self = __variant_cast<_Types...>(*this);
696 __self = _Variant(in_place_index<__j>, __rhs_mem);
699 }, __variant_cast<_Types...>(__rhs));
703 _Copy_assign_base(
const _Copy_assign_base&) =
default;
704 _Copy_assign_base(_Copy_assign_base&&) =
default;
705 _Copy_assign_base& operator=(_Copy_assign_base&&) =
default;
708 template<
typename... _Types>
709 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
711 using _Base = _Move_ctor_alias<_Types...>;
715 template<
typename... _Types>
716 using _Copy_assign_alias =
717 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
719 template<bool,
typename... _Types>
720 struct _Move_assign_base : _Copy_assign_alias<_Types...>
722 using _Base = _Copy_assign_alias<_Types...>;
727 operator=(_Move_assign_base&& __rhs)
728 noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
730 __variant::__raw_idx_visit(
731 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
733 constexpr size_t __j = __rhs_index;
734 if constexpr (__j != variant_npos)
736 if (this->_M_index == __j)
737 __variant::__get<__j>(*
this) =
std::move(__rhs_mem);
740 using _Tj =
typename _Nth_type<__j, _Types...>::type;
741 if constexpr (is_nothrow_move_constructible_v<_Tj>)
742 __variant::__emplace<__j>(*
this,
std::move(__rhs_mem));
745 using _Variant = variant<_Types...>;
746 _Variant& __self = __variant_cast<_Types...>(*this);
747 __self.template emplace<__j>(
std::move(__rhs_mem));
753 }, __variant_cast<_Types...>(__rhs));
757 _Move_assign_base(
const _Move_assign_base&) =
default;
758 _Move_assign_base(_Move_assign_base&&) =
default;
759 _Move_assign_base& operator=(
const _Move_assign_base&) =
default;
762 template<
typename... _Types>
763 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
765 using _Base = _Copy_assign_alias<_Types...>;
769 template<
typename... _Types>
770 using _Move_assign_alias =
771 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
773 template<
typename... _Types>
774 struct _Variant_base : _Move_assign_alias<_Types...>
776 using _Base = _Move_assign_alias<_Types...>;
779 _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
780 : _Variant_base(in_place_index<0>) { }
782 template<
size_t _Np,
typename... _Args>
784 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
785 : _Base(__i, std::
forward<_Args>(__args)...)
788 _Variant_base(
const _Variant_base&) =
default;
789 _Variant_base(_Variant_base&&) =
default;
790 _Variant_base& operator=(
const _Variant_base&) =
default;
791 _Variant_base& operator=(_Variant_base&&) =
default;
794 template<
typename _Tp,
typename... _Types>
795 inline constexpr bool __exactly_once
796 = std::__find_uniq_type_in_pack<_Tp, _Types...>() <
sizeof...(_Types);
799 template<
typename _Ti>
struct _Arr { _Ti _M_x[1]; };
802 template<
size_t _Ind,
typename _Tp,
typename _Ti,
typename =
void>
807 void _S_fun() =
delete;
811 template<
size_t _Ind,
typename _Tp,
typename _Ti>
812 struct _Build_FUN<_Ind, _Tp, _Ti,
816 static integral_constant<size_t, _Ind> _S_fun(_Ti);
819 template<
typename _Tp,
typename _Variant,
823 template<
typename _Tp,
typename... _Ti,
size_t... _Ind>
825 : _Build_FUN<_Ind, _Tp, _Ti>...
827 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
832 template<
typename _Tp,
typename _Variant>
837 template<
typename _Tp,
typename _Variant,
typename =
void>
838 inline constexpr size_t
839 __accepted_index = variant_npos;
841 template<
typename _Tp,
typename _Variant>
842 inline constexpr size_t
843 __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
844 = _FUN_type<_Tp, _Variant>::value;
846 template<
typename _Maybe_variant_cookie,
typename _Variant,
847 typename = __remove_cvref_t<_Variant>>
848 inline constexpr bool
849 __extra_visit_slot_needed =
false;
851 template<
typename _Var,
typename... _Types>
852 inline constexpr bool
853 __extra_visit_slot_needed<__variant_cookie, _Var, variant<_Types...>>
854 = !__variant::__never_valueless<_Types...>();
856 template<
typename _Var,
typename... _Types>
857 inline constexpr bool
858 __extra_visit_slot_needed<__variant_idx_cookie, _Var, variant<_Types...>>
859 = !__variant::__never_valueless<_Types...>();
862 template<
typename _Tp,
size_t... _Dimensions>
866 template<
typename _Tp>
867 struct _Multi_array<_Tp>
870 struct __untag_result
872 {
using element_type = _Tp; };
874#pragma GCC diagnostic push
875#pragma GCC diagnostic ignored "-Wignored-qualifiers"
876 template <
typename... _Args>
877 struct __untag_result<const void(*)(_Args...)>
879 {
using element_type = void(*)(_Args...); };
880#pragma GCC diagnostic pop
882 template <
typename... _Args>
883 struct __untag_result<__variant_cookie(*)(_Args...)>
885 {
using element_type = void(*)(_Args...); };
887 template <
typename... _Args>
888 struct __untag_result<__variant_idx_cookie(*)(_Args...)>
890 {
using element_type = void(*)(_Args...); };
892 template <
typename _Res,
typename... _Args>
893 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
895 {
using element_type = _Res(*)(_Args...); };
897 using __result_is_deduced = __untag_result<_Tp>;
899 constexpr const typename __untag_result<_Tp>::element_type&
903 typename __untag_result<_Tp>::element_type _M_data;
907 template<
typename _Ret,
909 typename... _Variants,
910 size_t __first,
size_t... __rest>
911 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
913 static constexpr size_t __index =
914 sizeof...(_Variants) -
sizeof...(__rest) - 1;
916 using _Variant =
typename _Nth_type<__index, _Variants...>::type;
918 static constexpr int __do_cookie =
919 __extra_visit_slot_needed<_Ret, _Variant> ? 1 : 0;
921 using _Tp = _Ret(*)(_Visitor, _Variants...);
923 template<
typename... _Args>
924 constexpr decltype(
auto)
925 _M_access(
size_t __first_index, _Args... __rest_indices)
const
927 return _M_arr[__first_index + __do_cookie]
928 ._M_access(__rest_indices...);
931 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
961 template<
typename _Array_type,
typename _Index_seq>
962 struct __gen_vtable_impl;
971 template<
typename _Result_type,
typename _Visitor,
size_t... __dimensions,
972 typename... _Variants,
size_t... __indices>
973 struct __gen_vtable_impl<
974 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
979 _Variants...>::type>;
981 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
984 static constexpr _Array_type
987 _Array_type __vtable{};
993 template<
size_t... __var_indices>
994 static constexpr void
995 _S_apply_all_alts(_Array_type& __vtable,
998 if constexpr (__extra_visit_slot_needed<_Result_type, _Next>)
999 (_S_apply_single_alt<true, __var_indices>(
1000 __vtable._M_arr[__var_indices + 1],
1001 &(__vtable._M_arr[0])), ...);
1003 (_S_apply_single_alt<false, __var_indices>(
1004 __vtable._M_arr[__var_indices]), ...);
1007 template<
bool __do_cookie,
size_t __index,
typename _Tp>
1008 static constexpr void
1009 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element =
nullptr)
1011 if constexpr (__do_cookie)
1013 __element = __gen_vtable_impl<
1016 *__cookie_element = __gen_vtable_impl<
1022 auto __tmp_element = __gen_vtable_impl<
1025 static_assert(is_same_v<_Tp,
decltype(__tmp_element)>,
1026 "std::visit requires the visitor to have the same "
1027 "return type for all alternatives of a variant");
1028 __element = __tmp_element;
1036 template<
typename _Result_type,
typename _Visitor,
typename... _Variants,
1037 size_t... __indices>
1038 struct __gen_vtable_impl<
1039 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
1043 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
1045 template<
size_t __index,
typename _Variant>
1046 static constexpr decltype(
auto)
1047 __element_by_index_or_cookie(_Variant&& __var)
noexcept
1049 if constexpr (__index != variant_npos)
1052 return __variant_cookie{};
1055 static constexpr decltype(
auto)
1056 __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1058 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1062 __element_by_index_or_cookie<__indices>(
1064 integral_constant<size_t, __indices>()...);
1065 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1068 __element_by_index_or_cookie<__indices>(
1070 else if constexpr (_Array_type::__result_is_deduced::value)
1073 __element_by_index_or_cookie<__indices>(
1076 return std::__invoke_r<_Result_type>(
1081 static constexpr auto
1084 if constexpr (_Array_type::__result_is_deduced::value)
1086 constexpr bool __visit_ret_type_mismatch =
1087 !is_same_v<
typename _Result_type::type,
1090 if constexpr (__visit_ret_type_mismatch)
1092 struct __cannot_match {};
1093 return __cannot_match{};
1096 return _Array_type{&__visit_invoke};
1099 return _Array_type{&__visit_invoke};
1103 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1107 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1108 variant_size_v<remove_reference_t<_Variants>>...>;
1110 static constexpr _Array_type _S_vtable
1111 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1114#if ! _GLIBCXX_INLINE_VERSION
1115 template<
size_t _Nm,
typename _Tp>
1116 struct _Base_dedup :
public _Tp { };
1118 template<
typename _Variant,
typename __indices>
1119 struct _Variant_hash_base;
1121 template<
typename... _Types,
size_t... __indices>
1122 struct _Variant_hash_base<variant<_Types...>,
1124 : _Base_dedup<__indices, __hash_empty_base<remove_const_t<_Types>>>...
1129 template<
size_t _Np,
typename _Variant,
1133 = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1136 template<
typename _Visitor,
typename... _Variants>
1137 using __visit_result_t
1138 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1140 template<
typename _Tp,
typename... _Types>
1141 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1143 template <
typename _Visitor,
typename _Variant,
size_t... _Idxs>
1146 return __same_types<
1147 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1154 template<
typename _Tp,
typename... _Types>
1156 holds_alternative(
const variant<_Types...>& __v)
noexcept
1158 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1159 "T must occur exactly once in alternatives");
1160 return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>();
1163 template<
typename _Tp,
typename... _Types>
1165 get(variant<_Types...>& __v)
1167 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1168 "T must occur exactly once in alternatives");
1169 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1170 return std::get<__n>(__v);
1173 template<
typename _Tp,
typename... _Types>
1175 get(variant<_Types...>&& __v)
1177 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1178 "T must occur exactly once in alternatives");
1179 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1183 template<
typename _Tp,
typename... _Types>
1184 constexpr const _Tp&
1185 get(
const variant<_Types...>& __v)
1187 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1188 "T must occur exactly once in alternatives");
1189 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1190 return std::get<__n>(__v);
1193 template<
typename _Tp,
typename... _Types>
1194 constexpr const _Tp&&
1195 get(
const variant<_Types...>&& __v)
1197 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1198 "T must occur exactly once in alternatives");
1199 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1203 template<
size_t _Np,
typename... _Types>
1204 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1205 get_if(variant<_Types...>* __ptr)
noexcept
1207 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1208 static_assert(_Np <
sizeof...(_Types),
1209 "The index must be in [0, number of alternatives)");
1210 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1211 if (__ptr && __ptr->index() == _Np)
1216 template<
size_t _Np,
typename... _Types>
1218 add_pointer_t<
const variant_alternative_t<_Np, variant<_Types...>>>
1219 get_if(
const variant<_Types...>* __ptr)
noexcept
1221 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1222 static_assert(_Np <
sizeof...(_Types),
1223 "The index must be in [0, number of alternatives)");
1224 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1225 if (__ptr && __ptr->index() == _Np)
1230 template<
typename _Tp,
typename... _Types>
1232 get_if(variant<_Types...>* __ptr)
noexcept
1234 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1235 "T must occur exactly once in alternatives");
1236 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1237 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1238 return std::get_if<__n>(__ptr);
1241 template<
typename _Tp,
typename... _Types>
1243 get_if(
const variant<_Types...>* __ptr)
noexcept
1245 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1246 "T must occur exactly once in alternatives");
1247 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1248 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1249 return std::get_if<__n>(__ptr);
1252namespace __detail::__variant
1254 template<
typename _Ret,
typename _Vp,
typename _Op>
1256 __compare(_Ret __ret,
const _Vp& __lhs,
const _Vp& __rhs, _Op __op)
1258 __variant::__raw_idx_visit(
1259 [&__ret, &__lhs, __op] (
auto&& __rhs_mem,
auto __rhs_index)
mutable
1261 if constexpr (__rhs_index != variant_npos)
1263 if (__lhs.index() == __rhs_index.value)
1265 auto& __this_mem = std::get<__rhs_index>(__lhs);
1266 __ret = __op(__this_mem, __rhs_mem);
1270 __ret = __op(__lhs.index() + 1, __rhs_index + 1);
1276 template<
typename... _Types>
1277#if __cpp_lib_concepts
1278 requires ((
requires (
const _Types& __t) {
1282 operator== [[nodiscard]] (
const variant<_Types...>& __lhs,
1283 const variant<_Types...>& __rhs)
1285 namespace __variant = __detail::__variant;
1286 return __variant::__compare(
true, __lhs, __rhs,
1287 [](
auto&& __l,
auto&& __r) ->
bool {
1292 template<
typename... _Types>
1293#if __cpp_lib_concepts
1294 requires ((
requires (
const _Types& __t) {
1298 operator!= [[nodiscard]] (
const variant<_Types...>& __lhs,
1299 const variant<_Types...>& __rhs)
1301 namespace __variant = __detail::__variant;
1302 return __variant::__compare(
true, __lhs, __rhs,
1303 [](
auto&& __l,
auto&& __r) ->
bool {
1308 template<
typename... _Types>
1309#if __cpp_lib_concepts
1310 requires ((
requires (
const _Types& __t) {
1314 operator< [[nodiscard]] (
const variant<_Types...>& __lhs,
1315 const variant<_Types...>& __rhs)
1317 namespace __variant = __detail::__variant;
1318 return __variant::__compare(
true, __lhs, __rhs,
1319 [](
auto&& __l,
auto&& __r) ->
bool {
1324 template<
typename... _Types>
1325#if __cpp_lib_concepts
1326 requires ((
requires (
const _Types& __t) {
1330 operator<= [[nodiscard]] (
const variant<_Types...>& __lhs,
1331 const variant<_Types...>& __rhs)
1333 namespace __variant = __detail::__variant;
1334 return __variant::__compare(
true, __lhs, __rhs,
1335 [](
auto&& __l,
auto&& __r) ->
bool {
1340 template<
typename... _Types>
1341#if __cpp_lib_concepts
1342 requires ((
requires (
const _Types& __t) {
1346 operator> [[nodiscard]] (
const variant<_Types...>& __lhs,
1347 const variant<_Types...>& __rhs)
1349 namespace __variant = __detail::__variant;
1350 return __variant::__compare(
true, __lhs, __rhs,
1351 [](
auto&& __l,
auto&& __r) ->
bool {
1356 template<
typename... _Types>
1357#if __cpp_lib_concepts
1358 requires ((
requires (
const _Types& __t) {
1362 operator>= [[nodiscard]] (
const variant<_Types...>& __lhs,
1363 const variant<_Types...>& __rhs)
1365 namespace __variant = __detail::__variant;
1366 return __variant::__compare(
true, __lhs, __rhs,
1367 [](
auto&& __l,
auto&& __r) ->
bool {
1372#ifdef __cpp_lib_three_way_comparison
1373 template<
typename... _Types>
1374 requires (three_way_comparable<_Types> && ...)
1376 common_comparison_category_t<compare_three_way_result_t<_Types>...>
1377 operator<=>(
const variant<_Types...>& __v,
const variant<_Types...>& __w)
1379 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1380 = strong_ordering::equal;
1381 namespace __variant = __detail::__variant;
1382 return __variant::__compare(__ret, __v, __w,
1383 [](
auto&& __l,
auto&& __r) {
1389 template<
typename _Visitor,
typename... _Variants>
1390 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1391 visit(_Visitor&&, _Variants&&...);
1393#if __cplusplus > 201703L
1394 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1396 visit(_Visitor&&, _Variants&&...);
1399 template<
typename... _Types>
1400 _GLIBCXX20_CONSTEXPR
1401 inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1402 && (is_swappable_v<_Types> && ...)>
1403 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1404 noexcept(
noexcept(__lhs.swap(__rhs)))
1405 { __lhs.swap(__rhs); }
1409 template<
typename... _Types>
1410 enable_if_t<!((is_move_constructible_v<_Types> && ...)
1411 && (is_swappable_v<_Types> && ...))>
1412 swap(variant<_Types...>&, variant<_Types...>&) =
delete;
1414#if __cpp_lib_constexpr_exceptions >= 202502L
1415#define _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS constexpr
1417#define _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
1419 [[noreturn]] _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
void
1420 __throw_bad_variant_access(
unsigned);
1422 class bad_variant_access :
public exception
1425 _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS bad_variant_access() noexcept { }
1427 _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
const char* what()
1428 const noexcept
override
1429 {
return _M_reason; }
1433 _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
1434 bad_variant_access(
const char* __reason) noexcept : _M_reason(__reason) { }
1437 const char* _M_reason =
"bad variant access";
1439 friend _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
void
1440 __throw_bad_variant_access([[maybe_unused]]
unsigned __n)
1442 [[maybe_unused]]
static constexpr const char* __reasons[] = {
1443 "std::get: wrong index for variant",
1444 "std::get: variant is valueless",
1445 "std::visit: variant is valueless",
1446 "std::visit<R>: variant is valueless",
1448 _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__reasons[__n % 4u]));
1450#undef _GLIBCXX_CONSTEXPR_BAD_VARIANT_ACCESS
1453 template<
typename... _Types>
1455 :
private __detail::__variant::_Variant_base<_Types...>,
1456 private _Enable_copy_move<
1457 __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1458 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1459 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1460 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1464 template <
typename... _UTypes,
typename _Tp>
1465 friend _GLIBCXX20_CONSTEXPR
decltype(
auto)
1466 __variant_cast(_Tp&&);
1468 static_assert(
sizeof...(_Types) > 0,
1469 "variant must have at least one alternative");
1470 static_assert(((std::is_object_v<_Types> && !is_array_v<_Types>) && ...),
1471 "variant alternatives must be non-array object types");
1473 using _Base = __detail::__variant::_Variant_base<_Types...>;
1475 template<
typename _Tp>
1476 static constexpr bool __not_self
1477 = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1479 template<
typename _Tp>
1480 static constexpr bool
1481 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1483 template<
typename _Tp>
1484 static constexpr size_t __accepted_index
1485 = __detail::__variant::__accepted_index<_Tp, variant>;
1487 template<
size_t _Np,
typename =
enable_if_t<(_Np <
sizeof...(_Types))>>
1488 using __to_type =
typename _Nth_type<_Np, _Types...>::type;
1490 template<
typename _Tp,
typename = enable_if_t<__not_self<_Tp>>>
1491 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1493 template<
typename _Tp>
1494 static constexpr size_t __index_of
1495 = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1497 using _Traits = __detail::__variant::_Traits<_Types...>;
1499 template<
typename _Tp>
1500 static constexpr bool __not_in_place_tag
1501 = !__is_in_place_type_v<__remove_cvref_t<_Tp>>
1502 && !__is_in_place_index_v<__remove_cvref_t<_Tp>>;
1506 variant()
requires is_default_constructible_v<__to_type<0>> = default;
1508 template<
typename _Tp0 = __to_type<0>,
1509 typename = enable_if_t<is_default_constructible_v<_Tp0>>>
1511 variant() noexcept(is_nothrow_default_constructible_v<__to_type<0>>)
1515 variant(
const variant& __rhs) =
default;
1516 variant(variant&&) =
default;
1517 variant& operator=(
const variant&) =
default;
1518 variant& operator=(variant&&) =
default;
1519 _GLIBCXX20_CONSTEXPR ~variant() =
default;
1521 template<
typename _Tp,
1523 typename = enable_if_t<__not_in_place_tag<_Tp>>,
1524 typename _Tj = __accepted_type<_Tp&&>,
1525 typename = enable_if_t<__exactly_once<_Tj>
1526 && is_constructible_v<_Tj, _Tp>>>
1529 noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1530 : variant(in_place_index<__accepted_index<_Tp>>,
1534 template<
typename _Tp,
typename... _Args,
1535 typename = enable_if_t<__exactly_once<_Tp>
1536 && is_constructible_v<_Tp, _Args...>>>
1538 variant(in_place_type_t<_Tp>, _Args&&... __args)
1539 : variant(in_place_index<__index_of<_Tp>>,
1540 std::
forward<_Args>(__args)...)
1543 template<
typename _Tp,
typename _Up,
typename... _Args,
1544 typename = enable_if_t<__exactly_once<_Tp>
1545 && is_constructible_v<_Tp,
1546 initializer_list<_Up>&, _Args...>>>
1548 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1550 : variant(in_place_index<__index_of<_Tp>>, __il,
1551 std::
forward<_Args>(__args)...)
1554 template<
size_t _Np,
typename... _Args,
1555 typename _Tp = __to_type<_Np>,
1556 typename =
enable_if_t<is_constructible_v<_Tp, _Args...>>>
1558 variant(in_place_index_t<_Np>, _Args&&... __args)
1559 : _Base(in_place_index<_Np>, std::
forward<_Args>(__args)...)
1562 template<
size_t _Np,
typename _Up,
typename... _Args,
1563 typename _Tp = __to_type<_Np>,
1565 initializer_list<_Up>&,
1568 variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1570 : _Base(in_place_index<_Np>, __il, std::
forward<_Args>(__args)...)
1573 template<
typename _Tp>
1574 _GLIBCXX20_CONSTEXPR
1575 enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1576 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1577 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1579 operator=(_Tp&& __rhs)
1580 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1581 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1583 constexpr auto __index = __accepted_index<_Tp>;
1584 if (index() == __index)
1588 using _Tj = __accepted_type<_Tp&&>;
1589 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1590 || !is_nothrow_move_constructible_v<_Tj>)
1600 template<
typename _Tp,
typename... _Args>
1601 _GLIBCXX20_CONSTEXPR
1602 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1604 emplace(_Args&&... __args)
1606 constexpr size_t __index = __index_of<_Tp>;
1610 template<
typename _Tp,
typename _Up,
typename... _Args>
1611 _GLIBCXX20_CONSTEXPR
1612 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1613 && __exactly_once<_Tp>,
1615 emplace(initializer_list<_Up> __il, _Args&&... __args)
1617 constexpr size_t __index = __index_of<_Tp>;
1621 template<
size_t _Np,
typename... _Args>
1622 _GLIBCXX20_CONSTEXPR
1623 enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>,
1625 emplace(_Args&&... __args)
1627 namespace __variant = std::__detail::__variant;
1628 using type =
typename _Nth_type<_Np, _Types...>::type;
1631 if constexpr (is_nothrow_constructible_v<type, _Args...>)
1635 else if constexpr (is_scalar_v<type>)
1640 __variant::__emplace<_Np>(*
this, __tmp);
1642 else if constexpr (__variant::_Never_valueless_alt<type>()
1643 && _Traits::_S_move_assign)
1646 variant __tmp(in_place_index<_Np>,
1657 return std::get<_Np>(*
this);
1660 template<
size_t _Np,
typename _Up,
typename... _Args>
1661 _GLIBCXX20_CONSTEXPR
1662 enable_if_t<is_constructible_v<__to_type<_Np>,
1663 initializer_list<_Up>&, _Args...>,
1665 emplace(initializer_list<_Up> __il, _Args&&... __args)
1667 namespace __variant = std::__detail::__variant;
1668 using type =
typename _Nth_type<_Np, _Types...>::type;
1671 if constexpr (is_nothrow_constructible_v<type,
1672 initializer_list<_Up>&,
1675 __variant::__emplace<_Np>(*
this, __il,
1678 else if constexpr (__variant::_Never_valueless_alt<type>()
1679 && _Traits::_S_move_assign)
1682 variant __tmp(in_place_index<_Np>, __il,
1691 __variant::__emplace<_Np>(*
this, __il,
1694 return std::get<_Np>(*
this);
1697 template<
size_t _Np,
typename... _Args>
1698 enable_if_t<!(_Np <
sizeof...(_Types))> emplace(_Args&&...) =
delete;
1700 template<
typename _Tp,
typename... _Args>
1701 enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) =
delete;
1703 constexpr bool valueless_by_exception() const noexcept
1704 {
return !this->_M_valid(); }
1706 constexpr size_t index() const noexcept
1708 using __index_type =
typename _Base::__index_type;
1709 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1710 return this->_M_index;
1711 else if constexpr (
sizeof...(_Types) <= __index_type(-1) / 2)
1712 return make_signed_t<__index_type>(this->_M_index);
1714 return size_t(__index_type(this->_M_index + 1)) - 1;
1717 _GLIBCXX20_CONSTEXPR
1719 swap(variant& __rhs)
1720 noexcept((__is_nothrow_swappable<_Types>::value && ...)
1721 && is_nothrow_move_constructible_v<variant>)
1723 static_assert((is_move_constructible_v<_Types> && ...));
1726 if (__rhs.valueless_by_exception()) [[__unlikely__]]
1728 if (!this->valueless_by_exception()) [[__likely__]]
1733 namespace __variant = __detail::__variant;
1735 __variant::__raw_idx_visit(
1736 [
this, &__rhs](
auto&& __rhs_mem,
auto __rhs_index)
mutable
1738 constexpr size_t __j = __rhs_index;
1739 if constexpr (__j != variant_npos)
1741 if (this->index() == __j)
1744 swap(std::get<__j>(*
this), __rhs_mem);
1750 if constexpr (_Traits::_S_trivial_move_assign)
1753 __variant::__raw_idx_visit(
1754 [&__rhs](
auto&& __this_mem,
auto __this_index)
mutable
1756 constexpr size_t __k = __this_index;
1757 if constexpr (__k != variant_npos)
1758 __variant::__emplace<__k>(__rhs,
1762 __variant::__emplace<__j>(*
this,
std::move(__tmp));
1768#if __cpp_lib_variant >= 202306L
1778 template<
int = 0,
typename _Self,
typename _Visitor>
1779 constexpr decltype(
auto)
1780 visit(
this _Self&& __self, _Visitor&& __vis)
1782 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1783 const variant, variant>;
1784 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1796 template<
typename _Res,
typename _Self,
typename _Visitor>
1798 visit(
this _Self&& __self, _Visitor&& __vis)
1800 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1801 const variant, variant>;
1802 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1809 template<
size_t _Np,
typename _Vp>
1810 friend constexpr decltype(
auto)
1811 __detail::__variant::__get(_Vp&& __v)
noexcept;
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>(__v);
1825 template<
size_t _Np,
typename... _Types>
1826 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1827 get(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>(
std::move(__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>(__v);
1847 template<
size_t _Np,
typename... _Types>
1848 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1849 get(
const variant<_Types...>&& __v)
1851 static_assert(_Np <
sizeof...(_Types),
1852 "The index must be in [0, number of alternatives)");
1853 if (__v.index() != _Np)
1854 __throw_bad_variant_access(__v.valueless_by_exception());
1855 return __detail::__variant::__get<_Np>(
std::move(__v));
1859 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1860 constexpr decltype(
auto)
1861 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1864 if constexpr (
sizeof...(_Variants) == 0)
1866 if constexpr (is_void_v<_Result_type>)
1873 constexpr size_t __max = 11;
1876 using _V0 =
typename _Nth_type<0, _Variants...>::type;
1878 constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
1880 if constexpr (
sizeof...(_Variants) > 1 || __n > __max)
1883 constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1884 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1886 auto __func_ptr = __vtable._M_access(__variants.index()...);
1894 = [](_V0& __v, ...) -> _V0& {
return __v; }(__variants...);
1896 using __detail::__variant::_Multi_array;
1897 using __detail::__variant::__gen_vtable_impl;
1898 using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0&&)>;
1900#ifdef _GLIBCXX_DEBUG
1901# define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap
1903# define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable
1906#define _GLIBCXX_VISIT_CASE(N) \
1909 if constexpr (N < __n) \
1911 return __gen_vtable_impl<_Ma, index_sequence<N>>:: \
1912 __visit_invoke(std::forward<_Visitor>(__visitor), \
1913 std::forward<_V0>(__v0)); \
1915 else _GLIBCXX_VISIT_UNREACHABLE(); \
1918 switch (__v0.index())
1920 _GLIBCXX_VISIT_CASE(0)
1921 _GLIBCXX_VISIT_CASE(1)
1922 _GLIBCXX_VISIT_CASE(2)
1923 _GLIBCXX_VISIT_CASE(3)
1924 _GLIBCXX_VISIT_CASE(4)
1925 _GLIBCXX_VISIT_CASE(5)
1926 _GLIBCXX_VISIT_CASE(6)
1927 _GLIBCXX_VISIT_CASE(7)
1928 _GLIBCXX_VISIT_CASE(8)
1929 _GLIBCXX_VISIT_CASE(9)
1930 _GLIBCXX_VISIT_CASE(10)
1932 using
__detail::__variant::__variant_idx_cookie;
1933 using
__detail::__variant::__variant_cookie;
1934 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
1935 || is_same_v<_Result_type, __variant_cookie>)
1938 return __gen_vtable_impl<_Ma, _Npos>::
1943 _GLIBCXX_VISIT_UNREACHABLE();
1945 _GLIBCXX_VISIT_UNREACHABLE();
1947#undef _GLIBCXX_VISIT_CASE
1948#undef _GLIBCXX_VISIT_UNREACHABLE
1954 template<
typename _Visitor,
typename... _Variants>
1955 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1956 visit(_Visitor&& __visitor, _Variants&&... __variants)
1958 namespace __variant = std::__detail::__variant;
1960 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1961 __throw_bad_variant_access(2);
1964 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1966 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1968 if constexpr (
sizeof...(_Variants) == 1)
1972 constexpr bool __visit_rettypes_match = __detail::__variant::
1973 __check_visitor_results<_Visitor, _Vp>(
1975 if constexpr (!__visit_rettypes_match)
1977 static_assert(__visit_rettypes_match,
1978 "std::visit requires the visitor to have the same "
1979 "return type for all alternatives of a variant");
1983 return std::__do_visit<_Tag>(
1985 static_cast<_Vp
>(__variants)...);
1988 return std::__do_visit<_Tag>(
1993#if __cplusplus > 201703L
1994 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1996 visit(_Visitor&& __visitor, _Variants&&... __variants)
1998 namespace __variant = std::__detail::__variant;
2000 if ((__variant::__as(__variants).valueless_by_exception() || ...))
2001 __throw_bad_variant_access(3);
2009 template<
typename... _Types>
2010 struct __variant_hash
2012#if __cplusplus < 202002L
2013 using result_type [[__deprecated__]] = size_t;
2014 using argument_type [[__deprecated__]] = variant<_Types...>;
2018 operator()(
const variant<_Types...>& __t)
const
2019 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
2022 __detail::__variant::__raw_visit(
2023 [&__t, &__ret](
auto&& __t_mem)
mutable
2025 using _Type = __remove_cvref_t<
decltype(__t_mem)>;
2026 if constexpr (!is_same_v<_Type,
2027 __detail::__variant::__variant_cookie>)
2028 __ret = std::hash<size_t>{}(__t.index())
2029 + std::hash<_Type>{}(__t_mem);
2031 __ret = std::hash<size_t>{}(__t.index());
2038 template<
typename... _Types>
2039 struct hash<variant<_Types...>>
2040 : __conditional_t<(__is_hash_enabled_for<remove_const_t<_Types>> && ...),
2041 __variant_hash<_Types...>,
2042 __hash_not_enabled<variant<_Types...>>>
2043#if ! _GLIBCXX_INLINE_VERSION
2044 , __detail::__variant::_Variant_hash_base<variant<_Types...>,
2045 index_sequence_for<_Types...>>
2049 template<
typename... _Types>
2051 : bool_constant<(__is_fast_hash<_Types>::value && ...)>
2054_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.
[concept.convertible], concept convertible_to