1#ifdef IPPL_USE_ALTERNATIVE_VARIANT
30#ifndef _GLIBCXX_VARIANT
31#define _GLIBCXX_VARIANT 1
33#pragma GCC system_header
35#if __cplusplus >= 201703L
37#include <bits/enable_special_members.h>
38#include <bits/exception_defines.h>
39#include <bits/functional_hash.h>
40#include <bits/invoke.h>
41#include <bits/parse_numbers.h>
42#include <bits/stl_construct.h>
43#include <bits/stl_iterator_base_funcs.h>
44#include <bits/utility.h>
45#include <initializer_list>
47#if __cplusplus >= 202002L
51#if __cpp_concepts >= 202002L && __cpp_constexpr >= 201811L
53#define __cpp_lib_variant 202106L
55#include <ext/aligned_buffer.h>
56#define __cpp_lib_variant 202102L
59namespace std _GLIBCXX_VISIBILITY(default) {
60 _GLIBCXX_BEGIN_NAMESPACE_VERSION
62 template <
typename... _Types>
64 template <
typename... _Types>
69 template <
typename _Variant>
72 template <
typename _Variant>
73 struct variant_size<const _Variant> : variant_size<_Variant> {};
75 template <
typename _Variant>
76 struct variant_size<volatile _Variant> : variant_size<_Variant> {};
78 template <
typename _Variant>
79 struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
81 template <
typename... _Types>
82 struct variant_size<variant<_Types...>> : std::integral_constant<size_t, sizeof...(_Types)> {};
84 template <
typename _Variant>
85 inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
87 template <
typename... _Types>
88 inline constexpr size_t variant_size_v<variant<_Types...>> =
sizeof...(_Types);
90 template <
typename... _Types>
91 inline constexpr size_t variant_size_v<
const variant<_Types...>> =
sizeof...(_Types);
93 template <
size_t _Np,
typename _Variant>
94 struct variant_alternative;
96 template <
size_t _Np,
typename... _Types>
97 struct variant_alternative<_Np, variant<_Types...>> {
98 static_assert(_Np <
sizeof...(_Types));
100 using type =
typename _Nth_type<_Np, _Types...>::type;
103 template <
size_t _Np,
typename _Variant>
104 using variant_alternative_t =
typename variant_alternative<_Np, _Variant>::type;
106 template <
size_t _Np,
typename _Variant>
107 struct variant_alternative<_Np, const _Variant> {
108 using type =
const variant_alternative_t<_Np, _Variant>;
111 template <
size_t _Np,
typename _Variant>
112 struct variant_alternative<_Np, volatile _Variant> {
113 using type =
volatile variant_alternative_t<_Np, _Variant>;
116 template <
size_t _Np,
typename _Variant>
117 struct variant_alternative<_Np, const volatile _Variant> {
118 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...>>&
get(variant<_Types...>&);
126 template <
size_t _Np,
typename... _Types>
127 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
get(variant<_Types...>&&);
129 template <
size_t _Np,
typename... _Types>
130 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&
get(
const variant<_Types...>&);
132 template <
size_t _Np,
typename... _Types>
133 constexpr variant_alternative_t<_Np, variant<_Types...>>
const&&
get(
134 const variant<_Types...>&&);
136 template <
typename _Result_type,
typename _Visitor,
typename... _Variants>
137 constexpr decltype(
auto) __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
139 template <
typename... _Types,
typename _Tp>
140 _GLIBCXX20_CONSTEXPR
decltype(
auto) __variant_cast(_Tp&& __rhs) {
141 if constexpr (is_lvalue_reference_v<_Tp>) {
142 if constexpr (is_const_v<remove_reference_t<_Tp>>)
143 return static_cast<const variant<_Types...
>&>(__rhs);
145 return static_cast<variant<_Types...
>&>(__rhs);
147 return static_cast<variant<_Types...
>&&>(__rhs);
151 namespace __variant {
153 struct __variant_cookie {};
155 struct __variant_idx_cookie {
156 using type = __variant_idx_cookie;
159 template <
typename _Tp>
160 struct __deduce_visit_result {
165 template <
typename _Visitor,
typename... _Variants>
166 constexpr void __raw_visit(_Visitor&& __visitor, _Variants&&... __variants) {
167 std::__do_visit<__variant_cookie>(std::forward<_Visitor>(__visitor),
168 std::forward<_Variants>(__variants)...);
172 template <
typename _Visitor,
typename... _Variants>
173 constexpr void __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants) {
174 std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor),
175 std::forward<_Variants>(__variants)...);
180 template <
typename... _Types>
181 constexpr std::variant<_Types...>& __as(std::variant<_Types...>& __v)
noexcept {
185 template <
typename... _Types>
186 constexpr const std::variant<_Types...>& __as(
187 const std::variant<_Types...>& __v)
noexcept {
191 template <
typename... _Types>
192 constexpr std::variant<_Types...>&& __as(std::variant<_Types...>&& __v)
noexcept {
193 return std::move(__v);
196 template <
typename... _Types>
197 constexpr const std::variant<_Types...>&& __as(
198 const std::variant<_Types...>&& __v)
noexcept {
199 return std::move(__v);
208 template <
typename _Type,
bool = std::is_trivially_destructible_v<_Type>>
209 struct _Uninitialized;
211 template <
typename _Type>
212 struct _Uninitialized<_Type, true> {
213 template <
typename... _Args>
214 constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args)
215 : _M_storage(std::forward<_Args>(__args)...) {}
217 constexpr const _Type& _M_get() const& noexcept {
return _M_storage; }
219 constexpr _Type& _M_get() &
noexcept {
return _M_storage; }
221 constexpr const _Type&& _M_get() const&& noexcept {
return std::move(_M_storage); }
223 constexpr _Type&& _M_get() &&
noexcept {
return std::move(_M_storage); }
228 template <
typename _Type>
229 struct _Uninitialized<_Type, false> {
230#if __cpp_lib_variant >= 202106L
231 template <
typename... _Args>
232 constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args)
233 : _M_storage(std::forward<_Args>(__args)...) {}
235 constexpr ~_Uninitialized() {}
237 _Uninitialized(
const _Uninitialized&) =
default;
238 _Uninitialized(_Uninitialized&&) =
default;
239 _Uninitialized& operator=(
const _Uninitialized&) =
default;
240 _Uninitialized& operator=(_Uninitialized&&) =
default;
242 constexpr const _Type& _M_get() const& noexcept {
return _M_storage; }
244 constexpr _Type& _M_get() &
noexcept {
return _M_storage; }
246 constexpr const _Type&& _M_get() const&& noexcept {
return std::move(_M_storage); }
248 constexpr _Type&& _M_get() &&
noexcept {
return std::move(_M_storage); }
250 struct _Empty_byte {};
253 _Empty_byte _M_empty;
257 template <
typename... _Args>
258 constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args) {
259 ::new ((
void*)std::addressof(_M_storage)) _Type(std::forward<_Args>(__args)...);
262 const _Type& _M_get() const& noexcept {
return *_M_storage._M_ptr(); }
264 _Type& _M_get() &
noexcept {
return *_M_storage._M_ptr(); }
266 const _Type&& _M_get() const&& noexcept {
return std::move(*_M_storage._M_ptr()); }
268 _Type&& _M_get() &&
noexcept {
return std::move(*_M_storage._M_ptr()); }
270 __gnu_cxx::__aligned_membuf<_Type> _M_storage;
274 template <
size_t _Np,
typename _Union>
275 constexpr decltype(
auto) __get_n(_Union&& __u)
noexcept {
276 if constexpr (_Np == 0)
277 return std::forward<_Union>(__u)._M_first._M_get();
278 else if constexpr (_Np == 1)
279 return std::forward<_Union>(__u)._M_rest._M_first._M_get();
280 else if constexpr (_Np == 2)
281 return std::forward<_Union>(__u)._M_rest._M_rest._M_first._M_get();
283 return __variant::__get_n<_Np - 3>(
284 std::forward<_Union>(__u)._M_rest._M_rest._M_rest);
288 template <
size_t _Np,
typename _Variant>
289 constexpr decltype(
auto) __get(_Variant&& __v)
noexcept {
290 return __variant::__get_n<_Np>(std::forward<_Variant>(__v)._M_u);
293 template <
typename... _Types>
295 static constexpr bool _S_default_ctor =
296 is_default_constructible_v<
typename _Nth_type<0, _Types...>::type>;
297 static constexpr bool _S_copy_ctor = (is_copy_constructible_v<_Types> && ...);
298 static constexpr bool _S_move_ctor = (is_move_constructible_v<_Types> && ...);
299 static constexpr bool _S_copy_assign =
300 _S_copy_ctor && (is_copy_assignable_v<_Types> && ...);
301 static constexpr bool _S_move_assign =
302 _S_move_ctor && (is_move_assignable_v<_Types> && ...);
304 static constexpr bool _S_trivial_dtor =
305 (is_trivially_destructible_v<_Types> && ...);
306 static constexpr bool _S_trivial_copy_ctor =
307 (is_trivially_copy_constructible_v<_Types> && ...);
308 static constexpr bool _S_trivial_move_ctor =
309 (is_trivially_move_constructible_v<_Types> && ...);
310 static constexpr bool _S_trivial_copy_assign =
311 _S_trivial_dtor && _S_trivial_copy_ctor
312 && (is_trivially_copy_assignable_v<_Types> && ...);
313 static constexpr bool _S_trivial_move_assign =
314 _S_trivial_dtor && _S_trivial_move_ctor
315 && (is_trivially_move_assignable_v<_Types> && ...);
319 static constexpr bool _S_nothrow_default_ctor =
320 is_nothrow_default_constructible_v<
typename _Nth_type<0, _Types...>::type>;
321 static constexpr bool _S_nothrow_copy_ctor =
false;
322 static constexpr bool _S_nothrow_move_ctor =
323 (is_nothrow_move_constructible_v<_Types> && ...);
324 static constexpr bool _S_nothrow_copy_assign =
false;
325 static constexpr bool _S_nothrow_move_assign =
326 _S_nothrow_move_ctor && (is_nothrow_move_assignable_v<_Types> && ...);
330 template <
typename... _Types>
331 union _Variadic_union {
332 _Variadic_union() =
default;
334 template <
size_t _Np,
typename... _Args>
335 _Variadic_union(in_place_index_t<_Np>, _Args&&...) =
delete;
338 template <
typename _First,
typename... _Rest>
339 union _Variadic_union<_First, _Rest...> {
340 constexpr _Variadic_union()
343 template <
typename... _Args>
344 constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args)
345 : _M_first(in_place_index<0>, std::forward<_Args>(__args)...) {}
347 template <
size_t _Np,
typename... _Args>
348 constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
349 : _M_rest(in_place_index<_Np - 1>, std::forward<_Args>(__args)...) {}
351#if __cpp_lib_variant >= 202106L
352 _Variadic_union(
const _Variadic_union&) =
default;
353 _Variadic_union(_Variadic_union&&) =
default;
354 _Variadic_union& operator=(
const _Variadic_union&) =
default;
355 _Variadic_union& operator=(_Variadic_union&&) =
default;
357 ~_Variadic_union(){};
359 constexpr ~_Variadic_union()
360 requires(!__has_trivial_destructor(_First))
361 || (!__has_trivial_destructor(_Variadic_union<_Rest...>))
365 _Uninitialized<_First> _M_first;
366 _Variadic_union<_Rest...> _M_rest;
374 template <
typename _Tp>
375 struct _Never_valueless_alt
376 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>> {};
388 template <typename... _Types>
389 constexpr bool __never_valueless() {
390 return _Traits<_Types...>::_S_move_assign
391 && (_Never_valueless_alt<_Types>::value && ...);
395 template <bool __trivially_destructible, typename... _Types>
396 struct _Variant_storage;
398 template <typename... _Types>
399 using __select_index =
400 typename __select_int::_Select_int_base<sizeof...(_Types), unsigned char,
401 unsigned short>::type::value_type;
403 template <typename... _Types>
404 struct _Variant_storage<false, _Types...> {
405 constexpr _Variant_storage()
406 : _M_index(static_cast<__index_type>(variant_npos)) {}
408 template <size_t _Np, typename... _Args>
409 constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
410 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...)
413 constexpr void _M_reset() {
414 if (!_M_valid()) [[unlikely]]
417 std::__do_visit<void>(
418 [](auto&& __this_mem) mutable {
419 std::_Destroy(std::__addressof(__this_mem));
421 __variant_cast<_Types...>(*this));
423 _M_index = static_cast<__index_type>(variant_npos);
427 ~_Variant_storage() { _M_reset(); }
429 constexpr bool _M_valid() const noexcept {
430 if constexpr (__variant::__never_valueless<_Types...>())
432 return this->_M_index != __index_type(variant_npos);
435 _Variadic_union<_Types...> _M_u;
436 using __index_type = __select_index<_Types...>;
437 __index_type _M_index;
440 template <typename... _Types>
441 struct _Variant_storage<true, _Types...> {
442 constexpr _Variant_storage()
443 : _M_index(static_cast<__index_type>(variant_npos)) {}
445 template <
size_t _Np,
typename... _Args>
446 constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
447 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...)
450 constexpr void _M_reset() noexcept {
451 _M_index =
static_cast<__index_type
>(variant_npos);
454 constexpr bool _M_valid() const noexcept {
455 if constexpr (__variant::__never_valueless<_Types...>())
463 return this->_M_index !=
static_cast<__index_type
>(variant_npos);
466 _Variadic_union<_Types...> _M_u;
467 using __index_type = __select_index<_Types...>;
468 __index_type _M_index;
472 template <
size_t _Np,
bool _Triv,
typename... _Types,
typename... _Args>
473 _GLIBCXX20_CONSTEXPR
inline void __emplace(_Variant_storage<_Triv, _Types...>& __v,
476 auto* __addr = std::__addressof(__variant::__get_n<_Np>(__v._M_u));
477 std::_Construct(__addr, std::forward<_Args>(__args)...);
482 template <
typename... _Types>
483 using _Variant_storage_alias =
484 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
489 template <bool,
typename... _Types>
490 struct _Copy_ctor_base : _Variant_storage_alias<_Types...> {
491 using _Base = _Variant_storage_alias<_Types...>;
495 _Copy_ctor_base(
const _Copy_ctor_base& __rhs)
noexcept(
496 _Traits<_Types...>::_S_nothrow_copy_ctor) {
497 __variant::__raw_idx_visit(
498 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable {
499 constexpr size_t __j = __rhs_index;
500 if constexpr (__j != variant_npos)
501 std::_Construct(std::__addressof(this->_M_u), in_place_index<__j>,
504 __variant_cast<_Types...>(__rhs));
505 this->_M_index = __rhs._M_index;
508 _Copy_ctor_base(_Copy_ctor_base&&) =
default;
509 _Copy_ctor_base& operator=(
const _Copy_ctor_base&) =
default;
510 _Copy_ctor_base& operator=(_Copy_ctor_base&&) =
default;
513 template <
typename... _Types>
514 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...> {
515 using _Base = _Variant_storage_alias<_Types...>;
519 template <
typename... _Types>
520 using _Copy_ctor_alias =
521 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
523 template <bool,
typename... _Types>
524 struct _Move_ctor_base : _Copy_ctor_alias<_Types...> {
525 using _Base = _Copy_ctor_alias<_Types...>;
529 _Move_ctor_base(_Move_ctor_base&& __rhs)
noexcept(
530 _Traits<_Types...>::_S_nothrow_move_ctor) {
531 __variant::__raw_idx_visit(
532 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable {
533 constexpr size_t __j = __rhs_index;
534 if constexpr (__j != variant_npos)
535 std::_Construct(std::__addressof(this->_M_u), in_place_index<__j>,
536 std::forward<
decltype(__rhs_mem)>(__rhs_mem));
538 __variant_cast<_Types...>(std::move(__rhs)));
539 this->_M_index = __rhs._M_index;
542 _Move_ctor_base(
const _Move_ctor_base&) =
default;
543 _Move_ctor_base& operator=(
const _Move_ctor_base&) =
default;
544 _Move_ctor_base& operator=(_Move_ctor_base&&) =
default;
547 template <
typename... _Types>
548 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...> {
549 using _Base = _Copy_ctor_alias<_Types...>;
553 template <
typename... _Types>
554 using _Move_ctor_alias =
555 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
557 template <bool,
typename... _Types>
558 struct _Copy_assign_base : _Move_ctor_alias<_Types...> {
559 using _Base = _Move_ctor_alias<_Types...>;
563 _Copy_assign_base& operator=(
const _Copy_assign_base& __rhs)
noexcept(
564 _Traits<_Types...>::_S_nothrow_copy_assign) {
565 __variant::__raw_idx_visit(
566 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable {
567 constexpr size_t __j = __rhs_index;
568 if constexpr (__j == variant_npos)
570 else if (this->_M_index == __j)
571 __variant::__get<__j>(*
this) = __rhs_mem;
573 using _Tj =
typename _Nth_type<__j, _Types...>::type;
574 if constexpr (is_nothrow_copy_constructible_v<_Tj>
575 || !is_nothrow_move_constructible_v<_Tj>)
576 __variant::__emplace<__j>(*
this, __rhs_mem);
578 using _Variant = variant<_Types...>;
579 _Variant& __self = __variant_cast<_Types...>(*this);
580 __self = _Variant(in_place_index<__j>, __rhs_mem);
584 __variant_cast<_Types...>(__rhs));
588 _Copy_assign_base(
const _Copy_assign_base&) =
default;
589 _Copy_assign_base(_Copy_assign_base&&) =
default;
590 _Copy_assign_base& operator=(_Copy_assign_base&&) =
default;
593 template <
typename... _Types>
594 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...> {
595 using _Base = _Move_ctor_alias<_Types...>;
599 template <
typename... _Types>
600 using _Copy_assign_alias =
601 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
603 template <bool,
typename... _Types>
604 struct _Move_assign_base : _Copy_assign_alias<_Types...> {
605 using _Base = _Copy_assign_alias<_Types...>;
609 _Move_assign_base& operator=(_Move_assign_base&& __rhs)
noexcept(
610 _Traits<_Types...>::_S_nothrow_move_assign) {
611 __variant::__raw_idx_visit(
612 [
this](
auto&& __rhs_mem,
auto __rhs_index)
mutable {
613 constexpr size_t __j = __rhs_index;
614 if constexpr (__j != variant_npos) {
615 if (this->_M_index == __j)
616 __variant::__get<__j>(*
this) = std::move(__rhs_mem);
618 using _Tj =
typename _Nth_type<__j, _Types...>::type;
619 if constexpr (is_nothrow_move_constructible_v<_Tj>)
620 __variant::__emplace<__j>(*
this, std::move(__rhs_mem));
622 using _Variant = variant<_Types...>;
623 _Variant& __self = __variant_cast<_Types...>(*this);
624 __self.template emplace<__j>(std::move(__rhs_mem));
630 __variant_cast<_Types...>(__rhs));
634 _Move_assign_base(
const _Move_assign_base&) =
default;
635 _Move_assign_base(_Move_assign_base&&) =
default;
636 _Move_assign_base& operator=(
const _Move_assign_base&) =
default;
639 template <
typename... _Types>
640 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...> {
641 using _Base = _Copy_assign_alias<_Types...>;
645 template <
typename... _Types>
646 using _Move_assign_alias =
647 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
649 template <
typename... _Types>
650 struct _Variant_base : _Move_assign_alias<_Types...> {
651 using _Base = _Move_assign_alias<_Types...>;
653 constexpr _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
654 : _Variant_base(in_place_index<0>) {}
656 template <
size_t _Np,
typename... _Args>
657 constexpr explicit _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
658 : _Base(__i, std::forward<_Args>(__args)...) {}
660 _Variant_base(
const _Variant_base&) =
default;
661 _Variant_base(_Variant_base&&) =
default;
662 _Variant_base& operator=(
const _Variant_base&) =
default;
663 _Variant_base& operator=(_Variant_base&&) =
default;
666 template <
typename _Tp,
typename... _Types>
667 inline constexpr bool __exactly_once =
668 std::__find_uniq_type_in_pack<_Tp, _Types...>() <
sizeof...(_Types);
671 template <
typename _Ti>
677 template <
size_t _Ind,
typename _Tp,
typename _Ti,
typename =
void>
681 void _S_fun() =
delete;
685 template <
size_t _Ind,
typename _Tp,
typename _Ti>
686 struct _Build_FUN<_Ind, _Tp, _Ti, void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>> {
688 static integral_constant<size_t, _Ind> _S_fun(_Ti);
691 template <
typename _Tp,
typename _Variant,
692 typename = make_index_sequence<variant_size_v<_Variant>>>
695 template <
typename _Tp,
typename... _Ti,
size_t... _Ind>
696 struct _Build_FUNs<_Tp, variant<_Ti...>, index_sequence<_Ind...>>
697 : _Build_FUN<_Ind, _Tp, _Ti>... {
698 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
703 template <
typename _Tp,
typename _Variant>
704 using _FUN_type =
decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>()));
707 template <
typename _Tp,
typename _Variant,
typename =
void>
708 inline constexpr size_t __accepted_index = variant_npos;
710 template <
typename _Tp,
typename _Variant>
711 inline constexpr size_t
712 __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>> =
713 _FUN_type<_Tp, _Variant>::value;
715 template <
typename _Maybe_variant_cookie,
typename _Variant,
716 typename = __remove_cvref_t<_Variant>>
717 inline constexpr bool __extra_visit_slot_needed =
false;
719 template <
typename _Var,
typename... _Types>
720 inline constexpr bool
721 __extra_visit_slot_needed<__variant_cookie, _Var, variant<_Types...>> =
722 !__variant::__never_valueless<_Types...>();
724 template <
typename _Var,
typename... _Types>
725 inline constexpr bool
726 __extra_visit_slot_needed<__variant_idx_cookie, _Var, variant<_Types...>> =
727 !__variant::__never_valueless<_Types...>();
730 template <
typename _Tp,
size_t... _Dimensions>
734 template <
typename _Tp>
735 struct _Multi_array<_Tp> {
737 struct __untag_result : false_type {
738 using element_type = _Tp;
741#pragma GCC diagnostic push
742#pragma GCC diagnostic ignored "-Wignored-qualifiers"
743 template <
typename... _Args>
744 struct __untag_result<const void (*)(_Args...)> : false_type {
745 using element_type = void (*)(_Args...);
747#pragma GCC diagnostic pop
749 template <
typename... _Args>
750 struct __untag_result<__variant_cookie (*)(_Args...)> : false_type {
751 using element_type = void (*)(_Args...);
754 template <
typename... _Args>
755 struct __untag_result<__variant_idx_cookie (*)(_Args...)> : false_type {
756 using element_type = void (*)(_Args...);
759 template <
typename _Res,
typename... _Args>
760 struct __untag_result<__deduce_visit_result<_Res> (*)(_Args...)> : true_type {
761 using element_type = _Res (*)(_Args...);
764 using __result_is_deduced = __untag_result<_Tp>;
766 constexpr const typename __untag_result<_Tp>::element_type& _M_access()
const {
770 typename __untag_result<_Tp>::element_type _M_data;
774 template <
typename _Ret,
typename _Visitor,
typename... _Variants,
size_t __first,
776 struct _Multi_array<_Ret (*)(_Visitor, _Variants...), __first, __rest...> {
777 static constexpr size_t __index =
sizeof...(_Variants) -
sizeof...(__rest) - 1;
779 using _Variant =
typename _Nth_type<__index, _Variants...>::type;
781 static constexpr int __do_cookie =
782 __extra_visit_slot_needed<_Ret, _Variant> ? 1 : 0;
784 using _Tp = _Ret (*)(_Visitor, _Variants...);
786 template <
typename... _Args>
787 constexpr decltype(
auto) _M_access(
size_t __first_index,
788 _Args... __rest_indices)
const {
789 return _M_arr[__first_index + __do_cookie]._M_access(__rest_indices...);
792 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
822 template <
typename _Array_type,
typename _Index_seq>
823 struct __gen_vtable_impl;
832 template <
typename _Result_type,
typename _Visitor,
size_t... __dimensions,
833 typename... _Variants,
size_t... __indices>
834 struct __gen_vtable_impl<
835 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
836 std::index_sequence<__indices...>> {
837 using _Next = remove_reference_t<
838 typename _Nth_type<
sizeof...(__indices), _Variants...>::type>;
840 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>;
842 static constexpr _Array_type _S_apply() {
843 _Array_type __vtable{};
844 _S_apply_all_alts(__vtable, make_index_sequence<variant_size_v<_Next>>());
848 template <
size_t... __var_indices>
849 static constexpr void _S_apply_all_alts(_Array_type& __vtable,
850 std::index_sequence<__var_indices...>) {
851 if constexpr (__extra_visit_slot_needed<_Result_type, _Next>)
852 (_S_apply_single_alt<true, __var_indices>(
853 __vtable._M_arr[__var_indices + 1], &(__vtable._M_arr[0])),
856 (_S_apply_single_alt<false, __var_indices>(__vtable._M_arr[__var_indices]),
860 template <
bool __do_cookie,
size_t __index,
typename _Tp>
861 static constexpr void _S_apply_single_alt(_Tp& __element,
862 _Tp* __cookie_element =
nullptr) {
863 if constexpr (__do_cookie) {
864 __element = __gen_vtable_impl<
865 _Tp, std::index_sequence<__indices..., __index>>::_S_apply();
866 *__cookie_element = __gen_vtable_impl<
867 _Tp, std::index_sequence<__indices..., variant_npos>>::_S_apply();
869 auto __tmp_element = __gen_vtable_impl<
870 remove_reference_t<
decltype(__element)>,
871 std::index_sequence<__indices..., __index>>::_S_apply();
872 static_assert(is_same_v<_Tp,
decltype(__tmp_element)>,
873 "std::visit requires the visitor to have the same "
874 "return type for all alternatives of a variant");
875 __element = __tmp_element;
883 template <
typename _Result_type,
typename _Visitor,
typename... _Variants,
885 struct __gen_vtable_impl<_Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
886 std::index_sequence<__indices...>> {
887 using _Array_type = _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
889 template <
size_t __index,
typename _Variant>
890 static constexpr decltype(
auto) __element_by_index_or_cookie(
891 _Variant&& __var)
noexcept {
892 if constexpr (__index != variant_npos)
893 return __variant::__get<__index>(std::forward<_Variant>(__var));
895 return __variant_cookie{};
898 static constexpr decltype(
auto) __visit_invoke(_Visitor&& __visitor,
899 _Variants... __vars) {
900 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
903 std::__invoke(std::forward<_Visitor>(__visitor),
904 __element_by_index_or_cookie<__indices>(
905 std::forward<_Variants>(__vars))...,
906 integral_constant<size_t, __indices>()...);
907 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
909 std::__invoke(std::forward<_Visitor>(__visitor),
910 __element_by_index_or_cookie<__indices>(
911 std::forward<_Variants>(__vars))...);
912 else if constexpr (_Array_type::__result_is_deduced::value)
914 return std::__invoke(std::forward<_Visitor>(__visitor),
915 __element_by_index_or_cookie<__indices>(
916 std::forward<_Variants>(__vars))...);
918 return std::__invoke_r<_Result_type>(
919 std::forward<_Visitor>(__visitor),
920 __variant::__get<__indices>(std::forward<_Variants>(__vars))...);
923 static constexpr auto _S_apply() {
924 if constexpr (_Array_type::__result_is_deduced::value) {
925 constexpr bool __visit_ret_type_mismatch =
926 !is_same_v<
typename _Result_type::type,
927 decltype(__visit_invoke(std::declval<_Visitor>(),
928 std::declval<_Variants>()...))>;
929 if constexpr (__visit_ret_type_mismatch) {
930 struct __cannot_match {};
931 return __cannot_match{};
933 return _Array_type{&__visit_invoke};
935 return _Array_type{&__visit_invoke};
939 template <
typename _Result_type,
typename _Visitor,
typename... _Variants>
940 struct __gen_vtable {
941 using _Array_type = _Multi_array<_Result_type (*)(_Visitor, _Variants...),
942 variant_size_v<remove_reference_t<_Variants>>...>;
944 static constexpr _Array_type _S_vtable =
945 __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
948 template <
size_t _Np,
typename _Tp>
949 struct _Base_dedup :
public _Tp {};
951 template <
typename _Variant,
typename __indices>
952 struct _Variant_hash_base;
954 template <
typename... _Types,
size_t... __indices>
955 struct _Variant_hash_base<variant<_Types...>, std::index_sequence<__indices...>>
956 : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... {};
959 template <
size_t _Np,
typename _Variant,
960 typename _AsV =
decltype(__variant::__as(std::declval<_Variant>())),
961 typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>>
962 using __get_t = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
965 template <
typename _Visitor,
typename... _Variants>
966 using __visit_result_t = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
968 template <
typename _Tp,
typename... _Types>
969 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
971 template <
typename _Visitor,
typename _Variant,
size_t... _Idxs>
972 constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>) {
973 return __same_types<invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...>;
979 template <
typename _Tp,
typename... _Types>
980 constexpr bool holds_alternative(
const variant<_Types...>& __v)
noexcept {
981 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
982 "T must occur exactly once in alternatives");
983 return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>();
986 template <
typename _Tp,
typename... _Types>
987 constexpr _Tp&
get(variant<_Types...>& __v) {
988 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
989 "T must occur exactly once in alternatives");
990 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
991 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
995 template <
typename _Tp,
typename... _Types>
996 constexpr _Tp&&
get(variant<_Types...>&& __v) {
997 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
998 "T must occur exactly once in alternatives");
999 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1000 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1004 template <
typename _Tp,
typename... _Types>
1005 constexpr const _Tp&
get(
const variant<_Types...>& __v) {
1006 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1007 "T must occur exactly once in alternatives");
1008 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1009 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1013 template <
typename _Tp,
typename... _Types>
1014 constexpr const _Tp&&
get(
const variant<_Types...>&& __v) {
1015 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1016 "T must occur exactly once in alternatives");
1017 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1018 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1022 template <
size_t _Np,
typename... _Types>
1023 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>> get_if(
1024 variant<_Types...>* __ptr)
noexcept {
1025 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1026 static_assert(_Np <
sizeof...(_Types),
"The index must be in [0, number of alternatives)");
1027 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1028 if (__ptr && __ptr->index() == _Np)
1029 return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
1033 template <
size_t _Np,
typename... _Types>
1034 constexpr add_pointer_t<
const variant_alternative_t<_Np, variant<_Types...>>> get_if(
1035 const variant<_Types...>* __ptr)
noexcept {
1036 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1037 static_assert(_Np <
sizeof...(_Types),
"The index must be in [0, number of alternatives)");
1038 static_assert(!is_void_v<_Alternative_type>,
"_Tp must not be void");
1039 if (__ptr && __ptr->index() == _Np)
1040 return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
1044 template <
typename _Tp,
typename... _Types>
1045 constexpr add_pointer_t<_Tp> get_if(variant<_Types...>* __ptr)
noexcept {
1046 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1047 "T must occur exactly once in alternatives");
1048 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1049 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1050 return std::get_if<__n>(__ptr);
1053 template <
typename _Tp,
typename... _Types>
1054 constexpr add_pointer_t<const _Tp> get_if(
const variant<_Types...>* __ptr)
noexcept {
1055 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1056 "T must occur exactly once in alternatives");
1057 static_assert(!is_void_v<_Tp>,
"_Tp must not be void");
1058 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1059 return std::get_if<__n>(__ptr);
1062 struct monostate {};
1064#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1065 template <typename... _Types> \
1066 constexpr bool operator __OP(const variant<_Types...>& __lhs, \
1067 const variant<_Types...>& __rhs) { \
1068 bool __ret = true; \
1069 __detail::__variant::__raw_idx_visit( \
1070 [&__ret, &__lhs](auto&& __rhs_mem, auto __rhs_index) mutable { \
1071 if constexpr (__rhs_index != variant_npos) { \
1072 if (__lhs.index() == __rhs_index) { \
1073 auto& __this_mem = std::get<__rhs_index>(__lhs); \
1074 __ret = __this_mem __OP __rhs_mem; \
1076 __ret = (__lhs.index() + 1) __OP(__rhs_index + 1); \
1078 __ret = (__lhs.index() + 1) __OP(__rhs_index + 1); \
1084 _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1085 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1086 _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1087 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1088 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1089 _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1091#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1093 constexpr bool operator==(monostate, monostate)
noexcept {
1097#ifdef __cpp_lib_three_way_comparison
1098 template <
typename... _Types>
1099 requires(three_way_comparable<_Types> && ...)
1100 constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...> operator<=>(
1101 const variant<_Types...>& __v, const variant<_Types...>& __w) {
1102 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret =
1103 strong_ordering::equal;
1105 __detail::__variant::__raw_idx_visit(
1106 [&__ret, &__v](
auto&& __w_mem,
auto __w_index)
mutable {
1107 if constexpr (__w_index != variant_npos) {
1108 if (__v.index() == __w_index) {
1110 __ret = __this_mem <=> __w_mem;
1114 __ret = (__v.index() + 1) <=> (__w_index + 1);
1120 constexpr strong_ordering operator<=>(monostate, monostate)
noexcept {
1121 return strong_ordering::equal;
1124 constexpr bool operator!=(monostate, monostate)
noexcept {
1127 constexpr bool operator<(monostate, monostate)
noexcept {
1130 constexpr bool operator>(monostate, monostate)
noexcept {
1133 constexpr bool operator<=(monostate, monostate)
noexcept {
1136 constexpr bool operator>=(monostate, monostate)
noexcept {
1141 template <
typename _Visitor,
typename... _Variants>
1142 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> visit(_Visitor&&,
1145 template <
typename... _Types>
1146 _GLIBCXX20_CONSTEXPR
inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1147 && (is_swappable_v<_Types> && ...)>
1148 swap(variant<_Types...>& __lhs,
1149 variant<_Types...>& __rhs)
noexcept(
noexcept(__lhs.swap(__rhs))) {
1153 template <
typename... _Types>
1154 enable_if_t<!((is_move_constructible_v<_Types> && ...) && (is_swappable_v<_Types> && ...))>
1155 swap(variant<_Types...>&, variant<_Types...>&) =
delete;
1157 class bad_variant_access :
public exception {
1159 bad_variant_access() noexcept {}
1161 const char* what() const noexcept
override {
return _M_reason; }
1164 bad_variant_access(
const char* __reason) noexcept
1165 : _M_reason(__reason) {}
1168 const char* _M_reason =
"bad variant access";
1170 friend void __throw_bad_variant_access(
const char* __what);
1174 inline void __throw_bad_variant_access(
const char* __what) {
1175 _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what));
1178 inline void __throw_bad_variant_access(
bool __valueless) {
1179 if (__valueless) [[__unlikely__]]
1180 __throw_bad_variant_access(
"std::get: variant is valueless");
1182 __throw_bad_variant_access(
"std::get: wrong index for variant");
1185 template <
typename... _Types>
1187 :
private __detail::__variant::_Variant_base<_Types...>,
1188 private _Enable_default_constructor<
1189 __detail::__variant::_Traits<_Types...>::_S_default_ctor, variant<_Types...>>,
1190 private _Enable_copy_move<__detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1191 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1192 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1193 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1194 variant<_Types...>> {
1196 template <
typename... _UTypes,
typename _Tp>
1197 friend _GLIBCXX20_CONSTEXPR
decltype(
auto) __variant_cast(_Tp&&);
1199 static_assert(
sizeof...(_Types) > 0,
"variant must have at least one alternative");
1200 static_assert(!(std::is_reference_v<_Types> || ...),
1201 "variant must have no reference alternative");
1202 static_assert(!(std::is_void_v<_Types> || ...),
"variant must have no void alternative");
1204 using _Base = __detail::__variant::_Variant_base<_Types...>;
1205 using _Default_ctor_enabler =
1206 _Enable_default_constructor<__detail::__variant::_Traits<_Types...>::_S_default_ctor,
1207 variant<_Types...>>;
1209 template <
typename _Tp>
1210 static constexpr bool __not_self = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1212 template <
typename _Tp>
1213 static constexpr bool __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1215 template <
typename _Tp>
1216 static constexpr size_t __accepted_index =
1217 __detail::__variant::__accepted_index<_Tp, variant>;
1219 template <
size_t _Np,
typename = enable_if_t<(_Np <
sizeof...(_Types))>>
1220 using __to_type =
typename _Nth_type<_Np, _Types...>::type;
1222 template <
typename _Tp,
typename = enable_if_t<__not_self<_Tp>>>
1223 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1225 template <
typename _Tp>
1226 static constexpr size_t __index_of = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1228 using _Traits = __detail::__variant::_Traits<_Types...>;
1230 template <
typename _Tp>
1231 struct __is_in_place_tag : false_type {};
1232 template <
typename _Tp>
1233 struct __is_in_place_tag<in_place_type_t<_Tp>> : true_type {};
1234 template <
size_t _Np>
1235 struct __is_in_place_tag<in_place_index_t<_Np>> : true_type {};
1237 template <
typename _Tp>
1238 static constexpr bool __not_in_place_tag = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value;
1241 variant() =
default;
1242 variant(
const variant& __rhs) =
default;
1243 variant(variant&&) =
default;
1244 variant& operator=(
const variant&) =
default;
1245 variant& operator=(variant&&) =
default;
1246 _GLIBCXX20_CONSTEXPR ~variant() =
default;
1248 template <
typename _Tp,
typename = enable_if_t<
sizeof...(_Types) != 0>,
1249 typename = enable_if_t<__not_in_place_tag<_Tp>>,
1250 typename _Tj = __accepted_type<_Tp&&>,
1251 typename = enable_if_t<__exactly_once<_Tj> && is_constructible_v<_Tj, _Tp>>>
1252 constexpr variant(_Tp&& __t)
noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1253 : variant(in_place_index<__accepted_index<_Tp>>, std::forward<_Tp>(__t)) {}
1255 template <
typename _Tp,
typename... _Args,
1256 typename = enable_if_t<__exactly_once<_Tp> && is_constructible_v<_Tp, _Args...>>>
1257 constexpr explicit variant(in_place_type_t<_Tp>, _Args&&... __args)
1258 : variant(in_place_index<__index_of<_Tp>>, std::forward<_Args>(__args)...) {}
1261 typename _Tp,
typename _Up,
typename... _Args,
1262 typename = enable_if_t<__exactly_once<_Tp>
1263 && is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>>>
1264 constexpr explicit variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1266 : variant(in_place_index<__index_of<_Tp>>, __il, std::forward<_Args>(__args)...) {}
1268 template <
size_t _Np,
typename... _Args,
typename _Tp = __to_type<_Np>,
1269 typename = enable_if_t<is_constructible_v<_Tp, _Args...>>>
1270 constexpr explicit variant(in_place_index_t<_Np>, _Args&&... __args)
1271 : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...)
1272 , _Default_ctor_enabler(_Enable_default_constructor_tag{}) {}
1274 template <
size_t _Np,
typename _Up,
typename... _Args,
typename _Tp = __to_type<_Np>,
1275 typename = enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>>>
1276 constexpr explicit variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1278 : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...)
1279 , _Default_ctor_enabler(_Enable_default_constructor_tag{}) {}
1281 template <
typename _Tp>
1282 _GLIBCXX20_CONSTEXPR enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1283 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1284 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1286 operator=(_Tp&& __rhs)
noexcept(
1287 is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>&&
1288 is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>) {
1289 constexpr auto __index = __accepted_index<_Tp>;
1290 if (index() == __index)
1293 using _Tj = __accepted_type<_Tp&&>;
1294 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1295 || !is_nothrow_move_constructible_v<_Tj>)
1296 this->emplace<__index>(std::forward<_Tp>(__rhs));
1300 this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs)));
1305 template <
typename _Tp,
typename... _Args>
1306 _GLIBCXX20_CONSTEXPR
1307 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>, _Tp&>
1308 emplace(_Args&&... __args) {
1309 constexpr size_t __index = __index_of<_Tp>;
1310 return this->emplace<__index>(std::forward<_Args>(__args)...);
1313 template <
typename _Tp,
typename _Up,
typename... _Args>
1314 _GLIBCXX20_CONSTEXPR enable_if_t<
1315 is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> && __exactly_once<_Tp>, _Tp&>
1316 emplace(initializer_list<_Up> __il, _Args&&... __args) {
1317 constexpr size_t __index = __index_of<_Tp>;
1318 return this->emplace<__index>(__il, std::forward<_Args>(__args)...);
1321 template <
size_t _Np,
typename... _Args>
1322 _GLIBCXX20_CONSTEXPR
1323 enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>, __to_type<_Np>&>
1324 emplace(_Args&&... __args) {
1325 namespace __variant = std::__detail::__variant;
1326 using type =
typename _Nth_type<_Np, _Types...>::type;
1329 if constexpr (is_nothrow_constructible_v<type, _Args...>) {
1330 __variant::__emplace<_Np>(*
this, std::forward<_Args>(__args)...);
1331 }
else if constexpr (is_scalar_v<type>) {
1333 const type __tmp(std::forward<_Args>(__args)...);
1335 __variant::__emplace<_Np>(*
this, __tmp);
1336 }
else if constexpr (__variant::_Never_valueless_alt<type>()
1337 && _Traits::_S_move_assign) {
1339 variant __tmp(in_place_index<_Np>, std::forward<_Args>(__args)...);
1341 *
this = std::move(__tmp);
1345 __variant::__emplace<_Np>(*
this, std::forward<_Args>(__args)...);
1350 template <
size_t _Np,
typename _Up,
typename... _Args>
1351 _GLIBCXX20_CONSTEXPR enable_if_t<
1352 is_constructible_v<__to_type<_Np>, initializer_list<_Up>&, _Args...>, __to_type<_Np>&>
1353 emplace(initializer_list<_Up> __il, _Args&&... __args) {
1354 namespace __variant = std::__detail::__variant;
1355 using type =
typename _Nth_type<_Np, _Types...>::type;
1358 if constexpr (is_nothrow_constructible_v<type, initializer_list<_Up>&, _Args...>) {
1359 __variant::__emplace<_Np>(*
this, __il, std::forward<_Args>(__args)...);
1360 }
else if constexpr (__variant::_Never_valueless_alt<type>()
1361 && _Traits::_S_move_assign) {
1363 variant __tmp(in_place_index<_Np>, __il, std::forward<_Args>(__args)...);
1365 *
this = std::move(__tmp);
1369 __variant::__emplace<_Np>(*
this, __il, std::forward<_Args>(__args)...);
1374 template <
size_t _Np,
typename... _Args>
1375 enable_if_t<!(_Np <
sizeof...(_Types))> emplace(_Args&&...) =
delete;
1377 template <
typename _Tp,
typename... _Args>
1378 enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) =
delete;
1380 constexpr bool valueless_by_exception() const noexcept {
return !this->_M_valid(); }
1382 constexpr size_t index() const noexcept {
1383 using __index_type =
typename _Base::__index_type;
1384 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1385 return this->_M_index;
1386 else if constexpr (
sizeof...(_Types) <= __index_type(-1) / 2)
1387 return make_signed_t<__index_type>(this->_M_index);
1389 return size_t(__index_type(this->_M_index + 1)) - 1;
1392 _GLIBCXX20_CONSTEXPR
1393 void swap(variant& __rhs)
noexcept((__is_nothrow_swappable<_Types>::value && ...)
1394 && is_nothrow_move_constructible_v<variant>) {
1395 static_assert((is_move_constructible_v<_Types> && ...));
1398 if (__rhs.valueless_by_exception()) [[__unlikely__]] {
1399 if (!this->valueless_by_exception()) [[__likely__]]
1404 namespace __variant = __detail::__variant;
1406 __variant::__raw_idx_visit(
1407 [
this, &__rhs](
auto&& __rhs_mem,
auto __rhs_index)
mutable {
1408 constexpr size_t __j = __rhs_index;
1409 if constexpr (__j != variant_npos) {
1410 if (this->index() == __j) {
1414 auto __tmp(std::move(__rhs_mem));
1416 if constexpr (_Traits::_S_trivial_move_assign)
1417 __rhs = std::move(*
this);
1419 __variant::__raw_idx_visit(
1420 [&__rhs](
auto&& __this_mem,
auto __this_index)
mutable {
1421 constexpr size_t __k = __this_index;
1422 if constexpr (__k != variant_npos)
1423 __variant::__emplace<__k>(__rhs, std::move(__this_mem));
1427 __variant::__emplace<__j>(*
this, std::move(__tmp));
1434#if defined(__clang__) && __clang_major__ <= 7
1440 template <
size_t _Np,
typename _Vp>
1441 friend constexpr decltype(
auto) __detail::__variant::__get(_Vp&& __v)
noexcept;
1443#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1444 template <typename... _Tp> \
1445 friend constexpr bool operator __OP(const variant<_Tp...>& __lhs, \
1446 const variant<_Tp...>& __rhs);
1448 _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1449 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1450 _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1451 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1452 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1453 _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1455#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1458 template <
size_t _Np,
typename... _Types>
1459 constexpr variant_alternative_t<_Np, variant<_Types...>>&
get(variant<_Types...>& __v) {
1460 static_assert(_Np <
sizeof...(_Types),
"The index must be in [0, number of alternatives)");
1461 if (__v.index() != _Np)
1462 __throw_bad_variant_access(__v.valueless_by_exception());
1463 return __detail::__variant::__get<_Np>(__v);
1466 template <
size_t _Np,
typename... _Types>
1467 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
get(variant<_Types...>&& __v) {
1468 static_assert(_Np <
sizeof...(_Types),
"The index must be in [0, number of alternatives)");
1469 if (__v.index() != _Np)
1470 __throw_bad_variant_access(__v.valueless_by_exception());
1471 return __detail::__variant::__get<_Np>(std::move(__v));
1474 template <
size_t _Np,
typename... _Types>
1475 constexpr const variant_alternative_t<_Np, variant<_Types...>>&
get(
1476 const variant<_Types...>& __v) {
1477 static_assert(_Np <
sizeof...(_Types),
"The index must be in [0, number of alternatives)");
1478 if (__v.index() != _Np)
1479 __throw_bad_variant_access(__v.valueless_by_exception());
1480 return __detail::__variant::__get<_Np>(__v);
1483 template <
size_t _Np,
typename... _Types>
1484 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
get(
1485 const variant<_Types...>&& __v) {
1486 static_assert(_Np <
sizeof...(_Types),
"The index must be in [0, number of alternatives)");
1487 if (__v.index() != _Np)
1488 __throw_bad_variant_access(__v.valueless_by_exception());
1489 return __detail::__variant::__get<_Np>(std::move(__v));
1493 template <
typename _Result_type,
typename _Visitor,
typename... _Variants>
1494 constexpr decltype(
auto) __do_visit(_Visitor&& __visitor, _Variants&&... __variants) {
1496 if constexpr (
sizeof...(_Variants) == 0) {
1497 if constexpr (is_void_v<_Result_type>)
1498 return (
void)std::forward<_Visitor>(__visitor)();
1500 return std::forward<_Visitor>(__visitor)();
1502 constexpr size_t __max = 11;
1505 using _V0 =
typename _Nth_type<0, _Variants...>::type;
1507 constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
1509 if constexpr (
sizeof...(_Variants) > 1 || __n > __max) {
1511 constexpr auto& __vtable =
1512 __detail::__variant::__gen_vtable<_Result_type, _Visitor&&,
1513 _Variants&&...>::_S_vtable;
1515 auto __func_ptr = __vtable._M_access(__variants.index()...);
1516 return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1517 std::forward<_Variants>(__variants)...);
1521 _V0& __v0 = [](_V0& __v, ...) -> _V0& {
1525 using __detail::__variant::__gen_vtable_impl;
1526 using __detail::__variant::_Multi_array;
1527 using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0 &&)>;
1529#ifdef _GLIBCXX_DEBUG
1530#define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap
1532#define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable
1535#define _GLIBCXX_VISIT_CASE(N) \
1537 if constexpr (N < __n) { \
1538 return __gen_vtable_impl<_Ma, index_sequence<N>>::__visit_invoke( \
1539 std::forward<_Visitor>(__visitor), std::forward<_V0>(__v0)); \
1541 _GLIBCXX_VISIT_UNREACHABLE(); \
1544 switch (__v0.index()) {
1545 _GLIBCXX_VISIT_CASE(0)
1546 _GLIBCXX_VISIT_CASE(1)
1547 _GLIBCXX_VISIT_CASE(2)
1548 _GLIBCXX_VISIT_CASE(3)
1549 _GLIBCXX_VISIT_CASE(4)
1550 _GLIBCXX_VISIT_CASE(5)
1551 _GLIBCXX_VISIT_CASE(6)
1552 _GLIBCXX_VISIT_CASE(7)
1553 _GLIBCXX_VISIT_CASE(8)
1554 _GLIBCXX_VISIT_CASE(9)
1555 _GLIBCXX_VISIT_CASE(10)
1557 using __detail::__variant::__variant_cookie;
1558 using __detail::__variant::__variant_idx_cookie;
1559 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
1560 || is_same_v<_Result_type, __variant_cookie>) {
1561 using _Npos = index_sequence<variant_npos>;
1562 return __gen_vtable_impl<_Ma, _Npos>::__visit_invoke(
1563 std::forward<_Visitor>(__visitor), std::forward<_V0>(__v0));
1565 _GLIBCXX_VISIT_UNREACHABLE();
1567 _GLIBCXX_VISIT_UNREACHABLE();
1569#undef _GLIBCXX_VISIT_CASE
1570#undef _GLIBCXX_VISIT_UNREACHABLE
1576 template <
typename _Visitor,
typename... _Variants>
1577 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> visit(
1578 _Visitor&& __visitor, _Variants&&... __variants) {
1579 namespace __variant = std::__detail::__variant;
1581 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1582 __throw_bad_variant_access(
"std::visit: variant is valueless");
1584 using _Result_type = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1586 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1588 if constexpr (
sizeof...(_Variants) == 1) {
1589 using _Vp =
decltype(__variant::__as(std::declval<_Variants>()...));
1591 constexpr bool __visit_rettypes_match =
1592 __detail::__variant::__check_visitor_results<_Visitor, _Vp>(
1593 make_index_sequence<variant_size_v<remove_reference_t<_Vp>>>());
1594 if constexpr (!__visit_rettypes_match) {
1595 static_assert(__visit_rettypes_match,
1596 "std::visit requires the visitor to have the same "
1597 "return type for all alternatives of a variant");
1600 return std::__do_visit<_Tag>(std::forward<_Visitor>(__visitor),
1601 static_cast<_Vp
>(__variants)...);
1603 return std::__do_visit<_Tag>(std::forward<_Visitor>(__visitor),
1604 __variant::__as(std::forward<_Variants>(__variants))...);
1607#if __cplusplus > 201703L
1608 template <
typename _Res,
typename _Visitor,
typename... _Variants>
1609 constexpr _Res visit(_Visitor&& __visitor, _Variants&&... __variants) {
1610 namespace __variant = std::__detail::__variant;
1612 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1613 __throw_bad_variant_access(
"std::visit<R>: variant is valueless");
1615 return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor),
1616 __variant::__as(std::forward<_Variants>(__variants))...);
1621 template <bool,
typename... _Types>
1622 struct __variant_hash_call_base_impl {
1623 size_t operator()(
const variant<_Types...>& __t)
const
1624 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...)) {
1626 __detail::__variant::__raw_visit(
1627 [&__t, &__ret](
auto&& __t_mem)
mutable {
1628 using _Type = __remove_cvref_t<
decltype(__t_mem)>;
1629 if constexpr (!is_same_v<_Type, __detail::__variant::__variant_cookie>)
1630 __ret = std::hash<size_t>{}(__t.index()) + std::hash<_Type>{}(__t_mem);
1632 __ret = std::hash<size_t>{}(__t.index());
1639 template <
typename... _Types>
1640 struct __variant_hash_call_base_impl<false, _Types...> {};
1642 template <
typename... _Types>
1643 using __variant_hash_call_base = __variant_hash_call_base_impl<
1644 (__poison_hash<remove_const_t<_Types>>::__enable_hash_call && ...), _Types...>;
1647 template <
typename... _Types>
1648 struct hash<variant<_Types...>>
1649 :
private __detail::__variant::_Variant_hash_base<variant<_Types...>,
1650 std::index_sequence_for<_Types...>>,
1651 public __variant_hash_call_base<_Types...> {
1652 using result_type [[__deprecated__]] = size_t;
1653 using argument_type [[__deprecated__]] = variant<_Types...>;
1657 struct hash<monostate> {
1658 using result_type [[__deprecated__]] = size_t;
1659 using argument_type [[__deprecated__]] = monostate;
1661 size_t operator()(
const monostate&)
const noexcept {
1662 constexpr size_t __magic_monostate_hash = -7777;
1663 return __magic_monostate_hash;
1667 template <
typename... _Types>
1668 struct __is_fast_hash<hash<variant<_Types...>>>
1669 : bool_constant<(__is_fast_hash<_Types>::value && ...)> {};
1671 _GLIBCXX_END_NAMESPACE_VERSION
KOKKOS_INLINE_FUNCTION auto & get(::ippl::Tuple< Ts... > &t)
bool operator!=(const NDIndex< Dim > &nd1, const NDIndex< Dim > &nd2)
bool operator==(const NDIndex< Dim > &nd1, const NDIndex< Dim > &nd2)