29#ifndef _GLIBCXX_VARIANT
30#define _GLIBCXX_VARIANT 1
32#pragma GCC system_header
34#if __cplusplus >= 201703L
48#if __cplusplus > 201703L
52namespace std _GLIBCXX_VISIBILITY(default)
54_GLIBCXX_BEGIN_NAMESPACE_VERSION
60 template<
size_t _Np,
typename... _Types>
63 template<
size_t _Np,
typename _First,
typename... _Rest>
64 struct _Nth_type<_Np, _First, _Rest...>
65 : _Nth_type<_Np-1, _Rest...> { };
67 template<
typename _First,
typename... _Rest>
68 struct _Nth_type<0, _First, _Rest...>
69 {
using type = _First; };
74#define __cpp_lib_variant 202102L
76 template<
typename... _Types>
class tuple;
77 template<
typename... _Types>
class variant;
78 template <
typename>
struct hash;
80 template<
typename _Variant>
83 template<
typename _Variant>
84 struct variant_size<const _Variant> : variant_size<_Variant> {};
86 template<
typename _Variant>
87 struct variant_size<volatile _Variant> : variant_size<_Variant> {};
89 template<
typename _Variant>
90 struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
92 template<
typename... _Types>
93 struct variant_size<variant<_Types...>>
96 template<
typename _Variant>
97 inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
99 template<
size_t _Np,
typename _Variant>
100 struct variant_alternative;
102 template<
size_t _Np,
typename _First,
typename... _Rest>
103 struct variant_alternative<_Np, variant<_First, _Rest...>>
104 : variant_alternative<_Np-1, variant<_Rest...>> {};
106 template<
typename _First,
typename... _Rest>
107 struct variant_alternative<0, variant<_First, _Rest...>>
108 {
using type = _First; };
110 template<
size_t _Np,
typename _Variant>
111 using variant_alternative_t =
112 typename variant_alternative<_Np, _Variant>::type;
114 template<
size_t _Np,
typename _Variant>
115 struct variant_alternative<_Np, const _Variant>
116 {
using type = add_const_t<variant_alternative_t<_Np, _Variant>>; };
118 template<
size_t _Np,
typename _Variant>
119 struct variant_alternative<_Np, volatile _Variant>
120 {
using type = add_volatile_t<variant_alternative_t<_Np, _Variant>>; };
122 template<
size_t _Np,
typename _Variant>
123 struct variant_alternative<_Np, const volatile _Variant>
124 {
using type = add_cv_t<variant_alternative_t<_Np, _Variant>>; };
126 inline constexpr size_t variant_npos = -1;
128 template<
size_t _Np,
typename... _Types>
129 constexpr variant_alternative_t<_Np, variant<_Types...>>&
130 get(variant<_Types...>&);
132 template<
size_t _Np,
typename... _Types>
133 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
134 get(variant<_Types...>&&);
136 template<
size_t _Np,
typename... _Types>
137 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&
138 get(
const variant<_Types...>&);
140 template<
size_t _Np,
typename... _Types>
141 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&&
142 get(
const variant<_Types...>&&);
144 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
145 constexpr decltype(
auto)
146 __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
148 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);
169 template<
typename _Tp,
typename... _Types>
172 template<
typename _Tp,
typename... _Types>
173 inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value;
175 template<
typename _Tp,
typename _First,
typename... _Rest>
176 struct __index_of<_Tp, _First, _Rest...> :
178 ? 0 : __index_of_v<_Tp, _Rest...> + 1> {};
181 struct __variant_cookie {};
183 struct __variant_idx_cookie {
using type = __variant_idx_cookie; };
185 template<
typename _Tp>
struct __deduce_visit_result {
using type = _Tp; };
188 template<
typename _Visitor,
typename... _Variants>
190 __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
192 std::__do_visit<__variant_cookie>(std::forward<_Visitor>(__visitor),
193 std::forward<_Variants>(__variants)...);
197 template<
typename _Visitor,
typename... _Variants>
199 __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
201 std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor),
202 std::forward<_Variants>(__variants)...);
207 template<
typename... _Types>
208 constexpr std::variant<_Types...>&
209 __as(std::variant<_Types...>& __v)
noexcept
212 template<
typename... _Types>
213 constexpr const std::variant<_Types...>&
214 __as(
const std::variant<_Types...>& __v)
noexcept
217 template<
typename... _Types>
218 constexpr std::variant<_Types...>&&
219 __as(std::variant<_Types...>&& __v)
noexcept
222 template<
typename... _Types>
223 constexpr const std::variant<_Types...>&&
224 __as(
const std::variant<_Types...>&& __v)
noexcept
229 template<
typename _Type,
bool = std::is_trivially_destructible_v<_Type>>
230 struct _Uninitialized;
232 template<
typename _Type>
233 struct _Uninitialized<_Type, true>
235 template<
typename... _Args>
237 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
241 constexpr const _Type& _M_get() const & noexcept
242 {
return _M_storage; }
244 constexpr _Type& _M_get() &
noexcept
245 {
return _M_storage; }
247 constexpr const _Type&& _M_get() const && noexcept
250 constexpr _Type&& _M_get() &&
noexcept
256 template<
typename _Type>
257 struct _Uninitialized<_Type, false>
259 template<
typename... _Args>
261 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
264 _Type(std::forward<_Args>(__args)...);
267 const _Type& _M_get() const & noexcept
268 {
return *_M_storage._M_ptr(); }
270 _Type& _M_get() &
noexcept
271 {
return *_M_storage._M_ptr(); }
273 const _Type&& _M_get() const && noexcept
274 {
return std::move(*_M_storage._M_ptr()); }
276 _Type&& _M_get() &&
noexcept
277 {
return std::move(*_M_storage._M_ptr()); }
279 __gnu_cxx::__aligned_membuf<_Type> _M_storage;
282 template<
typename _Union>
283 constexpr decltype(
auto)
284 __get(in_place_index_t<0>, _Union&& __u)
noexcept
285 {
return std::forward<_Union>(__u)._M_first._M_get(); }
287 template<
size_t _Np,
typename _Union>
288 constexpr decltype(
auto)
289 __get(in_place_index_t<_Np>, _Union&& __u)
noexcept
291 return __variant::__get(in_place_index<_Np-1>,
292 std::forward<_Union>(__u)._M_rest);
296 template<
size_t _Np,
typename _Variant>
297 constexpr decltype(
auto)
298 __get(_Variant&& __v)
noexcept
300 return __variant::__get(std::in_place_index<_Np>,
301 std::forward<_Variant>(__v)._M_u);
304 template<
typename... _Types>
307 static constexpr bool _S_default_ctor =
308 is_default_constructible_v<
typename _Nth_type<0, _Types...>::type>;
309 static constexpr bool _S_copy_ctor =
310 (is_copy_constructible_v<_Types> && ...);
311 static constexpr bool _S_move_ctor =
312 (is_move_constructible_v<_Types> && ...);
313 static constexpr bool _S_copy_assign =
315 && (is_copy_assignable_v<_Types> && ...);
316 static constexpr bool _S_move_assign =
318 && (is_move_assignable_v<_Types> && ...);
320 static constexpr bool _S_trivial_dtor =
321 (is_trivially_destructible_v<_Types> && ...);
322 static constexpr bool _S_trivial_copy_ctor =
323 (is_trivially_copy_constructible_v<_Types> && ...);
324 static constexpr bool _S_trivial_move_ctor =
325 (is_trivially_move_constructible_v<_Types> && ...);
326 static constexpr bool _S_trivial_copy_assign =
327 _S_trivial_dtor && _S_trivial_copy_ctor
328 && (is_trivially_copy_assignable_v<_Types> && ...);
329 static constexpr bool _S_trivial_move_assign =
330 _S_trivial_dtor && _S_trivial_move_ctor
331 && (is_trivially_move_assignable_v<_Types> && ...);
335 static constexpr bool _S_nothrow_default_ctor =
336 is_nothrow_default_constructible_v<
337 typename _Nth_type<0, _Types...>::type>;
338 static constexpr bool _S_nothrow_copy_ctor =
false;
339 static constexpr bool _S_nothrow_move_ctor =
340 (is_nothrow_move_constructible_v<_Types> && ...);
341 static constexpr bool _S_nothrow_copy_assign =
false;
342 static constexpr bool _S_nothrow_move_assign =
344 && (is_nothrow_move_assignable_v<_Types> && ...);
348 template<
typename... _Types>
349 union _Variadic_union { };
351 template<
typename _First,
typename... _Rest>
352 union _Variadic_union<_First, _Rest...>
354 constexpr _Variadic_union() : _M_rest() { }
356 template<
typename... _Args>
357 constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args)
358 : _M_first(in_place_index<0>,
std::
forward<_Args>(__args)...)
361 template<
size_t _Np,
typename... _Args>
362 constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
363 : _M_rest(in_place_index<_Np-1>,
std::
forward<_Args>(__args)...)
366 _Uninitialized<_First> _M_first;
367 _Variadic_union<_Rest...> _M_rest;
375 template<
typename _Tp>
376 struct _Never_valueless_alt
377 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
390 template <typename... _Types>
391 constexpr bool __never_valueless()
393 return _Traits<_Types...>::_S_move_assign
394 && (_Never_valueless_alt<_Types>::value && ...);
398 template<bool __trivially_destructible, typename... _Types>
399 struct _Variant_storage;
401 template <typename... _Types>
402 using __select_index =
403 typename __select_int::_Select_int_base<sizeof...(_Types),
405 unsigned short>::type::value_type;
407 template<typename... _Types>
408 struct _Variant_storage<false, _Types...>
412 : _M_index(static_cast<__index_type>(variant_npos))
415 template<size_t _Np, typename... _Args>
417 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
418 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
424 if (!_M_valid()) [[unlikely]]
427 std::__do_visit<void>([](auto&& __this_mem) mutable
429 std::_Destroy(std::__addressof(__this_mem));
430 }, __variant_cast<_Types...>(*this));
432 _M_index = static_cast<__index_type>(variant_npos);
439 _M_valid() const noexcept
441 if constexpr (__variant::__never_valueless<_Types...>())
443 return this->_M_index != __index_type(variant_npos);
446 _Variadic_union<_Types...> _M_u;
447 using __index_type = __select_index<_Types...>;
448 __index_type _M_index;
451 template<typename... _Types>
452 struct _Variant_storage<true, _Types...>
456 : _M_index(static_cast<__index_type>(variant_npos))
459 template<
size_t _Np,
typename... _Args>
461 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
462 : _M_u(in_place_index<_Np>,
std::
forward<_Args>(__args)...),
466 void _M_reset() noexcept
467 { _M_index =
static_cast<__index_type
>(variant_npos); }
470 _M_valid() const noexcept
472 if constexpr (__variant::__never_valueless<_Types...>())
474 return this->_M_index !=
static_cast<__index_type
>(variant_npos);
477 _Variadic_union<_Types...> _M_u;
478 using __index_type = __select_index<_Types...>;
479 __index_type _M_index;
482 template<
typename... _Types>
483 using _Variant_storage_alias =
484 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
486 template<
typename _Tp,
typename _Up>
487 void __variant_construct_single(_Tp&& __lhs, _Up&& __rhs_mem)
491 if constexpr (!is_same_v<_Type, __variant_cookie>)
496 template<
typename... _Types,
typename _Tp,
typename _Up>
497 void __variant_construct(_Tp&& __lhs, _Up&& __rhs)
499 __lhs._M_index = __rhs._M_index;
500 __variant::__raw_visit([&__lhs](
auto&& __rhs_mem)
mutable
502 __variant_construct_single(std::forward<_Tp>(__lhs),
504 }, __variant_cast<_Types...>(std::forward<_Up>(__rhs)));
510 template<bool,
typename... _Types>
511 struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
513 using _Base = _Variant_storage_alias<_Types...>;
516 _Copy_ctor_base(
const _Copy_ctor_base& __rhs)
517 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
519 __variant_construct<_Types...>(*
this, __rhs);
522 _Copy_ctor_base(_Copy_ctor_base&&) =
default;
523 _Copy_ctor_base& operator=(
const _Copy_ctor_base&) =
default;
524 _Copy_ctor_base& operator=(_Copy_ctor_base&&) =
default;
527 template<
typename... _Types>
528 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
530 using _Base = _Variant_storage_alias<_Types...>;
534 template<
typename... _Types>
535 using _Copy_ctor_alias =
536 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
538 template<bool,
typename... _Types>
539 struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
541 using _Base = _Copy_ctor_alias<_Types...>;
544 _Move_ctor_base(_Move_ctor_base&& __rhs)
545 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
547 __variant_construct<_Types...>(*
this,
std::move(__rhs));
550 template<
typename _Up>
551 void _M_destructive_move(
unsigned short __rhs_index, _Up&& __rhs)
554 __variant_construct_single(*
this, std::forward<_Up>(__rhs));
555 this->_M_index = __rhs_index;
558 template<
typename _Up>
559 void _M_destructive_copy(
unsigned short __rhs_index,
const _Up& __rhs)
562 __variant_construct_single(*
this, __rhs);
563 this->_M_index = __rhs_index;
566 _Move_ctor_base(
const _Move_ctor_base&) =
default;
567 _Move_ctor_base& operator=(
const _Move_ctor_base&) =
default;
568 _Move_ctor_base& operator=(_Move_ctor_base&&) =
default;
571 template<
typename... _Types>
572 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
574 using _Base = _Copy_ctor_alias<_Types...>;
577 template<
typename _Up>
578 void _M_destructive_move(
unsigned short __rhs_index, _Up&& __rhs)
581 __variant_construct_single(*
this, std::forward<_Up>(__rhs));
582 this->_M_index = __rhs_index;
585 template<
typename _Up>
586 void _M_destructive_copy(
unsigned short __rhs_index,
const _Up& __rhs)
589 __variant_construct_single(*
this, __rhs);
590 this->_M_index = __rhs_index;
594 template<
typename... _Types>
595 using _Move_ctor_alias =
596 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
598 template<bool,
typename... _Types>
599 struct _Copy_assign_base : _Move_ctor_alias<_Types...>
601 using _Base = _Move_ctor_alias<_Types...>;
605 operator=(
const _Copy_assign_base& __rhs)
606 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
608 __variant::__raw_idx_visit(
609 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
611 if constexpr (__rhs_index != variant_npos)
613 if (this->_M_index == __rhs_index)
614 __variant::__get<__rhs_index>(*
this) = __rhs_mem;
617 using __rhs_type = __remove_cvref_t<
decltype(__rhs_mem)>;
618 if constexpr (is_nothrow_copy_constructible_v<__rhs_type>
619 || !is_nothrow_move_constructible_v<__rhs_type>)
627 this->_M_destructive_copy(__rhs_index, __rhs_mem);
629 __variant_cast<_Types...>(*this)
630 = variant<_Types...>(std::in_place_index<__rhs_index>,
636 }, __variant_cast<_Types...>(__rhs));
640 _Copy_assign_base(
const _Copy_assign_base&) =
default;
641 _Copy_assign_base(_Copy_assign_base&&) =
default;
642 _Copy_assign_base& operator=(_Copy_assign_base&&) =
default;
645 template<
typename... _Types>
646 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
648 using _Base = _Move_ctor_alias<_Types...>;
652 template<
typename... _Types>
653 using _Copy_assign_alias =
654 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
656 template<bool,
typename... _Types>
657 struct _Move_assign_base : _Copy_assign_alias<_Types...>
659 using _Base = _Copy_assign_alias<_Types...>;
663 operator=(_Move_assign_base&& __rhs)
664 noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
666 __variant::__raw_idx_visit(
667 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable
669 if constexpr (__rhs_index != variant_npos)
671 if (this->_M_index == __rhs_index)
672 __variant::__get<__rhs_index>(*
this) =
std::move(__rhs_mem);
674 __variant_cast<_Types...>(*this)
675 .template emplace<__rhs_index>(
std::move(__rhs_mem));
679 }, __variant_cast<_Types...>(__rhs));
683 _Move_assign_base(
const _Move_assign_base&) =
default;
684 _Move_assign_base(_Move_assign_base&&) =
default;
685 _Move_assign_base& operator=(
const _Move_assign_base&) =
default;
688 template<
typename... _Types>
689 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
691 using _Base = _Copy_assign_alias<_Types...>;
695 template<
typename... _Types>
696 using _Move_assign_alias =
697 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
699 template<
typename... _Types>
700 struct _Variant_base : _Move_assign_alias<_Types...>
702 using _Base = _Move_assign_alias<_Types...>;
706 noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
707 : _Variant_base(in_place_index<0>) { }
709 template<
size_t _Np,
typename... _Args>
711 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
715 _Variant_base(
const _Variant_base&) =
default;
716 _Variant_base(_Variant_base&&) =
default;
717 _Variant_base& operator=(
const _Variant_base&) =
default;
718 _Variant_base& operator=(_Variant_base&&) =
default;
722 template<
typename _Tp,
typename _Tuple>
723 struct __tuple_count;
725 template<
typename _Tp,
typename _Tuple>
726 inline constexpr size_t __tuple_count_v =
727 __tuple_count<_Tp, _Tuple>::value;
729 template<
typename _Tp,
typename... _Types>
730 struct __tuple_count<_Tp, tuple<_Types...>>
731 : integral_constant<size_t, 0> { };
733 template<
typename _Tp,
typename _First,
typename... _Rest>
734 struct __tuple_count<_Tp, tuple<_First, _Rest...>>
737 __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
740 template<
typename _Tp,
typename... _Types>
741 inline constexpr bool __exactly_once =
742 __tuple_count_v<_Tp, tuple<_Types...>> == 1;
745 template<
typename _Ti>
struct _Arr { _Ti _M_x[1]; };
748 template<
size_t _Ind,
typename _Tp,
typename _Ti,
typename =
void>
757 template<
size_t _Ind,
typename _Tp,
typename _Ti>
758 struct _Build_FUN<_Ind, _Tp, _Ti,
759 void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>>
762 static integral_constant<size_t, _Ind> _S_fun(_Ti);
765 template<
typename _Tp,
typename _Variant,
766 typename = make_index_sequence<variant_size_v<_Variant>>>
769 template<
typename _Tp,
typename... _Ti,
size_t... _Ind>
771 : _Build_FUN<_Ind, _Tp, _Ti>...
773 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
778 template<
typename _Tp,
typename _Variant>
780 =
decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>()));
783 template<
typename _Tp,
typename _Variant,
typename =
void>
784 struct __accepted_index
785 : integral_constant<size_t, variant_npos>
788 template<
typename _Tp,
typename _Variant>
789 struct __accepted_index<_Tp, _Variant,
void_t<_FUN_type<_Tp, _Variant>>>
790 : _FUN_type<_Tp, _Variant>
793 template <
typename _Maybe_variant_cookie,
typename _Variant>
794 struct _Extra_visit_slot_needed
796 template <
typename>
struct _Variant_never_valueless;
798 template <
typename... _Types>
799 struct _Variant_never_valueless<variant<_Types...>>
800 :
bool_constant<__variant::__never_valueless<_Types...>()> {};
802 static constexpr bool value =
803 (is_same_v<_Maybe_variant_cookie, __variant_cookie>
804 || is_same_v<_Maybe_variant_cookie, __variant_idx_cookie>)
805 && !_Variant_never_valueless<__remove_cvref_t<_Variant>>::value;
809 template<
typename _Tp,
size_t... _Dimensions>
813 template<
typename _Tp>
814 struct _Multi_array<_Tp>
817 struct __untag_result
819 {
using element_type = _Tp; };
821 template <
typename... _Args>
822 struct __untag_result<const void(*)(_Args...)>
824 {
using element_type = void(*)(_Args...); };
826 template <
typename... _Args>
827 struct __untag_result<__variant_cookie(*)(_Args...)>
829 {
using element_type = void(*)(_Args...); };
831 template <
typename... _Args>
832 struct __untag_result<__variant_idx_cookie(*)(_Args...)>
834 {
using element_type = void(*)(_Args...); };
836 template <
typename _Res,
typename... _Args>
837 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
839 {
using element_type = _Res(*)(_Args...); };
841 using __result_is_deduced = __untag_result<_Tp>;
843 constexpr const typename __untag_result<_Tp>::element_type&
847 typename __untag_result<_Tp>::element_type _M_data;
851 template<
typename _Ret,
853 typename... _Variants,
854 size_t __first,
size_t... __rest>
855 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
857 static constexpr size_t __index =
858 sizeof...(_Variants) -
sizeof...(__rest) - 1;
860 using _Variant =
typename _Nth_type<__index, _Variants...>::type;
862 static constexpr int __do_cookie =
863 _Extra_visit_slot_needed<_Ret, _Variant>::value ? 1 : 0;
865 using _Tp = _Ret(*)(_Visitor, _Variants...);
867 template<
typename... _Args>
868 constexpr decltype(
auto)
869 _M_access(
size_t __first_index, _Args... __rest_indices)
const
871 return _M_arr[__first_index + __do_cookie]
872 ._M_access(__rest_indices...);
875 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
905 template<
typename _Array_type,
typename _Index_seq>
906 struct __gen_vtable_impl;
915 template<
typename _Result_type,
typename _Visitor,
size_t... __dimensions,
916 typename... _Variants,
size_t... __indices>
917 struct __gen_vtable_impl<
918 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
923 _Variants...>::type>;
925 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
928 static constexpr _Array_type
931 _Array_type __vtable{};
937 template<
size_t... __var_indices>
938 static constexpr void
939 _S_apply_all_alts(_Array_type& __vtable,
942 if constexpr (_Extra_visit_slot_needed<_Result_type, _Next>::value)
943 (_S_apply_single_alt<true, __var_indices>(
944 __vtable._M_arr[__var_indices + 1],
945 &(__vtable._M_arr[0])), ...);
947 (_S_apply_single_alt<false, __var_indices>(
948 __vtable._M_arr[__var_indices]), ...);
951 template<
bool __do_cookie,
size_t __index,
typename _Tp>
952 static constexpr void
953 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element =
nullptr)
955 if constexpr (__do_cookie)
957 __element = __gen_vtable_impl<
960 *__cookie_element = __gen_vtable_impl<
966 auto __tmp_element = __gen_vtable_impl<
969 static_assert(is_same_v<_Tp,
decltype(__tmp_element)>,
970 "std::visit requires the visitor to have the same "
971 "return type for all alternatives of a variant");
972 __element = __tmp_element;
980 template<
typename _Result_type,
typename _Visitor,
typename... _Variants,
982 struct __gen_vtable_impl<
983 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
987 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
989 template<
size_t __index,
typename _Variant>
990 static constexpr decltype(
auto)
991 __element_by_index_or_cookie(_Variant&& __var)
noexcept
993 if constexpr (__index != variant_npos)
994 return __variant::__get<__index>(std::forward<_Variant>(__var));
996 return __variant_cookie{};
999 static constexpr decltype(
auto)
1000 __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1002 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1006 __element_by_index_or_cookie<__indices>(
1007 std::forward<_Variants>(__vars))...,
1008 integral_constant<size_t, __indices>()...);
1009 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1012 __element_by_index_or_cookie<__indices>(
1013 std::forward<_Variants>(__vars))...);
1014 else if constexpr (_Array_type::__result_is_deduced::value)
1017 __element_by_index_or_cookie<__indices>(
1018 std::forward<_Variants>(__vars))...);
1020 return std::__invoke_r<_Result_type>(
1021 std::forward<_Visitor>(__visitor),
1022 __variant::__get<__indices>(std::forward<_Variants>(__vars))...);
1025 static constexpr auto
1028 if constexpr (_Array_type::__result_is_deduced::value)
1030 constexpr bool __visit_ret_type_mismatch =
1031 !is_same_v<
typename _Result_type::type,
1032 decltype(__visit_invoke(std::declval<_Visitor>(),
1033 std::declval<_Variants>()...))>;
1034 if constexpr (__visit_ret_type_mismatch)
1036 struct __cannot_match {};
1037 return __cannot_match{};
1040 return _Array_type{&__visit_invoke};
1043 return _Array_type{&__visit_invoke};
1047 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1051 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1052 variant_size_v<remove_reference_t<_Variants>>...>;
1054 static constexpr _Array_type _S_vtable
1055 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1058 template<
size_t _Np,
typename _Tp>
1059 struct _Base_dedup :
public _Tp { };
1061 template<
typename _Variant,
typename __indices>
1062 struct _Variant_hash_base;
1064 template<
typename... _Types,
size_t... __indices>
1065 struct _Variant_hash_base<variant<_Types...>,
1067 : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
1070 template<
size_t _Np,
typename _Variant,
1071 typename _AsV =
decltype(__variant::__as(std::declval<_Variant>())),
1072 typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>>
1074 =
conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1077 template<
typename _Visitor,
typename... _Variants>
1078 using __visit_result_t
1079 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1081 template<
typename _Tp,
typename... _Types>
1082 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1084 template <
typename _Visitor,
typename _Variant,
size_t... _Idxs>
1087 return __same_types<
1088 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1092 template<
size_t _Np,
typename _Variant,
typename... _Args>
1094 __construct_by_index(_Variant& __v, _Args&&... __args)
1096 auto&& __storage = __detail::__variant::__get<_Np>(__v);
1098 remove_reference_t<decltype(__storage)>
1099 (std::forward<_Args>(__args)...);
1107 template<
typename _Tp,
typename... _Types>
1109 holds_alternative(
const variant<_Types...>& __v)
noexcept
1111 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1112 "T must occur exactly once in alternatives");
1113 return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>;
1116 template<
typename _Tp,
typename... _Types>
1117 constexpr _Tp& get(variant<_Types...>& __v)
1119 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1120 "T must occur exactly once in alternatives");
1121 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1122 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
1125 template<
typename _Tp,
typename... _Types>
1126 constexpr _Tp&& get(variant<_Types...>&& __v)
1128 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1129 "T must occur exactly once in alternatives");
1130 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1131 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
1135 template<
typename _Tp,
typename... _Types>
1136 constexpr const _Tp& get(
const variant<_Types...>& __v)
1138 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1139 "T must occur exactly once in alternatives");
1140 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1141 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
1144 template<
typename _Tp,
typename... _Types>
1145 constexpr const _Tp&& get(
const variant<_Types...>&& __v)
1147 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1148 "T must occur exactly once in alternatives");
1149 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1150 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
1154 template<
size_t _Np,
typename... _Types>
1155 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1156 get_if(variant<_Types...>* __ptr)
noexcept
1158 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1159 static_assert(_Np <
sizeof...(_Types),
1160 "The index must be in [0, number of alternatives)");
1161 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1162 if (__ptr && __ptr->index() == _Np)
1167 template<
size_t _Np,
typename... _Types>
1169 add_pointer_t<
const variant_alternative_t<_Np, variant<_Types...>>>
1170 get_if(
const variant<_Types...>* __ptr)
noexcept
1172 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1173 static_assert(_Np <
sizeof...(_Types),
1174 "The index must be in [0, number of alternatives)");
1175 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1176 if (__ptr && __ptr->index() == _Np)
1181 template<
typename _Tp,
typename... _Types>
1182 constexpr add_pointer_t<_Tp>
1183 get_if(variant<_Types...>* __ptr)
noexcept
1185 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1186 "T must occur exactly once in alternatives");
1187 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1188 return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
1192 template<
typename _Tp,
typename... _Types>
1193 constexpr add_pointer_t<const _Tp>
1194 get_if(
const variant<_Types...>* __ptr)
noexcept
1196 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1197 "T must occur exactly once in alternatives");
1198 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1199 return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
1203 struct monostate { };
1205#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1206 template<typename... _Types> \
1207 constexpr bool operator __OP(const variant<_Types...>& __lhs, \
1208 const variant<_Types...>& __rhs) \
1210 bool __ret = true; \
1211 __detail::__variant::__raw_idx_visit( \
1212 [&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \
1214 if constexpr (__rhs_index != variant_npos) \
1216 if (__lhs.index() == __rhs_index) \
1218 auto& __this_mem = std::get<__rhs_index>(__lhs); \
1219 __ret = __this_mem __OP __rhs_mem; \
1222 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
1225 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
1230 _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1231 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1232 _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1233 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1234 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1235 _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1237#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1239 constexpr bool operator==(monostate, monostate)
noexcept {
return true; }
1241#ifdef __cpp_lib_three_way_comparison
1242 template<
typename... _Types>
1243 requires (three_way_comparable<_Types> && ...)
1245 common_comparison_category_t<compare_three_way_result_t<_Types>...>
1246 operator<=>(
const variant<_Types...>& __v,
const variant<_Types...>& __w)
1248 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1249 = strong_ordering::equal;
1251 __detail::__variant::__raw_idx_visit(
1252 [&__ret, &__v] (
auto&& __w_mem,
auto __w_index)
mutable
1254 if constexpr (__w_index != variant_npos)
1256 if (__v.index() == __w_index)
1258 auto& __this_mem = std::get<__w_index>(__v);
1259 __ret = __this_mem <=> __w_mem;
1263 __ret = (__v.index() + 1) <=> (__w_index + 1);
1268 constexpr strong_ordering
1269 operator<=>(monostate, monostate)
noexcept {
return strong_ordering::equal; }
1271 constexpr bool operator!=(monostate, monostate)
noexcept {
return false; }
1272 constexpr bool operator<(monostate, monostate)
noexcept {
return false; }
1273 constexpr bool operator>(monostate, monostate)
noexcept {
return false; }
1274 constexpr bool operator<=(monostate, monostate)
noexcept {
return true; }
1275 constexpr bool operator>=(monostate, monostate)
noexcept {
return true; }
1278 template<
typename _Visitor,
typename... _Variants>
1279 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1280 visit(_Visitor&&, _Variants&&...);
1282 template<
typename... _Types>
1283 inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1284 && (is_swappable_v<_Types> && ...)>
1285 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1286 noexcept(
noexcept(__lhs.swap(__rhs)))
1287 { __lhs.swap(__rhs); }
1289 template<
typename... _Types>
1290 enable_if_t<!((is_move_constructible_v<_Types> && ...)
1291 && (is_swappable_v<_Types> && ...))>
1292 swap(variant<_Types...>&, variant<_Types...>&) =
delete;
1294 class bad_variant_access :
public exception
1297 bad_variant_access() noexcept { }
1299 const char* what() const noexcept
override
1300 {
return _M_reason; }
1303 bad_variant_access(
const char* __reason) noexcept : _M_reason(__reason) { }
1306 const char* _M_reason =
"bad variant access";
1308 friend void __throw_bad_variant_access(
const char* __what);
1313 __throw_bad_variant_access(
const char* __what)
1314 { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1317 __throw_bad_variant_access(
bool __valueless)
1319 if (__valueless) [[__unlikely__]]
1320 __throw_bad_variant_access(
"std::get: variant is valueless");
1322 __throw_bad_variant_access(
"std::get: wrong index for variant");
1325 template<
typename... _Types>
1327 :
private __detail::__variant::_Variant_base<_Types...>,
1328 private _Enable_default_constructor<
1329 __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1330 variant<_Types...>>,
1331 private _Enable_copy_move<
1332 __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1333 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1334 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1335 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1339 template <
typename... _UTypes,
typename _Tp>
1340 friend decltype(
auto) __variant_cast(_Tp&&);
1341 template<
size_t _Np,
typename _Variant,
typename... _Args>
1343 __detail::__variant::__construct_by_index(_Variant& __v,
1346 static_assert(
sizeof...(_Types) > 0,
1347 "variant must have at least one alternative");
1348 static_assert(!(std::is_reference_v<_Types> || ...),
1349 "variant must have no reference alternative");
1350 static_assert(!(std::is_void_v<_Types> || ...),
1351 "variant must have no void alternative");
1353 using _Base = __detail::__variant::_Variant_base<_Types...>;
1354 using _Default_ctor_enabler =
1355 _Enable_default_constructor<
1356 __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1357 variant<_Types...>>;
1359 template<
typename _Tp>
1360 static constexpr bool __not_self
1361 = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1363 template<
typename _Tp>
1364 static constexpr bool
1365 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1367 template<
typename _Tp>
1368 static constexpr size_t __accepted_index
1369 = __detail::__variant::__accepted_index<_Tp, variant>::value;
1371 template<
size_t _Np,
typename =
enable_if_t<(_Np <
sizeof...(_Types))>>
1372 using __to_type = variant_alternative_t<_Np, variant>;
1374 template<
typename _Tp,
typename = enable_if_t<__not_self<_Tp>>>
1375 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1377 template<
typename _Tp>
1378 static constexpr size_t __index_of =
1379 __detail::__variant::__index_of_v<_Tp, _Types...>;
1381 using _Traits = __detail::__variant::_Traits<_Types...>;
1383 template<
typename _Tp>
1385 template<
typename _Tp>
1386 struct __is_in_place_tag<in_place_type_t<_Tp>> :
true_type { };
1387 template<
size_t _Np>
1388 struct __is_in_place_tag<in_place_index_t<_Np>> :
true_type { };
1390 template<
typename _Tp>
1391 static constexpr bool __not_in_place_tag
1392 = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value;
1395 variant() =
default;
1396 variant(
const variant& __rhs) =
default;
1397 variant(variant&&) =
default;
1398 variant& operator=(
const variant&) =
default;
1399 variant& operator=(variant&&) =
default;
1400 ~variant() =
default;
1402 template<
typename _Tp,
1405 typename _Tj = __accepted_type<_Tp&&>,
1407 && is_constructible_v<_Tj, _Tp>>>
1410 noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1411 : variant(in_place_index<__accepted_index<_Tp>>,
1415 template<
typename _Tp,
typename... _Args,
1416 typename = enable_if_t<__exactly_once<_Tp>
1417 && is_constructible_v<_Tp, _Args...>>>
1419 variant(in_place_type_t<_Tp>, _Args&&... __args)
1420 : variant(in_place_index<__index_of<_Tp>>,
1424 template<
typename _Tp,
typename _Up,
typename... _Args,
1425 typename = enable_if_t<__exactly_once<_Tp>
1426 && is_constructible_v<_Tp,
1427 initializer_list<_Up>&, _Args...>>>
1429 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1431 : variant(in_place_index<__index_of<_Tp>>, __il,
1435 template<
size_t _Np,
typename... _Args,
1436 typename _Tp = __to_type<_Np>,
1437 typename =
enable_if_t<is_constructible_v<_Tp, _Args...>>>
1439 variant(in_place_index_t<_Np>, _Args&&... __args)
1440 : _Base(in_place_index<_Np>,
std::
forward<_Args>(__args)...),
1441 _Default_ctor_enabler(_Enable_default_constructor_tag{})
1444 template<
size_t _Np,
typename _Up,
typename... _Args,
1445 typename _Tp = __to_type<_Np>,
1447 initializer_list<_Up>&,
1450 variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1452 : _Base(in_place_index<_Np>, __il,
std::
forward<_Args>(__args)...),
1453 _Default_ctor_enabler(_Enable_default_constructor_tag{})
1456 template<
typename _Tp>
1457 enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1458 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1459 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1461 operator=(_Tp&& __rhs)
1462 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1463 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1465 constexpr auto __index = __accepted_index<_Tp>;
1466 if (index() == __index)
1467 std::get<__index>(*
this) = std::forward<_Tp>(__rhs);
1470 using _Tj = __accepted_type<_Tp&&>;
1471 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1472 || !is_nothrow_move_constructible_v<_Tj>)
1473 this->emplace<__index>(std::forward<_Tp>(__rhs));
1477 this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs)));
1482 template<
typename _Tp,
typename... _Args>
1483 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1485 emplace(_Args&&... __args)
1487 constexpr size_t __index = __index_of<_Tp>;
1488 return this->emplace<__index>(std::forward<_Args>(__args)...);
1491 template<
typename _Tp,
typename _Up,
typename... _Args>
1492 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1493 && __exactly_once<_Tp>,
1495 emplace(initializer_list<_Up> __il, _Args&&... __args)
1497 constexpr size_t __index = __index_of<_Tp>;
1498 return this->emplace<__index>(__il, std::forward<_Args>(__args)...);
1501 template<
size_t _Np,
typename... _Args>
1502 enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1504 variant_alternative_t<_Np, variant>&>
1505 emplace(_Args&&... __args)
1507 static_assert(_Np <
sizeof...(_Types),
1508 "The index must be in [0, number of alternatives)");
1509 using type = variant_alternative_t<_Np, variant>;
1510 namespace __variant = std::__detail::__variant;
1513 if constexpr (is_nothrow_constructible_v<type, _Args...>)
1516 __variant::__construct_by_index<_Np>(*
this,
1517 std::forward<_Args>(__args)...);
1519 else if constexpr (is_scalar_v<type>)
1522 const type __tmp(std::forward<_Args>(__args)...);
1525 __variant::__construct_by_index<_Np>(*
this, __tmp);
1527 else if constexpr (__variant::_Never_valueless_alt<type>()
1528 && _Traits::_S_move_assign)
1531 variant __tmp(in_place_index<_Np>,
1532 std::forward<_Args>(__args)...);
1541 __variant::__construct_by_index<_Np>(*
this,
1542 std::forward<_Args>(__args)...);
1544 return std::get<_Np>(*
this);
1547 template<
size_t _Np,
typename _Up,
typename... _Args>
1548 enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1549 initializer_list<_Up>&, _Args...>,
1550 variant_alternative_t<_Np, variant>&>
1551 emplace(initializer_list<_Up> __il, _Args&&... __args)
1553 static_assert(_Np <
sizeof...(_Types),
1554 "The index must be in [0, number of alternatives)");
1555 using type = variant_alternative_t<_Np, variant>;
1556 namespace __variant = std::__detail::__variant;
1559 if constexpr (is_nothrow_constructible_v<type,
1560 initializer_list<_Up>&,
1564 __variant::__construct_by_index<_Np>(*
this, __il,
1565 std::forward<_Args>(__args)...);
1567 else if constexpr (__variant::_Never_valueless_alt<type>()
1568 && _Traits::_S_move_assign)
1571 variant __tmp(in_place_index<_Np>, __il,
1572 std::forward<_Args>(__args)...);
1581 __variant::__construct_by_index<_Np>(*
this, __il,
1582 std::forward<_Args>(__args)...);
1584 return std::get<_Np>(*
this);
1587 constexpr bool valueless_by_exception() const noexcept
1588 {
return !this->_M_valid(); }
1590 constexpr size_t index() const noexcept
1592 using __index_type =
typename _Base::__index_type;
1593 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1594 return this->_M_index;
1595 else if constexpr (
sizeof...(_Types) <= __index_type(-1) / 2)
1596 return make_signed_t<__index_type>(this->_M_index);
1598 return size_t(__index_type(this->_M_index + 1)) - 1;
1602 swap(variant& __rhs)
1603 noexcept((__is_nothrow_swappable<_Types>::value && ...)
1604 && is_nothrow_move_constructible_v<variant>)
1606 __detail::__variant::__raw_idx_visit(
1607 [
this, &__rhs](
auto&& __rhs_mem,
auto __rhs_index)
mutable
1609 if constexpr (__rhs_index != variant_npos)
1611 if (this->index() == __rhs_index)
1614 std::get<__rhs_index>(*
this);
1616 swap(__this_mem, __rhs_mem);
1620 if (!this->valueless_by_exception()) [[__likely__]]
1624 this->_M_destructive_move(__rhs_index,
1629 this->_M_destructive_move(__rhs_index,
1637 if (!this->valueless_by_exception()) [[__likely__]]
1648#if defined(__clang__) && __clang_major__ <= 7
1654 template<
size_t _Np,
typename _Vp>
1655 friend constexpr decltype(
auto)
1656 __detail::__variant::__get(_Vp&& __v)
noexcept;
1658#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1659 template<typename... _Tp> \
1660 friend constexpr bool \
1661 operator __OP(const variant<_Tp...>& __lhs, \
1662 const variant<_Tp...>& __rhs);
1664 _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1665 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1666 _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1667 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1668 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1669 _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1671#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1674 template<
size_t _Np,
typename... _Types>
1675 constexpr variant_alternative_t<_Np, variant<_Types...>>&
1676 get(variant<_Types...>& __v)
1678 static_assert(_Np <
sizeof...(_Types),
1679 "The index must be in [0, number of alternatives)");
1680 if (__v.index() != _Np)
1681 __throw_bad_variant_access(__v.valueless_by_exception());
1682 return __detail::__variant::__get<_Np>(__v);
1685 template<
size_t _Np,
typename... _Types>
1686 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1687 get(variant<_Types...>&& __v)
1689 static_assert(_Np <
sizeof...(_Types),
1690 "The index must be in [0, number of alternatives)");
1691 if (__v.index() != _Np)
1692 __throw_bad_variant_access(__v.valueless_by_exception());
1693 return __detail::__variant::__get<_Np>(
std::move(__v));
1696 template<
size_t _Np,
typename... _Types>
1697 constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1698 get(
const variant<_Types...>& __v)
1700 static_assert(_Np <
sizeof...(_Types),
1701 "The index must be in [0, number of alternatives)");
1702 if (__v.index() != _Np)
1703 __throw_bad_variant_access(__v.valueless_by_exception());
1704 return __detail::__variant::__get<_Np>(__v);
1707 template<
size_t _Np,
typename... _Types>
1708 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1709 get(
const variant<_Types...>&& __v)
1711 static_assert(_Np <
sizeof...(_Types),
1712 "The index must be in [0, number of alternatives)");
1713 if (__v.index() != _Np)
1714 __throw_bad_variant_access(__v.valueless_by_exception());
1715 return __detail::__variant::__get<_Np>(
std::move(__v));
1719 template<
typename _Result_type,
typename _Visitor,
typename... _Variants>
1720 constexpr decltype(
auto)
1721 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1723 constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1724 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1726 auto __func_ptr = __vtable._M_access(__variants.index()...);
1727 return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1728 std::forward<_Variants>(__variants)...);
1732 template<
typename _Visitor,
typename... _Variants>
1733 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1734 visit(_Visitor&& __visitor, _Variants&&... __variants)
1736 namespace __variant = std::__detail::__variant;
1738 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1739 __throw_bad_variant_access(
"std::visit: variant is valueless");
1742 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1744 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1746 if constexpr (
sizeof...(_Variants) == 1)
1748 using _Vp =
decltype(__variant::__as(std::declval<_Variants>()...));
1750 constexpr bool __visit_rettypes_match = __detail::__variant::
1751 __check_visitor_results<_Visitor, _Vp>(
1753 if constexpr (!__visit_rettypes_match)
1755 static_assert(__visit_rettypes_match,
1756 "std::visit requires the visitor to have the same "
1757 "return type for all alternatives of a variant");
1761 return std::__do_visit<_Tag>(
1762 std::forward<_Visitor>(__visitor),
1763 static_cast<_Vp
>(__variants)...);
1766 return std::__do_visit<_Tag>(
1767 std::forward<_Visitor>(__visitor),
1768 __variant::__as(std::forward<_Variants>(__variants))...);
1771#if __cplusplus > 201703L
1772 template<
typename _Res,
typename _Visitor,
typename... _Variants>
1774 visit(_Visitor&& __visitor, _Variants&&... __variants)
1776 namespace __variant = std::__detail::__variant;
1778 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1779 __throw_bad_variant_access(
"std::visit<R>: variant is valueless");
1781 return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor),
1782 __variant::__as(std::forward<_Variants>(__variants))...);
1787 template<bool,
typename... _Types>
1788 struct __variant_hash_call_base_impl
1791 operator()(
const variant<_Types...>& __t)
const
1792 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1795 __detail::__variant::__raw_visit(
1796 [&__t, &__ret](
auto&& __t_mem)
mutable
1798 using _Type = __remove_cvref_t<
decltype(__t_mem)>;
1799 if constexpr (!is_same_v<_Type,
1800 __detail::__variant::__variant_cookie>)
1810 template<
typename... _Types>
1811 struct __variant_hash_call_base_impl<false, _Types...> {};
1813 template<
typename... _Types>
1814 using __variant_hash_call_base =
1815 __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
1816 __enable_hash_call &&...), _Types...>;
1819 template<
typename... _Types>
1820 struct hash<variant<_Types...>>
1821 :
private __detail::__variant::_Variant_hash_base<
1822 variant<_Types...>, std::index_sequence_for<_Types...>>,
1823 public __variant_hash_call_base<_Types...>
1825 using result_type [[__deprecated__]] = size_t;
1826 using argument_type [[__deprecated__]] = variant<_Types...>;
1830 struct hash<monostate>
1832 using result_type [[__deprecated__]] = size_t;
1833 using argument_type [[__deprecated__]] = monostate;
1836 operator()(
const monostate&)
const noexcept
1838 constexpr size_t __magic_monostate_hash = -7777;
1839 return __magic_monostate_hash;
1843 template<
typename... _Types>
1844 struct __is_fast_hash<hash<variant<_Types...>>>
1848_GLIBCXX_END_NAMESPACE_VERSION
typename remove_reference< _Tp >::type remove_reference_t
Alias template for remove_reference.
integral_constant< bool, __v > bool_constant
Alias template for compile-time boolean constant types.
void void_t
A metafunction that always yields void, used for detecting valid types.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
typename conditional< _Cond, _Iftrue, _Iffalse >::type conditional_t
Alias template for conditional.
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
typename add_pointer< _Tp >::type add_pointer_t
Alias template for add_pointer.
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
constexpr _Tp * addressof(_Tp &__r) noexcept
Returns the actual address of the object or function referenced by r, even in the presence of an over...
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
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.
Primary class template hash.
Class template integer_sequence.