29#ifndef _GLIBCXX_VARIANT
30#define _GLIBCXX_VARIANT 1
32#pragma GCC system_header
34#define __glibcxx_want_freestanding_variant
35#define __glibcxx_want_variant
38#ifdef __cpp_lib_variant
49#if __cplusplus >= 202002L
54#if __cpp_lib_variant < 202106L
59namespace std _GLIBCXX_VISIBILITY(default)
61_GLIBCXX_BEGIN_NAMESPACE_VERSION
63 template<
typename... _Types>
class tuple;
64 template<
typename... _Types>
class variant;
65 template <
typename>
struct hash;
67 template<
typename _Variant>
70 template<
typename _Variant>
71 struct variant_size<const _Variant> : variant_size<_Variant> {};
73 template<
typename _Variant>
74 struct variant_size<volatile _Variant> : variant_size<_Variant> {};
76 template<
typename _Variant>
77 struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
79 template<
typename... _Types>
80 struct variant_size<variant<_Types...>>
81 : std::integral_constant<size_t, sizeof...(_Types)> {};
83 template<
typename _Variant>
84 inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
86 template<
typename... _Types>
87 inline constexpr size_t
88 variant_size_v<variant<_Types...>> =
sizeof...(_Types);
90 template<
typename... _Types>
91 inline constexpr size_t
92 variant_size_v<
const variant<_Types...>> =
sizeof...(_Types);
94 template<
size_t _Np,
typename _Variant>
95 struct variant_alternative;
97 template<
size_t _Np,
typename... _Types>
98 struct variant_alternative<_Np, variant<_Types...>>
100 static_assert(_Np <
sizeof...(_Types));
102 using type =
typename _Nth_type<_Np, _Types...>::type;
105 template<
size_t _Np,
typename _Variant>
106 using variant_alternative_t =
107 typename variant_alternative<_Np, _Variant>::type;
109 template<
size_t _Np,
typename _Variant>
110 struct variant_alternative<_Np, const _Variant>
111 {
using type =
const variant_alternative_t<_Np, _Variant>; };
113 template<
size_t _Np,
typename _Variant>
114 struct variant_alternative<_Np, volatile _Variant>
115 {
using type =
volatile variant_alternative_t<_Np, _Variant>; };
117 template<
size_t _Np,
typename _Variant>
118 struct variant_alternative<_Np, const volatile _Variant>
119 {
using type =
const volatile variant_alternative_t<_Np, _Variant>; };
121 inline constexpr size_t variant_npos = -1;
123 template<
size_t _Np,
typename... _Types>
124 constexpr variant_alternative_t<_Np, variant<_Types...>>&
125 get(variant<_Types...>&);
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...>>
const&
133 get(
const 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<
typename _Result_type,
typename _Visitor,
typename... _Variants>
140 constexpr decltype(
auto)
141 __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
143 template <
typename... _Types,
typename _Tp>
146 __variant_cast(_Tp&& __rhs)
148 if constexpr (is_lvalue_reference_v<_Tp>)
150 if constexpr (is_const_v<remove_reference_t<_Tp>>)
151 return static_cast<const variant<_Types...
>&>(__rhs);
153 return static_cast<variant<_Types...
>&>(__rhs);
156 return static_cast<variant<_Types...
>&&>(__rhs);
164 struct __variant_cookie {};
166 struct __variant_idx_cookie {
using type = __variant_idx_cookie; };
168 template<
typename _Tp>
struct __deduce_visit_result {
using type = _Tp; };
171 template<
typename _Visitor,
typename... _Variants>
173 __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
180 template<
typename _Visitor,
typename... _Variants>
182 __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
190 template<
typename... _Types>
191 constexpr std::variant<_Types...>&
192 __as(std::variant<_Types...>& __v)
noexcept
195 template<
typename... _Types>
196 constexpr const std::variant<_Types...>&
197 __as(
const std::variant<_Types...>& __v)
noexcept
200 template<
typename... _Types>
201 constexpr std::variant<_Types...>&&
202 __as(std::variant<_Types...>&& __v)
noexcept
205 template<
typename... _Types>
206 constexpr const std::variant<_Types...>&&
207 __as(
const std::variant<_Types...>&& __v)
noexcept
216 template<
typename _Type,
bool = std::is_trivially_destructible_v<_Type>>
217 struct _Uninitialized;
219 template<
typename _Type>
220 struct _Uninitialized<_Type, true>
222 template<
typename... _Args>
224 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
225 : _M_storage(std::
forward<_Args>(__args)...)
228 constexpr const _Type& _M_get() const & noexcept
229 {
return _M_storage; }
231 constexpr _Type& _M_get() &
noexcept
232 {
return _M_storage; }
234 constexpr const _Type&& _M_get() const && noexcept
237 constexpr _Type&& _M_get() &&
noexcept
243 template<
typename _Type>
244 struct _Uninitialized<_Type, false>
246#if __cpp_lib_variant >= 202106L
247 template<
typename... _Args>
249 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
250 : _M_storage(std::
forward<_Args>(__args)...)
253 constexpr ~_Uninitialized() { }
255 _Uninitialized(
const _Uninitialized&) =
default;
256 _Uninitialized(_Uninitialized&&) =
default;
257 _Uninitialized& operator=(
const _Uninitialized&) =
default;
258 _Uninitialized& operator=(_Uninitialized&&) =
default;
260 constexpr const _Type& _M_get() const & noexcept
261 {
return _M_storage; }
263 constexpr _Type& _M_get() &
noexcept
264 {
return _M_storage; }
266 constexpr const _Type&& _M_get() const && noexcept
269 constexpr _Type&& _M_get() &&
noexcept
272 struct _Empty_byte { };
275 _Empty_byte _M_empty;
279 template<
typename... _Args>
281 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
287 const _Type& _M_get() const & noexcept
288 {
return *_M_storage._M_ptr(); }
290 _Type& _M_get() &
noexcept
291 {
return *_M_storage._M_ptr(); }
293 const _Type&& _M_get() const && noexcept
294 {
return std::move(*_M_storage._M_ptr()); }
296 _Type&& _M_get() &&
noexcept
297 {
return std::move(*_M_storage._M_ptr()); }
299 __gnu_cxx::__aligned_membuf<_Type> _M_storage;
303 template<
size_t _Np,
typename _Union>
304 constexpr decltype(
auto)
305 __get_n(_Union&& __u)
noexcept
307 if constexpr (_Np == 0)
309 else if constexpr (_Np == 1)
311 else if constexpr (_Np == 2)
314 return __variant::__get_n<_Np - 3>(
319 template<
size_t _Np,
typename _Variant>
320 constexpr decltype(
auto)
321 __get(_Variant&& __v)
noexcept
325 template<
size_t _Np,
typename _Union>
326 constexpr decltype(
auto)
327 __construct_n(_Union& __u)
noexcept
329 if constexpr (_Np == 0)
330 return &__u._M_first;
331 else if constexpr (_Np == 1)
334 return &__u._M_rest._M_first;
336 else if constexpr (_Np == 2)
340 return &__u._M_rest._M_rest._M_first;
347 return __variant::__construct_n<_Np - 3>(__u._M_rest._M_rest._M_rest);
351 template<
typename... _Types>
354 static constexpr bool _S_default_ctor =
355 is_default_constructible_v<
typename _Nth_type<0, _Types...>::type>;
356 static constexpr bool _S_copy_ctor =
357 (is_copy_constructible_v<_Types> && ...);
358 static constexpr bool _S_move_ctor =
359 (is_move_constructible_v<_Types> && ...);
360 static constexpr bool _S_copy_assign =
362 && (is_copy_assignable_v<_Types> && ...);
363 static constexpr bool _S_move_assign =
365 && (is_move_assignable_v<_Types> && ...);
367 static constexpr bool _S_trivial_dtor =
368 (is_trivially_destructible_v<_Types> && ...);
369 static constexpr bool _S_trivial_copy_ctor =
370 (is_trivially_copy_constructible_v<_Types> && ...);
371 static constexpr bool _S_trivial_move_ctor =
372 (is_trivially_move_constructible_v<_Types> && ...);
373 static constexpr bool _S_trivial_copy_assign =
374 _S_trivial_dtor && _S_trivial_copy_ctor
375 && (is_trivially_copy_assignable_v<_Types> && ...);
376 static constexpr bool _S_trivial_move_assign =
377 _S_trivial_dtor && _S_trivial_move_ctor
378 && (is_trivially_move_assignable_v<_Types> && ...);
382 static constexpr bool _S_nothrow_default_ctor =
383 is_nothrow_default_constructible_v<
384 typename _Nth_type<0, _Types...>::type>;
385 static constexpr bool _S_nothrow_copy_ctor =
false;
386 static constexpr bool _S_nothrow_move_ctor =
387 (is_nothrow_move_constructible_v<_Types> && ...);
388 static constexpr bool _S_nothrow_copy_assign =
false;
389 static constexpr bool _S_nothrow_move_assign =
391 && (is_nothrow_move_assignable_v<_Types> && ...);
395 template<
bool __trivially_destructible,
typename... _Types>
396 union _Variadic_union
398 _Variadic_union() =
default;
400 template<
size_t _Np,
typename... _Args>
401 _Variadic_union(in_place_index_t<_Np>, _Args&&...) =
delete;
404 template<
bool __trivially_destructible,
typename _First,
typename... _Rest>
405 union _Variadic_union<__trivially_destructible, _First, _Rest...>
407 constexpr _Variadic_union() : _M_rest() { }
409 template<
typename... _Args>
411 _Variadic_union(in_place_index_t<0>, _Args&&... __args)
412 : _M_first(in_place_index<0>, std::
forward<_Args>(__args)...)
415 template<
size_t _Np,
typename... _Args>
417 _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
418 : _M_rest(in_place_index<_Np-1>, std::
forward<_Args>(__args)...)
421#if __cpp_lib_variant >= 202106L
422 _Variadic_union(
const _Variadic_union&) =
default;
423 _Variadic_union(_Variadic_union&&) =
default;
424 _Variadic_union& operator=(
const _Variadic_union&) =
default;
425 _Variadic_union& operator=(_Variadic_union&&) =
default;
427 ~_Variadic_union() =
default;
429 constexpr ~_Variadic_union()
430 requires (!__trivially_destructible)
434 _Uninitialized<_First> _M_first;
435 _Variadic_union<__trivially_destructible, _Rest...> _M_rest;
443 template<
typename _Tp>
444 struct _Never_valueless_alt
445 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
458 template <typename... _Types>
459 constexpr bool __never_valueless()
461 return _Traits<_Types...>::_S_move_assign
462 && (_Never_valueless_alt<_Types>::value && ...);
466 template<bool __trivially_destructible, typename... _Types>
467 struct _Variant_storage;
469 template <typename... _Types>
470 using __select_index =
471 typename __select_int::_Select_int_base<sizeof...(_Types),
473 unsigned short>::type::value_type;
475 template<typename... _Types>
476 struct _Variant_storage<false, _Types...>
480 : _M_index(static_cast<__index_type>(variant_npos))
483 template<size_t _Np, typename... _Args>
485 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
486 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
493 if (!_M_valid()) [[__unlikely__]]
496 std::__do_visit<void>([](auto&& __this_mem) mutable
498 std::_Destroy(std::__addressof(__this_mem));
499 }, __variant_cast<_Types...>(*this));
501 _M_index = static_cast<__index_type>(variant_npos);
509 _M_valid() const noexcept
511 if constexpr (__variant::__never_valueless<_Types...>())
513 return this->_M_index != __index_type(variant_npos);
516 _Variadic_union<false, _Types...> _M_u;
517 using __index_type = __select_index<_Types...>;
518 __index_type _M_index;
521 template<typename... _Types>
522 struct _Variant_storage<true, _Types...>
526 : _M_index(static_cast<__index_type>(variant_npos))
529 template<
size_t _Np,
typename... _Args>
531 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
532 : _M_u(in_place_index<_Np>, std::
forward<_Args>(__args)...),
538 { _M_index =
static_cast<__index_type
>(variant_npos); }
541 _M_valid() const noexcept
543 if constexpr (__variant::__never_valueless<_Types...>())
551 return this->_M_index !=
static_cast<__index_type
>(variant_npos);
554 _Variadic_union<
true, _Types...> _M_u;
555 using __index_type = __select_index<_Types...>;
556 __index_type _M_index;
560 template<
size_t _Np,
bool _Triv,
typename... _Types,
typename... _Args>
563 __emplace(_Variant_storage<_Triv, _Types...>& __v, _Args&&... __args)
566 auto* __addr = __variant::__construct_n<_Np>(__v._M_u);
573 template<
typename... _Types>
574 using _Variant_storage_alias =
575 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
580 template<bool,
typename... _Types>
581 struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
583 using _Base = _Variant_storage_alias<_Types...>;
587 _Copy_ctor_base(
const _Copy_ctor_base& __rhs)
588 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
590 __variant::__raw_idx_visit(
591 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
593 constexpr size_t __j = __rhs_index;
594 if constexpr (__j != variant_npos)
596 in_place_index<__j>, __rhs_mem);
597 }, __variant_cast<_Types...>(__rhs));
598 this->_M_index = __rhs._M_index;
601 _Copy_ctor_base(_Copy_ctor_base&&) =
default;
602 _Copy_ctor_base& operator=(
const _Copy_ctor_base&) =
default;
603 _Copy_ctor_base& operator=(_Copy_ctor_base&&) =
default;
606 template<
typename... _Types>
607 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
609 using _Base = _Variant_storage_alias<_Types...>;
613 template<
typename... _Types>
614 using _Copy_ctor_alias =
615 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
617 template<bool,
typename... _Types>
618 struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
620 using _Base = _Copy_ctor_alias<_Types...>;
624 _Move_ctor_base(_Move_ctor_base&& __rhs)
625 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
627 __variant::__raw_idx_visit(
628 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
630 constexpr size_t __j = __rhs_index;
631 if constexpr (__j != variant_npos)
635 }, __variant_cast<_Types...>(
std::move(__rhs)));
636 this->_M_index = __rhs._M_index;
639 _Move_ctor_base(
const _Move_ctor_base&) =
default;
640 _Move_ctor_base& operator=(
const _Move_ctor_base&) =
default;
641 _Move_ctor_base& operator=(_Move_ctor_base&&) =
default;
644 template<
typename... _Types>
645 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
647 using _Base = _Copy_ctor_alias<_Types...>;
651 template<
typename... _Types>
652 using _Move_ctor_alias =
653 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
655 template<bool,
typename... _Types>
656 struct _Copy_assign_base : _Move_ctor_alias<_Types...>
658 using _Base = _Move_ctor_alias<_Types...>;
663 operator=(
const _Copy_assign_base& __rhs)
664 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
666 __variant::__raw_idx_visit(
667 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
669 constexpr size_t __j = __rhs_index;
670 if constexpr (__j == variant_npos)
672 else if (this->_M_index == __j)
673 __variant::__get<__j>(*
this) = __rhs_mem;
676 using _Tj =
typename _Nth_type<__j, _Types...>::type;
677 if constexpr (is_nothrow_copy_constructible_v<_Tj>
678 || !is_nothrow_move_constructible_v<_Tj>)
679 __variant::__emplace<__j>(*
this, __rhs_mem);
682 using _Variant = variant<_Types...>;
683 _Variant& __self = __variant_cast<_Types...>(*this);
684 __self = _Variant(in_place_index<__j>, __rhs_mem);
687 }, __variant_cast<_Types...>(__rhs));
691 _Copy_assign_base(
const _Copy_assign_base&) =
default;
692 _Copy_assign_base(_Copy_assign_base&&) =
default;
693 _Copy_assign_base& operator=(_Copy_assign_base&&) =
default;
696 template<
typename... _Types>
697 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
699 using _Base = _Move_ctor_alias<_Types...>;
703 template<
typename... _Types>
704 using _Copy_assign_alias =
705 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
707 template<bool,
typename... _Types>
708 struct _Move_assign_base : _Copy_assign_alias<_Types...>
710 using _Base = _Copy_assign_alias<_Types...>;
715 operator=(_Move_assign_base&& __rhs)
716 noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
718 __variant::__raw_idx_visit(
719 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
721 constexpr size_t __j = __rhs_index;
722 if constexpr (__j != variant_npos)
724 if (this->_M_index == __j)
725 __variant::__get<__j>(*
this) =
std::move(__rhs_mem);
728 using _Tj =
typename _Nth_type<__j, _Types...>::type;
729 if constexpr (is_nothrow_move_constructible_v<_Tj>)
730 __variant::__emplace<__j>(*
this,
std::move(__rhs_mem));
733 using _Variant = variant<_Types...>;
734 _Variant& __self = __variant_cast<_Types...>(*this);
735 __self.template emplace<__j>(
std::move(__rhs_mem));
741 }, __variant_cast<_Types...>(__rhs));
745 _Move_assign_base(
const _Move_assign_base&) =
default;
746 _Move_assign_base(_Move_assign_base&&) =
default;
747 _Move_assign_base& operator=(
const _Move_assign_base&) =
default;
750 template<
typename... _Types>
751 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
753 using _Base = _Copy_assign_alias<_Types...>;
757 template<
typename... _Types>
758 using _Move_assign_alias =
759 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
761 template<
typename... _Types>
762 struct _Variant_base : _Move_assign_alias<_Types...>
764 using _Base = _Move_assign_alias<_Types...>;
767 _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
768 : _Variant_base(in_place_index<0>) { }
770 template<
size_t _Np,
typename... _Args>
772 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
773 : _Base(__i, std::
forward<_Args>(__args)...)
776 _Variant_base(
const _Variant_base&) =
default;
777 _Variant_base(_Variant_base&&) =
default;
778 _Variant_base& operator=(
const _Variant_base&) =
default;
779 _Variant_base& operator=(_Variant_base&&) =
default;
782 template<
typename _Tp,
typename... _Types>
783 inline constexpr bool __exactly_once
784 = std::__find_uniq_type_in_pack<_Tp, _Types...>() <
sizeof...(_Types);
787 template<
typename _Ti>
struct _Arr { _Ti _M_x[1]; };
790 template<
size_t _Ind,
typename _Tp,
typename _Ti,
typename =
void>
795 void _S_fun() =
delete;
799 template<
size_t _Ind,
typename _Tp,
typename _Ti>
800 struct _Build_FUN<_Ind, _Tp, _Ti,
804 static integral_constant<size_t, _Ind> _S_fun(_Ti);
807 template<
typename _Tp,
typename _Variant,
811 template<
typename _Tp,
typename... _Ti,
size_t... _Ind>
813 : _Build_FUN<_Ind, _Tp, _Ti>...
815 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
820 template<
typename _Tp,
typename _Variant>
825 template<
typename _Tp,
typename _Variant,
typename =
void>
826 inline constexpr size_t
827 __accepted_index = variant_npos;
829 template<
typename _Tp,
typename _Variant>
830 inline constexpr size_t
831 __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
832 = _FUN_type<_Tp, _Variant>::value;
834 template<
typename _Maybe_variant_cookie,
typename _Variant,
835 typename = __remove_cvref_t<_Variant>>
836 inline constexpr bool
837 __extra_visit_slot_needed =
false;
839 template<
typename _Var,
typename... _Types>
840 inline constexpr bool
841 __extra_visit_slot_needed<__variant_cookie, _Var, variant<_Types...>>
842 = !__variant::__never_valueless<_Types...>();
844 template<
typename _Var,
typename... _Types>
845 inline constexpr bool
846 __extra_visit_slot_needed<__variant_idx_cookie, _Var, variant<_Types...>>
847 = !__variant::__never_valueless<_Types...>();
850 template<
typename _Tp,
size_t... _Dimensions>
854 template<
typename _Tp>
855 struct _Multi_array<_Tp>
858 struct __untag_result
860 {
using element_type = _Tp; };
862#pragma GCC diagnostic push
863#pragma GCC diagnostic ignored "-Wignored-qualifiers"
864 template <
typename... _Args>
865 struct __untag_result<const void(*)(_Args...)>
867 {
using element_type = void(*)(_Args...); };
868#pragma GCC diagnostic pop
870 template <
typename... _Args>
871 struct __untag_result<__variant_cookie(*)(_Args...)>
873 {
using element_type = void(*)(_Args...); };
875 template <
typename... _Args>
876 struct __untag_result<__variant_idx_cookie(*)(_Args...)>
878 {
using element_type = void(*)(_Args...); };
880 template <
typename _Res,
typename... _Args>
881 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
883 {
using element_type = _Res(*)(_Args...); };
885 using __result_is_deduced = __untag_result<_Tp>;
887 constexpr const typename __untag_result<_Tp>::element_type&
891 typename __untag_result<_Tp>::element_type _M_data;
895 template<
typename _Ret,
897 typename... _Variants,
898 size_t __first,
size_t... __rest>
899 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
901 static constexpr size_t __index =
902 sizeof...(_Variants) -
sizeof...(__rest) - 1;
904 using _Variant =
typename _Nth_type<__index, _Variants...>::type;
906 static constexpr int __do_cookie =
907 __extra_visit_slot_needed<_Ret, _Variant> ? 1 : 0;
909 using _Tp = _Ret(*)(_Visitor, _Variants...);
911 template<
typename... _Args>
912 constexpr decltype(
auto)
913 _M_access(
size_t __first_index, _Args... __rest_indices)
const
915 return _M_arr[__first_index + __do_cookie]
916 ._M_access(__rest_indices...);
919 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
949 template<
typename _Array_type,
typename _Index_seq>
950 struct __gen_vtable_impl;
959 template<
typename _Result_type,
typename _Visitor,
size_t... __dimensions,
960 typename... _Variants,
size_t... __indices>
961 struct __gen_vtable_impl<
962 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
967 _Variants...>::type>;
969 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
972 static constexpr _Array_type
975 _Array_type __vtable{};
981 template<
size_t... __var_indices>
982 static constexpr void
983 _S_apply_all_alts(_Array_type& __vtable,
986 if constexpr (__extra_visit_slot_needed<_Result_type, _Next>)
987 (_S_apply_single_alt<true, __var_indices>(
988 __vtable._M_arr[__var_indices + 1],
989 &(__vtable._M_arr[0])), ...);
991 (_S_apply_single_alt<false, __var_indices>(
992 __vtable._M_arr[__var_indices]), ...);
995 template<
bool __do_cookie,
size_t __index,
typename _Tp>
996 static constexpr void
997 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element =
nullptr)
999 if constexpr (__do_cookie)
1001 __element = __gen_vtable_impl<
1004 *__cookie_element = __gen_vtable_impl<
1010 auto __tmp_element = __gen_vtable_impl<
1013 static_assert(is_same_v<_Tp,
decltype(__tmp_element)>,
1014 "std::visit requires the visitor to have the same "
1015 "return type for all alternatives of a variant");
1016 __element = __tmp_element;
1024 template<
typename _Result_type,
typename _Visitor,
typename... _Variants,
1025 size_t... __indices>
1026 struct __gen_vtable_impl<
1027 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
1031 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
1033 template<
size_t __index,
typename _Variant>
1034 static constexpr decltype(
auto)
1035 __element_by_index_or_cookie(_Variant&& __var)
noexcept
1037 if constexpr (__index != variant_npos)
1040 return __variant_cookie{};
1043 static constexpr decltype(
auto)
1044 __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1046 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1050 __element_by_index_or_cookie<__indices>(
1052 integral_constant<size_t, __indices>()...);
1053 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1056 __element_by_index_or_cookie<__indices>(
1058 else if constexpr (_Array_type::__result_is_deduced::value)
1061 __element_by_index_or_cookie<__indices>(
1064 return std::__invoke_r<_Result_type>(
1069 static constexpr auto
1072 if constexpr (_Array_type::__result_is_deduced::value)
1074 constexpr bool __visit_ret_type_mismatch =
1075 !is_same_v<
typename _Result_type::type,
1078 if constexpr (__visit_ret_type_mismatch)
1080 struct __cannot_match {};
1081 return __cannot_match{};
1084 return _Array_type{&__visit_invoke};
1087 return _Array_type{&__visit_invoke};
1091 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1095 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1096 variant_size_v<remove_reference_t<_Variants>>...>;
1098 static constexpr _Array_type _S_vtable
1099 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1102 template<
size_t _Np,
typename _Tp>
1103 struct _Base_dedup :
public _Tp { };
1105 template<
typename _Variant,
typename __indices>
1106 struct _Variant_hash_base;
1108 template<
typename... _Types,
size_t... __indices>
1109 struct _Variant_hash_base<variant<_Types...>,
1111 : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
1114 template<
size_t _Np,
typename _Variant,
1118 = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1121 template<
typename _Visitor,
typename... _Variants>
1122 using __visit_result_t
1123 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1125 template<
typename _Tp,
typename... _Types>
1126 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1128 template <
typename _Visitor,
typename _Variant,
size_t... _Idxs>
1131 return __same_types<
1132 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1139 template<
typename _Tp,
typename... _Types>
1141 holds_alternative(
const variant<_Types...>& __v)
noexcept
1143 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1144 "T must occur exactly once in alternatives");
1145 return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>();
1148 template<
typename _Tp,
typename... _Types>
1150 get(variant<_Types...>& __v)
1152 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1153 "T must occur exactly once in alternatives");
1154 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1155 return std::get<__n>(__v);
1158 template<
typename _Tp,
typename... _Types>
1160 get(variant<_Types...>&& __v)
1162 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1163 "T must occur exactly once in alternatives");
1164 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1168 template<
typename _Tp,
typename... _Types>
1169 constexpr const _Tp&
1170 get(
const variant<_Types...>& __v)
1172 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1173 "T must occur exactly once in alternatives");
1174 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1175 return std::get<__n>(__v);
1178 template<
typename _Tp,
typename... _Types>
1179 constexpr const _Tp&&
1180 get(
const variant<_Types...>&& __v)
1182 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1183 "T must occur exactly once in alternatives");
1184 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1188 template<
size_t _Np,
typename... _Types>
1189 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1190 get_if(variant<_Types...>* __ptr)
noexcept
1192 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1193 static_assert(_Np <
sizeof...(_Types),
1194 "The index must be in [0, number of alternatives)");
1195 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1196 if (__ptr && __ptr->index() == _Np)
1201 template<
size_t _Np,
typename... _Types>
1203 add_pointer_t<
const variant_alternative_t<_Np, variant<_Types...>>>
1204 get_if(
const 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<
typename _Tp,
typename... _Types>
1217 get_if(variant<_Types...>* __ptr)
noexcept
1219 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1220 "T must occur exactly once in alternatives");
1221 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1222 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1223 return std::get_if<__n>(__ptr);
1226 template<
typename _Tp,
typename... _Types>
1228 get_if(
const variant<_Types...>* __ptr)
noexcept
1230 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1231 "T must occur exactly once in alternatives");
1232 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1233 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1234 return std::get_if<__n>(__ptr);
1237 struct monostate { };
1239#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1240 template<typename... _Types> \
1241 constexpr bool operator __OP(const variant<_Types...>& __lhs, \
1242 const variant<_Types...>& __rhs) \
1244 bool __ret = true; \
1245 __detail::__variant::__raw_idx_visit( \
1246 [&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \
1248 if constexpr (__rhs_index != variant_npos) \
1250 if (__lhs.index() == __rhs_index) \
1252 auto& __this_mem = std::get<__rhs_index>(__lhs); \
1253 __ret = __this_mem __OP __rhs_mem; \
1256 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
1259 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
1264 _VARIANT_RELATION_FUNCTION_TEMPLATE(<,
less)
1265 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=,
less_equal)
1266 _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1267 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1269 _VARIANT_RELATION_FUNCTION_TEMPLATE(>,
greater)
1271#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1273 constexpr bool operator==(monostate, monostate)
noexcept {
return true; }
1275#ifdef __cpp_lib_three_way_comparison
1276 template<
typename... _Types>
1277 requires (three_way_comparable<_Types> && ...)
1279 common_comparison_category_t<compare_three_way_result_t<_Types>...>
1280 operator<=>(
const variant<_Types...>& __v,
const variant<_Types...>& __w)
1282 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1283 = strong_ordering::equal;
1285 __detail::__variant::__raw_idx_visit(
1286 [&__ret, &__v] (
auto&& __w_mem,
auto __w_index)
mutable
1288 if constexpr (__w_index != variant_npos)
1290 if (__v.index() == __w_index)
1292 auto& __this_mem = std::get<__w_index>(__v);
1293 __ret = __this_mem <=> __w_mem;
1297 __ret = (__v.index() + 1) <=> (__w_index + 1);
1302 constexpr strong_ordering
1303 operator<=>(monostate, monostate)
noexcept {
return strong_ordering::equal; }
1305 constexpr bool operator!=(monostate, monostate)
noexcept {
return false; }
1306 constexpr bool operator<(monostate, monostate)
noexcept {
return false; }
1307 constexpr bool operator>(monostate, monostate)
noexcept {
return false; }
1308 constexpr bool operator<=(monostate, monostate)
noexcept {
return true; }
1309 constexpr bool operator>=(monostate, monostate)
noexcept {
return true; }
1312 template<
typename _Visitor,
typename... _Variants>
1313 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1314 visit(_Visitor&&, _Variants&&...);
1316 template<
typename... _Types>
1317 _GLIBCXX20_CONSTEXPR
1318 inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1319 && (is_swappable_v<_Types> && ...)>
1320 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1321 noexcept(
noexcept(__lhs.swap(__rhs)))
1322 { __lhs.swap(__rhs); }
1324 template<
typename... _Types>
1325 enable_if_t<!((is_move_constructible_v<_Types> && ...)
1326 && (is_swappable_v<_Types> && ...))>
1327 swap(variant<_Types...>&, variant<_Types...>&) =
delete;
1329 class bad_variant_access :
public exception
1332 bad_variant_access() noexcept { }
1334 const char* what() const noexcept
override
1335 {
return _M_reason; }
1338 bad_variant_access(
const char* __reason) noexcept : _M_reason(__reason) { }
1341 const char* _M_reason =
"bad variant access";
1343 friend void __throw_bad_variant_access(
const char* __what);
1348 __throw_bad_variant_access(
const char* __what)
1349 { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1352 __throw_bad_variant_access(
bool __valueless)
1354 if (__valueless) [[__unlikely__]]
1355 __throw_bad_variant_access(
"std::get: variant is valueless");
1357 __throw_bad_variant_access(
"std::get: wrong index for variant");
1360 template<
typename... _Types>
1362 :
private __detail::__variant::_Variant_base<_Types...>,
1363 private _Enable_copy_move<
1364 __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1365 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1366 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1367 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1371 template <
typename... _UTypes,
typename _Tp>
1372 friend _GLIBCXX20_CONSTEXPR
decltype(
auto)
1373 __variant_cast(_Tp&&);
1375 static_assert(
sizeof...(_Types) > 0,
1376 "variant must have at least one alternative");
1377#ifdef __STRICT_ANSI__
1378 static_assert(((std::is_object_v<_Types> && !is_array_v<_Types>) && ...),
1379 "variant alternatives must be non-array object types");
1381 static_assert((std::is_object_v<_Types> && ...),
1382 "variant alternatives must be object types");
1385 using _Base = __detail::__variant::_Variant_base<_Types...>;
1387 template<
typename _Tp>
1388 static constexpr bool __not_self
1389 = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1391 template<
typename _Tp>
1392 static constexpr bool
1393 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1395 template<
typename _Tp>
1396 static constexpr size_t __accepted_index
1397 = __detail::__variant::__accepted_index<_Tp, variant>;
1399 template<
size_t _Np,
typename =
enable_if_t<(_Np <
sizeof...(_Types))>>
1400 using __to_type =
typename _Nth_type<_Np, _Types...>::type;
1402 template<
typename _Tp,
typename = enable_if_t<__not_self<_Tp>>>
1403 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1405 template<
typename _Tp>
1406 static constexpr size_t __index_of
1407 = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1409 using _Traits = __detail::__variant::_Traits<_Types...>;
1411 template<
typename _Tp>
1413 template<
typename _Tp>
1414 struct __is_in_place_tag<in_place_type_t<_Tp>> :
true_type { };
1415 template<
size_t _Np>
1416 struct __is_in_place_tag<in_place_index_t<_Np>> :
true_type { };
1418 template<
typename _Tp>
1419 static constexpr bool __not_in_place_tag
1420 = !__is_in_place_type_v<__remove_cvref_t<_Tp>>
1421 && !__is_in_place_index_v<__remove_cvref_t<_Tp>>;
1425 variant()
requires is_default_constructible_v<__to_type<0>> = default;
1427 template<
typename _Tp0 = __to_type<0>,
1428 typename = enable_if_t<is_default_constructible_v<_Tp0>>>
1430 variant() noexcept(is_nothrow_default_constructible_v<__to_type<0>>)
1434 variant(
const variant& __rhs) =
default;
1435 variant(variant&&) =
default;
1436 variant& operator=(
const variant&) =
default;
1437 variant& operator=(variant&&) =
default;
1438 _GLIBCXX20_CONSTEXPR ~variant() =
default;
1440 template<
typename _Tp,
1442 typename = enable_if_t<__not_in_place_tag<_Tp>>,
1443 typename _Tj = __accepted_type<_Tp&&>,
1444 typename = enable_if_t<__exactly_once<_Tj>
1445 && is_constructible_v<_Tj, _Tp>>>
1448 noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1449 : variant(in_place_index<__accepted_index<_Tp>>,
1453 template<
typename _Tp,
typename... _Args,
1454 typename = enable_if_t<__exactly_once<_Tp>
1455 && is_constructible_v<_Tp, _Args...>>>
1457 variant(in_place_type_t<_Tp>, _Args&&... __args)
1458 : variant(in_place_index<__index_of<_Tp>>,
1459 std::
forward<_Args>(__args)...)
1462 template<
typename _Tp,
typename _Up,
typename... _Args,
1463 typename = enable_if_t<__exactly_once<_Tp>
1464 && is_constructible_v<_Tp,
1465 initializer_list<_Up>&, _Args...>>>
1467 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1469 : variant(in_place_index<__index_of<_Tp>>, __il,
1470 std::
forward<_Args>(__args)...)
1473 template<
size_t _Np,
typename... _Args,
1474 typename _Tp = __to_type<_Np>,
1475 typename =
enable_if_t<is_constructible_v<_Tp, _Args...>>>
1477 variant(in_place_index_t<_Np>, _Args&&... __args)
1478 : _Base(in_place_index<_Np>, std::
forward<_Args>(__args)...)
1481 template<
size_t _Np,
typename _Up,
typename... _Args,
1482 typename _Tp = __to_type<_Np>,
1484 initializer_list<_Up>&,
1487 variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1489 : _Base(in_place_index<_Np>, __il, std::
forward<_Args>(__args)...)
1492 template<
typename _Tp>
1493 _GLIBCXX20_CONSTEXPR
1494 enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1495 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1496 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1498 operator=(_Tp&& __rhs)
1499 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1500 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1502 constexpr auto __index = __accepted_index<_Tp>;
1503 if (index() == __index)
1507 using _Tj = __accepted_type<_Tp&&>;
1508 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1509 || !is_nothrow_move_constructible_v<_Tj>)
1519 template<
typename _Tp,
typename... _Args>
1520 _GLIBCXX20_CONSTEXPR
1521 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1523 emplace(_Args&&... __args)
1525 constexpr size_t __index = __index_of<_Tp>;
1529 template<
typename _Tp,
typename _Up,
typename... _Args>
1530 _GLIBCXX20_CONSTEXPR
1531 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1532 && __exactly_once<_Tp>,
1534 emplace(initializer_list<_Up> __il, _Args&&... __args)
1536 constexpr size_t __index = __index_of<_Tp>;
1540 template<
size_t _Np,
typename... _Args>
1541 _GLIBCXX20_CONSTEXPR
1542 enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>,
1544 emplace(_Args&&... __args)
1546 namespace __variant = std::__detail::__variant;
1547 using type =
typename _Nth_type<_Np, _Types...>::type;
1550 if constexpr (is_nothrow_constructible_v<type, _Args...>)
1554 else if constexpr (is_scalar_v<type>)
1559 __variant::__emplace<_Np>(*
this, __tmp);
1561 else if constexpr (__variant::_Never_valueless_alt<type>()
1562 && _Traits::_S_move_assign)
1565 variant __tmp(in_place_index<_Np>,
1576 return std::get<_Np>(*
this);
1579 template<
size_t _Np,
typename _Up,
typename... _Args>
1580 _GLIBCXX20_CONSTEXPR
1581 enable_if_t<is_constructible_v<__to_type<_Np>,
1582 initializer_list<_Up>&, _Args...>,
1584 emplace(initializer_list<_Up> __il, _Args&&... __args)
1586 namespace __variant = std::__detail::__variant;
1587 using type =
typename _Nth_type<_Np, _Types...>::type;
1590 if constexpr (is_nothrow_constructible_v<type,
1591 initializer_list<_Up>&,
1594 __variant::__emplace<_Np>(*
this, __il,
1597 else if constexpr (__variant::_Never_valueless_alt<type>()
1598 && _Traits::_S_move_assign)
1601 variant __tmp(in_place_index<_Np>, __il,
1610 __variant::__emplace<_Np>(*
this, __il,
1613 return std::get<_Np>(*
this);
1616 template<
size_t _Np,
typename... _Args>
1617 enable_if_t<!(_Np <
sizeof...(_Types))> emplace(_Args&&...) =
delete;
1619 template<
typename _Tp,
typename... _Args>
1620 enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) =
delete;
1622 constexpr bool valueless_by_exception() const noexcept
1623 {
return !this->_M_valid(); }
1625 constexpr size_t index() const noexcept
1627 using __index_type =
typename _Base::__index_type;
1628 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1629 return this->_M_index;
1630 else if constexpr (
sizeof...(_Types) <= __index_type(-1) / 2)
1631 return make_signed_t<__index_type>(this->_M_index);
1633 return size_t(__index_type(this->_M_index + 1)) - 1;
1636 _GLIBCXX20_CONSTEXPR
1638 swap(variant& __rhs)
1639 noexcept((__is_nothrow_swappable<_Types>::value && ...)
1640 && is_nothrow_move_constructible_v<variant>)
1642 static_assert((is_move_constructible_v<_Types> && ...));
1645 if (__rhs.valueless_by_exception()) [[__unlikely__]]
1647 if (!this->valueless_by_exception()) [[__likely__]]
1652 namespace __variant = __detail::__variant;
1654 __variant::__raw_idx_visit(
1655 [
this, &__rhs](
auto&& __rhs_mem,
auto __rhs_index)
mutable
1657 constexpr size_t __j = __rhs_index;
1658 if constexpr (__j != variant_npos)
1660 if (this->index() == __j)
1663 swap(std::get<__j>(*
this), __rhs_mem);
1669 if constexpr (_Traits::_S_trivial_move_assign)
1672 __variant::__raw_idx_visit(
1673 [&__rhs](
auto&& __this_mem,
auto __this_index)
mutable
1675 constexpr size_t __k = __this_index;
1676 if constexpr (__k != variant_npos)
1677 __variant::__emplace<__k>(__rhs,
1681 __variant::__emplace<__j>(*
this,
std::move(__tmp));
1687#if defined(__clang__) && __clang_major__ <= 7
1693 template<
size_t _Np,
typename _Vp>
1694 friend constexpr decltype(
auto)
1695 __detail::__variant::__get(_Vp&& __v)
noexcept;
1697#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1698 template<typename... _Tp> \
1699 friend constexpr bool \
1700 operator __OP(const variant<_Tp...>& __lhs, \
1701 const variant<_Tp...>& __rhs);
1703 _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1704 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1705 _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1706 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1707 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1708 _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1710#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1713 template<
size_t _Np,
typename... _Types>
1714 constexpr variant_alternative_t<_Np, variant<_Types...>>&
1715 get(variant<_Types...>& __v)
1717 static_assert(_Np <
sizeof...(_Types),
1718 "The index must be in [0, number of alternatives)");
1719 if (__v.index() != _Np)
1720 __throw_bad_variant_access(__v.valueless_by_exception());
1721 return __detail::__variant::__get<_Np>(__v);
1724 template<
size_t _Np,
typename... _Types>
1725 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1726 get(variant<_Types...>&& __v)
1728 static_assert(_Np <
sizeof...(_Types),
1729 "The index must be in [0, number of alternatives)");
1730 if (__v.index() != _Np)
1731 __throw_bad_variant_access(__v.valueless_by_exception());
1732 return __detail::__variant::__get<_Np>(
std::move(__v));
1735 template<
size_t _Np,
typename... _Types>
1736 constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1737 get(
const variant<_Types...>& __v)
1739 static_assert(_Np <
sizeof...(_Types),
1740 "The index must be in [0, number of alternatives)");
1741 if (__v.index() != _Np)
1742 __throw_bad_variant_access(__v.valueless_by_exception());
1743 return __detail::__variant::__get<_Np>(__v);
1746 template<
size_t _Np,
typename... _Types>
1747 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1748 get(
const variant<_Types...>&& __v)
1750 static_assert(_Np <
sizeof...(_Types),
1751 "The index must be in [0, number of alternatives)");
1752 if (__v.index() != _Np)
1753 __throw_bad_variant_access(__v.valueless_by_exception());
1754 return __detail::__variant::__get<_Np>(
std::move(__v));
1758 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1759 constexpr decltype(
auto)
1760 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1763 if constexpr (
sizeof...(_Variants) == 0)
1765 if constexpr (is_void_v<_Result_type>)
1772 constexpr size_t __max = 11;
1775 using _V0 =
typename _Nth_type<0, _Variants...>::type;
1777 constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
1779 if constexpr (
sizeof...(_Variants) > 1 || __n > __max)
1782 constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1783 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1785 auto __func_ptr = __vtable._M_access(__variants.index()...);
1793 = [](_V0& __v, ...) -> _V0& {
return __v; }(__variants...);
1795 using __detail::__variant::_Multi_array;
1796 using __detail::__variant::__gen_vtable_impl;
1797 using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0&&)>;
1799#ifdef _GLIBCXX_DEBUG
1800# define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap
1802# define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable
1805#define _GLIBCXX_VISIT_CASE(N) \
1808 if constexpr (N < __n) \
1810 return __gen_vtable_impl<_Ma, index_sequence<N>>:: \
1811 __visit_invoke(std::forward<_Visitor>(__visitor), \
1812 std::forward<_V0>(__v0)); \
1814 else _GLIBCXX_VISIT_UNREACHABLE(); \
1817 switch (__v0.index())
1819 _GLIBCXX_VISIT_CASE(0)
1820 _GLIBCXX_VISIT_CASE(1)
1821 _GLIBCXX_VISIT_CASE(2)
1822 _GLIBCXX_VISIT_CASE(3)
1823 _GLIBCXX_VISIT_CASE(4)
1824 _GLIBCXX_VISIT_CASE(5)
1825 _GLIBCXX_VISIT_CASE(6)
1826 _GLIBCXX_VISIT_CASE(7)
1827 _GLIBCXX_VISIT_CASE(8)
1828 _GLIBCXX_VISIT_CASE(9)
1829 _GLIBCXX_VISIT_CASE(10)
1831 using
__detail::__variant::__variant_idx_cookie;
1832 using
__detail::__variant::__variant_cookie;
1833 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
1834 || is_same_v<_Result_type, __variant_cookie>)
1837 return __gen_vtable_impl<_Ma, _Npos>::
1842 _GLIBCXX_VISIT_UNREACHABLE();
1844 _GLIBCXX_VISIT_UNREACHABLE();
1846#undef _GLIBCXX_VISIT_CASE
1847#undef _GLIBCXX_VISIT_UNREACHABLE
1853 template<
typename _Visitor,
typename... _Variants>
1854 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1855 visit(_Visitor&& __visitor, _Variants&&... __variants)
1857 namespace __variant = std::__detail::__variant;
1859 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1860 __throw_bad_variant_access(
"std::visit: variant is valueless");
1863 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1865 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1867 if constexpr (
sizeof...(_Variants) == 1)
1871 constexpr bool __visit_rettypes_match = __detail::__variant::
1872 __check_visitor_results<_Visitor, _Vp>(
1874 if constexpr (!__visit_rettypes_match)
1876 static_assert(__visit_rettypes_match,
1877 "std::visit requires the visitor to have the same "
1878 "return type for all alternatives of a variant");
1882 return std::__do_visit<_Tag>(
1884 static_cast<_Vp
>(__variants)...);
1887 return std::__do_visit<_Tag>(
1892#if __cplusplus > 201703L
1893 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1895 visit(_Visitor&& __visitor, _Variants&&... __variants)
1897 namespace __variant = std::__detail::__variant;
1899 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1900 __throw_bad_variant_access(
"std::visit<R>: variant is valueless");
1908 template<bool,
typename... _Types>
1909 struct __variant_hash_call_base_impl
1912 operator()(
const variant<_Types...>& __t)
const
1913 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1916 __detail::__variant::__raw_visit(
1917 [&__t, &__ret](
auto&& __t_mem)
mutable
1919 using _Type = __remove_cvref_t<
decltype(__t_mem)>;
1920 if constexpr (!is_same_v<_Type,
1921 __detail::__variant::__variant_cookie>)
1922 __ret = std::hash<size_t>{}(__t.index())
1923 + std::hash<_Type>{}(__t_mem);
1925 __ret = std::hash<size_t>{}(__t.index());
1931 template<
typename... _Types>
1932 struct __variant_hash_call_base_impl<false, _Types...> {};
1934 template<
typename... _Types>
1935 using __variant_hash_call_base =
1936 __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
1937 __enable_hash_call &&...), _Types...>;
1940 template<
typename... _Types>
1941 struct hash<variant<_Types...>>
1942 :
private __detail::__variant::_Variant_hash_base<
1943 variant<_Types...>, std::index_sequence_for<_Types...>>,
1944 public __variant_hash_call_base<_Types...>
1946 using result_type [[__deprecated__]] = size_t;
1947 using argument_type [[__deprecated__]] = variant<_Types...>;
1951 struct hash<monostate>
1953 using result_type [[__deprecated__]] = size_t;
1954 using argument_type [[__deprecated__]] = monostate;
1957 operator()(
const monostate&)
const noexcept
1959 constexpr size_t __magic_monostate_hash = -7777;
1960 return __magic_monostate_hash;
1964 template<
typename... _Types>
1966 : bool_constant<(__is_fast_hash<_Types>::value && ...)>
1969_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.
One of the comparison functors.
One of the comparison functors.
One of the comparison functors.
One of the comparison functors.