1// <variant> -*- C++ -*-
3// Copyright (C) 2016-2025 Free Software Foundation, Inc.
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
26 * This is the `<variant>` C++ Library header.
29#ifndef _GLIBCXX_VARIANT
30#define _GLIBCXX_VARIANT 1
33#pragma GCC system_header
36#define __glibcxx_want_freestanding_variant
37#define __glibcxx_want_variant
38#define __glibcxx_want_constrained_equality
39#include <bits/version.h>
41#ifdef __cpp_lib_variant // C++ >= 17
42#include <initializer_list>
44#include <bits/enable_special_members.h>
45#include <bits/exception_defines.h>
46#include <bits/functional_hash.h>
47#include <bits/invoke.h>
48#include <bits/monostate.h>
49#include <bits/parse_numbers.h> // _Select_int
50#include <bits/stl_iterator_base_funcs.h>
51#include <bits/stl_construct.h>
52#include <bits/utility.h> // in_place_index_t
53#if __cplusplus >= 202002L
58// C++ < 20 || __cpp_concepts < 202002L || __cpp_constexpr < 201811L
59#if __cpp_lib_variant < 202106L
60# include <ext/aligned_buffer.h> // Use __aligned_membuf for storage.
63namespace std _GLIBCXX_VISIBILITY(default)
65_GLIBCXX_BEGIN_NAMESPACE_VERSION
67 template<typename... _Types> class tuple;
68 template<typename... _Types> class variant;
70 template<typename _Variant>
73 template<typename _Variant>
74 struct variant_size<const _Variant> : variant_size<_Variant> {};
76 template<typename _Variant>
77 struct variant_size<volatile _Variant> : variant_size<_Variant> {};
79 template<typename _Variant>
80 struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
82 template<typename... _Types>
83 struct variant_size<variant<_Types...>>
84 : std::integral_constant<size_t, sizeof...(_Types)> {};
86 template<typename _Variant>
87 inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
89 template<typename... _Types>
90 inline constexpr size_t
91 variant_size_v<variant<_Types...>> = sizeof...(_Types);
93 template<typename... _Types>
94 inline constexpr size_t
95 variant_size_v<const variant<_Types...>> = sizeof...(_Types);
97 template<size_t _Np, typename _Variant>
98 struct variant_alternative;
100 template<size_t _Np, typename... _Types>
101 struct variant_alternative<_Np, variant<_Types...>>
103 static_assert(_Np < sizeof...(_Types));
105 using type = typename _Nth_type<_Np, _Types...>::type;
108 template<size_t _Np, typename _Variant>
109 using variant_alternative_t =
110 typename variant_alternative<_Np, _Variant>::type;
112 template<size_t _Np, typename _Variant>
113 struct variant_alternative<_Np, const _Variant>
114 { using type = const variant_alternative_t<_Np, _Variant>; };
116 template<size_t _Np, typename _Variant>
117 struct variant_alternative<_Np, volatile _Variant>
118 { using type = volatile variant_alternative_t<_Np, _Variant>; };
120 template<size_t _Np, typename _Variant>
121 struct variant_alternative<_Np, const volatile _Variant>
122 { using type = const volatile variant_alternative_t<_Np, _Variant>; };
124 inline constexpr size_t variant_npos = -1;
126 template<size_t _Np, typename... _Types>
127 constexpr variant_alternative_t<_Np, variant<_Types...>>&
128 get(variant<_Types...>&);
130 template<size_t _Np, typename... _Types>
131 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
132 get(variant<_Types...>&&);
134 template<size_t _Np, typename... _Types>
135 constexpr variant_alternative_t<_Np, variant<_Types...>> const&
136 get(const variant<_Types...>&);
138 template<size_t _Np, typename... _Types>
139 constexpr variant_alternative_t<_Np, variant<_Types...>> const&&
140 get(const variant<_Types...>&&);
142 template<typename _Result_type, typename _Visitor, typename... _Variants>
143 constexpr decltype(auto)
144 __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
146 template <typename... _Types, typename _Tp>
149 __variant_cast(_Tp&& __rhs)
151 if constexpr (is_lvalue_reference_v<_Tp>)
153 if constexpr (is_const_v<remove_reference_t<_Tp>>)
154 return static_cast<const variant<_Types...>&>(__rhs);
156 return static_cast<variant<_Types...>&>(__rhs);
159 return static_cast<variant<_Types...>&&>(__rhs);
166 // used for raw visitation
167 struct __variant_cookie {};
168 // used for raw visitation with indices passed in
169 struct __variant_idx_cookie { using type = __variant_idx_cookie; };
170 // Used to enable deduction (and same-type checking) for std::visit:
171 template<typename _Tp> struct __deduce_visit_result { using type = _Tp; };
173 // Visit variants that might be valueless.
174 template<typename _Visitor, typename... _Variants>
176 __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
178 std::__do_visit<__variant_cookie>(std::forward<_Visitor>(__visitor),
179 std::forward<_Variants>(__variants)...);
182 // Visit variants that might be valueless, passing indices to the visitor.
183 template<typename _Visitor, typename... _Variants>
185 __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
187 std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor),
188 std::forward<_Variants>(__variants)...);
191 // The __as function templates implement the exposition-only "as-variant"
193 template<typename... _Types>
194 constexpr std::variant<_Types...>&
195 __as(std::variant<_Types...>& __v) noexcept
198 template<typename... _Types>
199 constexpr const std::variant<_Types...>&
200 __as(const std::variant<_Types...>& __v) noexcept
203 template<typename... _Types>
204 constexpr std::variant<_Types...>&&
205 __as(std::variant<_Types...>&& __v) noexcept
206 { return std::move(__v); }
208 template<typename... _Types>
209 constexpr const std::variant<_Types...>&&
210 __as(const std::variant<_Types...>&& __v) noexcept
211 { return std::move(__v); }
213#if __cpp_lib_variant < 202106L
214 template<typename _Type, bool = std::is_trivially_destructible_v<_Type>>
215 struct _Uninitialized;
217 template<typename _Type, bool /* unused */ = true>
218 struct _Uninitialized;
221 // The primary template is used for trivially destructible types in C++17,
222 // and for all types in C++20.
223 template<typename _Type, bool>
224 struct _Uninitialized
226 template<typename... _Args>
228 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
229 : _M_storage(std::forward<_Args>(__args)...)
232#if __cpp_lib_variant < 202106L
233 constexpr const _Type& _M_get() const & noexcept
234 { return _M_storage; }
236 constexpr _Type& _M_get() & noexcept
237 { return _M_storage; }
239 constexpr const _Type&& _M_get() const && noexcept
240 { return std::move(_M_storage); }
242 constexpr _Type&& _M_get() && noexcept
243 { return std::move(_M_storage); }
249#if __cpp_lib_variant < 202106L
250 // This partial specialization is used for non-trivially destructible types
251 // in C++17, so that _Uninitialized<T> is trivially destructible and can be
252 // used as a union member in _Variadic_union.
253 template<typename _Type>
254 struct _Uninitialized<_Type, false>
256 template<typename... _Args>
258 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
260 ::new ((void*)std::addressof(_M_storage))
261 _Type(std::forward<_Args>(__args)...);
264 const _Type& _M_get() const & noexcept
265 { return *_M_storage._M_ptr(); }
267 _Type& _M_get() & noexcept
268 { return *_M_storage._M_ptr(); }
270 const _Type&& _M_get() const && noexcept
271 { return std::move(*_M_storage._M_ptr()); }
273 _Type&& _M_get() && noexcept
274 { return std::move(*_M_storage._M_ptr()); }
276 __gnu_cxx::__aligned_membuf<_Type> _M_storage;
279 template<size_t _Np, typename _Union>
280 constexpr decltype(auto)
281 __get_n(_Union&& __u) noexcept
283 if constexpr (_Np == 0)
284 return std::forward<_Union>(__u)._M_first._M_get();
285 else if constexpr (_Np == 1)
286 return std::forward<_Union>(__u)._M_rest._M_first._M_get();
287 else if constexpr (_Np == 2)
288 return std::forward<_Union>(__u)._M_rest._M_rest._M_first._M_get();
290 return __variant::__get_n<_Np - 3>(
291 std::forward<_Union>(__u)._M_rest._M_rest._M_rest);
294 template<size_t _Np, typename _Union>
296 __get_n(_Union&& __u) noexcept
298 if constexpr (_Np == 0)
299 return std::forward<_Union>(__u)._M_first._M_storage;
300 else if constexpr (_Np == 1)
301 return std::forward<_Union>(__u)._M_rest._M_first._M_storage;
302 else if constexpr (_Np == 2)
303 return std::forward<_Union>(__u)._M_rest._M_rest._M_first._M_storage;
305 return __variant::__get_n<_Np - 3>(
306 std::forward<_Union>(__u)._M_rest._M_rest._M_rest);
310 // Returns the typed storage for __v.
311 template<size_t _Np, typename _Variant>
312 constexpr decltype(auto)
313 __get(_Variant&& __v) noexcept
314 { return __variant::__get_n<_Np>(std::forward<_Variant>(__v)._M_u); }
316 // Gets the _Uninitialized to construct into for __u.
317 template<size_t _Np, typename _Union>
318 constexpr decltype(auto)
319 __construct_n(_Union& __u) noexcept
321 if constexpr (_Np == 0)
322 return &__u._M_first;
323 else if constexpr (_Np == 1)
325 std::_Construct(&__u._M_rest);
326 return &__u._M_rest._M_first;
328 else if constexpr (_Np == 2)
330 std::_Construct(&__u._M_rest);
331 std::_Construct(&__u._M_rest._M_rest);
332 return &__u._M_rest._M_rest._M_first;
336 std::_Construct(&__u._M_rest);
337 std::_Construct(&__u._M_rest._M_rest);
338 std::_Construct(&__u._M_rest._M_rest._M_rest);
339 return __variant::__construct_n<_Np - 3>(__u._M_rest._M_rest._M_rest);
343 template<typename... _Types>
346 static constexpr bool _S_default_ctor =
347 is_default_constructible_v<typename _Nth_type<0, _Types...>::type>;
348 static constexpr bool _S_copy_ctor =
349 (is_copy_constructible_v<_Types> && ...);
350 static constexpr bool _S_move_ctor =
351 (is_move_constructible_v<_Types> && ...);
352 static constexpr bool _S_copy_assign =
354 && (is_copy_assignable_v<_Types> && ...);
355 static constexpr bool _S_move_assign =
357 && (is_move_assignable_v<_Types> && ...);
359 static constexpr bool _S_trivial_dtor =
360 (is_trivially_destructible_v<_Types> && ...);
361 static constexpr bool _S_trivial_copy_ctor =
362 (is_trivially_copy_constructible_v<_Types> && ...);
363 static constexpr bool _S_trivial_move_ctor =
364 (is_trivially_move_constructible_v<_Types> && ...);
365 static constexpr bool _S_trivial_copy_assign =
366 _S_trivial_dtor && _S_trivial_copy_ctor
367 && (is_trivially_copy_assignable_v<_Types> && ...);
368 static constexpr bool _S_trivial_move_assign =
369 _S_trivial_dtor && _S_trivial_move_ctor
370 && (is_trivially_move_assignable_v<_Types> && ...);
372 // The following nothrow traits are for non-trivial SMFs. Trivial SMFs
373 // are always nothrow.
374 static constexpr bool _S_nothrow_default_ctor =
375 is_nothrow_default_constructible_v<
376 typename _Nth_type<0, _Types...>::type>;
377 static constexpr bool _S_nothrow_copy_ctor = false;
378 static constexpr bool _S_nothrow_move_ctor =
379 (is_nothrow_move_constructible_v<_Types> && ...);
380 static constexpr bool _S_nothrow_copy_assign = false;
381 static constexpr bool _S_nothrow_move_assign =
383 && (is_nothrow_move_assignable_v<_Types> && ...);
386 // Defines members and ctors.
387 template<bool __trivially_destructible, typename... _Types>
388 union _Variadic_union
390 _Variadic_union() = default;
392 template<size_t _Np, typename... _Args>
393 _Variadic_union(in_place_index_t<_Np>, _Args&&...) = delete;
396 template<bool __trivially_destructible, typename _First, typename... _Rest>
397 union _Variadic_union<__trivially_destructible, _First, _Rest...>
399 constexpr _Variadic_union() : _M_rest() { }
401 template<typename... _Args>
403 _Variadic_union(in_place_index_t<0>, _Args&&... __args)
404 : _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
407 template<size_t _Np, typename... _Args>
409 _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
410 : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
413#if __cpp_lib_variant >= 202106L
414 _Variadic_union(const _Variadic_union&) = default;
415 _Variadic_union(_Variadic_union&&) = default;
416 _Variadic_union& operator=(const _Variadic_union&) = default;
417 _Variadic_union& operator=(_Variadic_union&&) = default;
419 ~_Variadic_union() = default;
421 // If any alternative type is not trivially destructible then we need a
422 // user-provided destructor that does nothing. The active alternative
423 // will be destroyed by _Variant_storage::_M_reset() instead of here.
424 constexpr ~_Variadic_union()
425 requires (!__trivially_destructible)
429 _Uninitialized<_First> _M_first;
430 _Variadic_union<__trivially_destructible, _Rest...> _M_rest;
433 // _Never_valueless_alt is true for variant alternatives that can
434 // always be placed in a variant without it becoming valueless.
436 // For suitably-small, trivially copyable types we can create temporaries
437 // on the stack and then memcpy them into place.
438 template<typename _Tp>
439 struct _Never_valueless_alt
440 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
443 // Specialize _Never_valueless_alt for other types which have a
444 // non-throwing and cheap move construction and move assignment operator,
445 // so that emplacing the type will provide the strong exception-safety
446 // guarantee, by creating and moving a temporary.
447 // Whether _Never_valueless_alt<T> is true or not affects the ABI of a
448 // variant using that alternative, so we can't change the value later!
450 // True if every alternative in _Types... can be emplaced in a variant
451 // without it becoming valueless. If this is true, variant<_Types...>
452 // can never be valueless, which enables some minor optimizations.
453 template <typename... _Types>
454 constexpr bool __never_valueless()
456 return _Traits<_Types...>::_S_move_assign
457 && (_Never_valueless_alt<_Types>::value && ...);
460 // Defines index and the dtor, possibly trivial.
461 template<bool __trivially_destructible, typename... _Types>
462 struct _Variant_storage;
464 template <typename... _Types>
465 using __select_index =
466 typename __select_int::_Select_int_base<sizeof...(_Types),
468 unsigned short>::type::value_type;
470 template<typename... _Types>
471 struct _Variant_storage<false, _Types...>
475 : _M_index(static_cast<__index_type>(variant_npos))
478 template<size_t _Np, typename... _Args>
480 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
481 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
488 if (!_M_valid()) [[__unlikely__]]
491 std::__do_visit<void>([](auto&& __this_mem) mutable
493 std::_Destroy(std::__addressof(__this_mem));
494 }, __variant_cast<_Types...>(*this));
496 _M_index = static_cast<__index_type>(variant_npos);
504 _M_valid() const noexcept
506 if constexpr (__variant::__never_valueless<_Types...>())
508 return this->_M_index != __index_type(variant_npos);
511 _Variadic_union<false, _Types...> _M_u;
512 using __index_type = __select_index<_Types...>;
513 __index_type _M_index;
516 template<typename... _Types>
517 struct _Variant_storage<true, _Types...>
521 : _M_index(static_cast<__index_type>(variant_npos))
524 template<size_t _Np, typename... _Args>
526 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
527 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
533 { _M_index = static_cast<__index_type>(variant_npos); }
536 _M_valid() const noexcept
538 if constexpr (__variant::__never_valueless<_Types...>())
540 // It would be nice if we could just return true for -fno-exceptions.
541 // It's possible (but inadvisable) that a std::variant could become
542 // valueless in a translation unit compiled with -fexceptions and then
543 // be passed to functions compiled with -fno-exceptions. We would need
544 // some #ifdef _GLIBCXX_NO_EXCEPTIONS_GLOBALLY property to elide all
545 // checks for valueless_by_exception().
546 return this->_M_index != static_cast<__index_type>(variant_npos);
549 _Variadic_union<true, _Types...> _M_u;
550 using __index_type = __select_index<_Types...>;
551 __index_type _M_index;
554 // Implementation of v.emplace<N>(args...).
555 template<size_t _Np, bool _Triv, typename... _Types, typename... _Args>
558 __emplace(_Variant_storage<_Triv, _Types...>& __v, _Args&&... __args)
561 auto* __addr = __variant::__construct_n<_Np>(__v._M_u);
562 std::_Construct(__addr, in_place_index<0>,
563 std::forward<_Args>(__args)...);
564 // Construction didn't throw, so can set the new index now:
568 template<typename... _Types>
569 using _Variant_storage_alias =
570 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
572 // The following are (Copy|Move) (ctor|assign) layers for forwarding
573 // triviality and handling non-trivial SMF behaviors.
575 template<bool, typename... _Types>
576 struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
578 using _Base = _Variant_storage_alias<_Types...>;
582 _Copy_ctor_base(const _Copy_ctor_base& __rhs)
583 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
585 __variant::__raw_idx_visit(
586 [this](auto&& __rhs_mem, auto __rhs_index) mutable
588 constexpr size_t __j = __rhs_index;
589 if constexpr (__j != variant_npos)
590 std::_Construct(std::__addressof(this->_M_u),
591 in_place_index<__j>, __rhs_mem);
592 }, __variant_cast<_Types...>(__rhs));
593 this->_M_index = __rhs._M_index;
596 _Copy_ctor_base(_Copy_ctor_base&&) = default;
597 _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default;
598 _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default;
601 template<typename... _Types>
602 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
604 using _Base = _Variant_storage_alias<_Types...>;
608 template<typename... _Types>
609 using _Copy_ctor_alias =
610 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
612 template<bool, typename... _Types>
613 struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
615 using _Base = _Copy_ctor_alias<_Types...>;
619 _Move_ctor_base(_Move_ctor_base&& __rhs)
620 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
622 __variant::__raw_idx_visit(
623 [this](auto&& __rhs_mem, auto __rhs_index) mutable
625 constexpr size_t __j = __rhs_index;
626 if constexpr (__j != variant_npos)
627 std::_Construct(std::__addressof(this->_M_u),
629 std::forward<decltype(__rhs_mem)>(__rhs_mem));
630 }, __variant_cast<_Types...>(std::move(__rhs)));
631 this->_M_index = __rhs._M_index;
634 _Move_ctor_base(const _Move_ctor_base&) = default;
635 _Move_ctor_base& operator=(const _Move_ctor_base&) = default;
636 _Move_ctor_base& operator=(_Move_ctor_base&&) = default;
639 template<typename... _Types>
640 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
642 using _Base = _Copy_ctor_alias<_Types...>;
646 template<typename... _Types>
647 using _Move_ctor_alias =
648 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
650 template<bool, typename... _Types>
651 struct _Copy_assign_base : _Move_ctor_alias<_Types...>
653 using _Base = _Move_ctor_alias<_Types...>;
658 operator=(const _Copy_assign_base& __rhs)
659 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
661 __variant::__raw_idx_visit(
662 [this](auto&& __rhs_mem, auto __rhs_index) mutable
664 constexpr size_t __j = __rhs_index;
665 if constexpr (__j == variant_npos)
666 this->_M_reset(); // Make *this valueless.
667 else if (this->_M_index == __j)
668 __variant::__get<__j>(*this) = __rhs_mem;
671 using _Tj = typename _Nth_type<__j, _Types...>::type;
672 if constexpr (is_nothrow_copy_constructible_v<_Tj>
673 || !is_nothrow_move_constructible_v<_Tj>)
674 __variant::__emplace<__j>(*this, __rhs_mem);
677 using _Variant = variant<_Types...>;
678 _Variant& __self = __variant_cast<_Types...>(*this);
679 __self = _Variant(in_place_index<__j>, __rhs_mem);
682 }, __variant_cast<_Types...>(__rhs));
686 _Copy_assign_base(const _Copy_assign_base&) = default;
687 _Copy_assign_base(_Copy_assign_base&&) = default;
688 _Copy_assign_base& operator=(_Copy_assign_base&&) = default;
691 template<typename... _Types>
692 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
694 using _Base = _Move_ctor_alias<_Types...>;
698 template<typename... _Types>
699 using _Copy_assign_alias =
700 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
702 template<bool, typename... _Types>
703 struct _Move_assign_base : _Copy_assign_alias<_Types...>
705 using _Base = _Copy_assign_alias<_Types...>;
710 operator=(_Move_assign_base&& __rhs)
711 noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
713 __variant::__raw_idx_visit(
714 [this](auto&& __rhs_mem, auto __rhs_index) mutable
716 constexpr size_t __j = __rhs_index;
717 if constexpr (__j != variant_npos)
719 if (this->_M_index == __j)
720 __variant::__get<__j>(*this) = std::move(__rhs_mem);
723 using _Tj = typename _Nth_type<__j, _Types...>::type;
724 if constexpr (is_nothrow_move_constructible_v<_Tj>)
725 __variant::__emplace<__j>(*this, std::move(__rhs_mem));
728 using _Variant = variant<_Types...>;
729 _Variant& __self = __variant_cast<_Types...>(*this);
730 __self.template emplace<__j>(std::move(__rhs_mem));
736 }, __variant_cast<_Types...>(__rhs));
740 _Move_assign_base(const _Move_assign_base&) = default;
741 _Move_assign_base(_Move_assign_base&&) = default;
742 _Move_assign_base& operator=(const _Move_assign_base&) = default;
745 template<typename... _Types>
746 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
748 using _Base = _Copy_assign_alias<_Types...>;
752 template<typename... _Types>
753 using _Move_assign_alias =
754 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
756 template<typename... _Types>
757 struct _Variant_base : _Move_assign_alias<_Types...>
759 using _Base = _Move_assign_alias<_Types...>;
762 _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
763 : _Variant_base(in_place_index<0>) { }
765 template<size_t _Np, typename... _Args>
767 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
768 : _Base(__i, std::forward<_Args>(__args)...)
771 _Variant_base(const _Variant_base&) = default;
772 _Variant_base(_Variant_base&&) = default;
773 _Variant_base& operator=(const _Variant_base&) = default;
774 _Variant_base& operator=(_Variant_base&&) = default;
777 template<typename _Tp, typename... _Types>
778 inline constexpr bool __exactly_once
779 = std::__find_uniq_type_in_pack<_Tp, _Types...>() < sizeof...(_Types);
781 // Helper used to check for valid conversions that don't involve narrowing.
782 template<typename _Ti> struct _Arr { _Ti _M_x[1]; };
784 // "Build an imaginary function FUN(Ti) for each alternative type Ti"
785 template<size_t _Ind, typename _Tp, typename _Ti, typename = void>
788 // This function means 'using _Build_FUN<I, T, Ti>::_S_fun;' is valid,
789 // but only static functions will be considered in the call below.
790 void _S_fun() = delete;
793 // "... for which Ti x[] = {std::forward<T>(t)}; is well-formed."
794 template<size_t _Ind, typename _Tp, typename _Ti>
795 struct _Build_FUN<_Ind, _Tp, _Ti,
796 void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>>
798 // This is the FUN function for type _Ti, with index _Ind
799 static integral_constant<size_t, _Ind> _S_fun(_Ti);
802 template<typename _Tp, typename _Variant,
803 typename = make_index_sequence<variant_size_v<_Variant>>>
806 template<typename _Tp, typename... _Ti, size_t... _Ind>
807 struct _Build_FUNs<_Tp, variant<_Ti...>, index_sequence<_Ind...>>
808 : _Build_FUN<_Ind, _Tp, _Ti>...
810 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
813 // The index j of the overload FUN(Tj) selected by overload resolution
814 // for FUN(std::forward<_Tp>(t))
815 template<typename _Tp, typename _Variant>
817 = decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>()));
819 // The index selected for FUN(std::forward<T>(t)), or variant_npos if none.
820 template<typename _Tp, typename _Variant, typename = void>
821 inline constexpr size_t
822 __accepted_index = variant_npos;
824 template<typename _Tp, typename _Variant>
825 inline constexpr size_t
826 __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
827 = _FUN_type<_Tp, _Variant>::value;
829 template<typename _Maybe_variant_cookie, typename _Variant,
830 typename = __remove_cvref_t<_Variant>>
831 inline constexpr bool
832 __extra_visit_slot_needed = false;
834 template<typename _Var, typename... _Types>
835 inline constexpr bool
836 __extra_visit_slot_needed<__variant_cookie, _Var, variant<_Types...>>
837 = !__variant::__never_valueless<_Types...>();
839 template<typename _Var, typename... _Types>
840 inline constexpr bool
841 __extra_visit_slot_needed<__variant_idx_cookie, _Var, variant<_Types...>>
842 = !__variant::__never_valueless<_Types...>();
844 // Used for storing a multi-dimensional vtable.
845 template<typename _Tp, size_t... _Dimensions>
848 // Partial specialization with rank zero, stores a single _Tp element.
849 template<typename _Tp>
850 struct _Multi_array<_Tp>
853 struct __untag_result
855 { using element_type = _Tp; };
857#pragma GCC diagnostic push
858#pragma GCC diagnostic ignored "-Wignored-qualifiers"
859 template <typename... _Args>
860 struct __untag_result<const void(*)(_Args...)>
862 { using element_type = void(*)(_Args...); };
863#pragma GCC diagnostic pop
865 template <typename... _Args>
866 struct __untag_result<__variant_cookie(*)(_Args...)>
868 { using element_type = void(*)(_Args...); };
870 template <typename... _Args>
871 struct __untag_result<__variant_idx_cookie(*)(_Args...)>
873 { using element_type = void(*)(_Args...); };
875 template <typename _Res, typename... _Args>
876 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
878 { using element_type = _Res(*)(_Args...); };
880 using __result_is_deduced = __untag_result<_Tp>;
882 constexpr const typename __untag_result<_Tp>::element_type&
886 typename __untag_result<_Tp>::element_type _M_data;
889 // Partial specialization with rank >= 1.
890 template<typename _Ret,
892 typename... _Variants,
893 size_t __first, size_t... __rest>
894 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
896 static constexpr size_t __index =
897 sizeof...(_Variants) - sizeof...(__rest) - 1;
899 using _Variant = typename _Nth_type<__index, _Variants...>::type;
901 static constexpr int __do_cookie =
902 __extra_visit_slot_needed<_Ret, _Variant> ? 1 : 0;
904 using _Tp = _Ret(*)(_Visitor, _Variants...);
906 template<typename... _Args>
907 constexpr decltype(auto)
908 _M_access(size_t __first_index, _Args... __rest_indices) const
910 return _M_arr[__first_index + __do_cookie]
911 ._M_access(__rest_indices...);
914 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
917 // Creates a multi-dimensional vtable recursively.
920 // visit([](auto, auto){},
921 // variant<int, char>(), // typedef'ed as V1
922 // variant<float, double, long double>()) // typedef'ed as V2
923 // will trigger instantiations of:
924 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>,
925 // tuple<V1&&, V2&&>, std::index_sequence<>>
926 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
927 // tuple<V1&&, V2&&>, std::index_sequence<0>>
928 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
929 // tuple<V1&&, V2&&>, std::index_sequence<0, 0>>
930 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
931 // tuple<V1&&, V2&&>, std::index_sequence<0, 1>>
932 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
933 // tuple<V1&&, V2&&>, std::index_sequence<0, 2>>
934 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
935 // tuple<V1&&, V2&&>, std::index_sequence<1>>
936 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
937 // tuple<V1&&, V2&&>, std::index_sequence<1, 0>>
938 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
939 // tuple<V1&&, V2&&>, std::index_sequence<1, 1>>
940 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
941 // tuple<V1&&, V2&&>, std::index_sequence<1, 2>>
942 // The returned multi-dimensional vtable can be fast accessed by the visitor
943 // using index calculation.
944 template<typename _Array_type, typename _Index_seq>
945 struct __gen_vtable_impl;
947 // Defines the _S_apply() member that returns a _Multi_array populated
948 // with function pointers that perform the visitation expressions e(m)
949 // for each valid pack of indexes into the variant types _Variants.
951 // This partial specialization builds up the index sequences by recursively
952 // calling _S_apply() on the next specialization of __gen_vtable_impl.
953 // The base case of the recursion defines the actual function pointers.
954 template<typename _Result_type, typename _Visitor, size_t... __dimensions,
955 typename... _Variants, size_t... __indices>
956 struct __gen_vtable_impl<
957 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
958 std::index_sequence<__indices...>>
961 remove_reference_t<typename _Nth_type<sizeof...(__indices),
962 _Variants...>::type>;
964 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
967 static constexpr _Array_type
970 _Array_type __vtable{};
972 __vtable, make_index_sequence<variant_size_v<_Next>>());
976 template<size_t... __var_indices>
977 static constexpr void
978 _S_apply_all_alts(_Array_type& __vtable,
979 std::index_sequence<__var_indices...>)
981 if constexpr (__extra_visit_slot_needed<_Result_type, _Next>)
982 (_S_apply_single_alt<true, __var_indices>(
983 __vtable._M_arr[__var_indices + 1],
984 &(__vtable._M_arr[0])), ...);
986 (_S_apply_single_alt<false, __var_indices>(
987 __vtable._M_arr[__var_indices]), ...);
990 template<bool __do_cookie, size_t __index, typename _Tp>
991 static constexpr void
992 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element = nullptr)
994 if constexpr (__do_cookie)
996 __element = __gen_vtable_impl<
998 std::index_sequence<__indices..., __index>>::_S_apply();
999 *__cookie_element = __gen_vtable_impl<
1001 std::index_sequence<__indices..., variant_npos>>::_S_apply();
1005 auto __tmp_element = __gen_vtable_impl<
1006 remove_reference_t<decltype(__element)>,
1007 std::index_sequence<__indices..., __index>>::_S_apply();
1008 static_assert(is_same_v<_Tp, decltype(__tmp_element)>,
1009 "std::visit requires the visitor to have the same "
1010 "return type for all alternatives of a variant");
1011 __element = __tmp_element;
1016 // This partial specialization is the base case for the recursion.
1017 // It populates a _Multi_array element with the address of a function
1018 // that invokes the visitor with the alternatives specified by __indices.
1019 template<typename _Result_type, typename _Visitor, typename... _Variants,
1020 size_t... __indices>
1021 struct __gen_vtable_impl<
1022 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
1023 std::index_sequence<__indices...>>
1026 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
1028 template<size_t __index, typename _Variant>
1029 static constexpr decltype(auto)
1030 __element_by_index_or_cookie(_Variant&& __var) noexcept
1032 if constexpr (__index != variant_npos)
1033 return __variant::__get<__index>(std::forward<_Variant>(__var));
1035 return __variant_cookie{};
1038 static constexpr decltype(auto)
1039 __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1041 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1042 // For raw visitation using indices, pass the indices to the visitor
1043 // and discard the return value:
1044 std::__invoke(std::forward<_Visitor>(__visitor),
1045 __element_by_index_or_cookie<__indices>(
1046 std::forward<_Variants>(__vars))...,
1047 integral_constant<size_t, __indices>()...);
1048 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1049 // For raw visitation without indices, and discard the return value:
1050 std::__invoke(std::forward<_Visitor>(__visitor),
1051 __element_by_index_or_cookie<__indices>(
1052 std::forward<_Variants>(__vars))...);
1053 else if constexpr (_Array_type::__result_is_deduced::value)
1054 // For the usual std::visit case deduce the return value:
1055 return std::__invoke(std::forward<_Visitor>(__visitor),
1056 __element_by_index_or_cookie<__indices>(
1057 std::forward<_Variants>(__vars))...);
1058 else // for std::visit<R> use INVOKE<R>
1059 return std::__invoke_r<_Result_type>(
1060 std::forward<_Visitor>(__visitor),
1061 __variant::__get<__indices>(std::forward<_Variants>(__vars))...);
1064 static constexpr auto
1067 if constexpr (_Array_type::__result_is_deduced::value)
1069 constexpr bool __visit_ret_type_mismatch =
1070 !is_same_v<typename _Result_type::type,
1071 decltype(__visit_invoke(std::declval<_Visitor>(),
1072 std::declval<_Variants>()...))>;
1073 if constexpr (__visit_ret_type_mismatch)
1075 struct __cannot_match {};
1076 return __cannot_match{};
1079 return _Array_type{&__visit_invoke};
1082 return _Array_type{&__visit_invoke};
1086 template<typename _Result_type, typename _Visitor, typename... _Variants>
1090 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1091 variant_size_v<remove_reference_t<_Variants>>...>;
1093 static constexpr _Array_type _S_vtable
1094 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1097#if ! _GLIBCXX_INLINE_VERSION
1098 template<size_t _Nm, typename _Tp>
1099 struct _Base_dedup : public _Tp { };
1101 template<typename _Variant, typename __indices>
1102 struct _Variant_hash_base;
1104 template<typename... _Types, size_t... __indices>
1105 struct _Variant_hash_base<variant<_Types...>,
1106 std::index_sequence<__indices...>>
1107 : _Base_dedup<__indices, __hash_empty_base<remove_const_t<_Types>>>...
1111 // Equivalent to decltype(get<_Np>(as-variant(declval<_Variant>())))
1112 template<size_t _Np, typename _Variant,
1113 typename _AsV = decltype(__variant::__as(std::declval<_Variant>())),
1114 typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>>
1116 = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1118 // Return type of std::visit.
1119 template<typename _Visitor, typename... _Variants>
1120 using __visit_result_t
1121 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1123 template<typename _Tp, typename... _Types>
1124 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1126 template <typename _Visitor, typename _Variant, size_t... _Idxs>
1127 constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>)
1129 return __same_types<
1130 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1134} // namespace __variant
1135} // namespace __detail
1137 template<typename _Tp, typename... _Types>
1139 holds_alternative(const variant<_Types...>& __v) noexcept
1141 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1142 "T must occur exactly once in alternatives");
1143 return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>();
1146 template<typename _Tp, typename... _Types>
1148 get(variant<_Types...>& __v)
1150 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1151 "T must occur exactly once in alternatives");
1152 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1153 return std::get<__n>(__v);
1156 template<typename _Tp, typename... _Types>
1158 get(variant<_Types...>&& __v)
1160 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1161 "T must occur exactly once in alternatives");
1162 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1163 return std::get<__n>(std::move(__v));
1166 template<typename _Tp, typename... _Types>
1167 constexpr const _Tp&
1168 get(const variant<_Types...>& __v)
1170 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1171 "T must occur exactly once in alternatives");
1172 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1173 return std::get<__n>(__v);
1176 template<typename _Tp, typename... _Types>
1177 constexpr const _Tp&&
1178 get(const variant<_Types...>&& __v)
1180 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1181 "T must occur exactly once in alternatives");
1182 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1183 return std::get<__n>(std::move(__v));
1186 template<size_t _Np, typename... _Types>
1187 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1188 get_if(variant<_Types...>* __ptr) noexcept
1190 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1191 static_assert(_Np < sizeof...(_Types),
1192 "The index must be in [0, number of alternatives)");
1193 static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void");
1194 if (__ptr && __ptr->index() == _Np)
1195 return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
1199 template<size_t _Np, typename... _Types>
1201 add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
1202 get_if(const variant<_Types...>* __ptr) noexcept
1204 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1205 static_assert(_Np < sizeof...(_Types),
1206 "The index must be in [0, number of alternatives)");
1207 static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void");
1208 if (__ptr && __ptr->index() == _Np)
1209 return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
1213 template<typename _Tp, typename... _Types>
1214 constexpr add_pointer_t<_Tp>
1215 get_if(variant<_Types...>* __ptr) noexcept
1217 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1218 "T must occur exactly once in alternatives");
1219 static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1220 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1221 return std::get_if<__n>(__ptr);
1224 template<typename _Tp, typename... _Types>
1225 constexpr add_pointer_t<const _Tp>
1226 get_if(const variant<_Types...>* __ptr) noexcept
1228 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1229 "T must occur exactly once in alternatives");
1230 static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1231 constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1232 return std::get_if<__n>(__ptr);
1235namespace __detail::__variant
1237 template<typename _Ret, typename _Vp, typename _Op>
1239 __compare(_Ret __ret, const _Vp& __lhs, const _Vp& __rhs, _Op __op)
1241 __variant::__raw_idx_visit(
1242 [&__ret, &__lhs, __op] (auto&& __rhs_mem, auto __rhs_index) mutable
1244 if constexpr (__rhs_index != variant_npos)
1246 if (__lhs.index() == __rhs_index.value)
1248 auto& __this_mem = std::get<__rhs_index>(__lhs);
1249 __ret = __op(__this_mem, __rhs_mem);
1253 __ret = __op(__lhs.index() + 1, __rhs_index + 1);
1257} // namespace __detail::__variant
1259 template<typename... _Types>
1260#if __cpp_lib_concepts
1261 requires ((requires (const _Types& __t) {
1262 { __t == __t } -> convertible_to<bool>; }) && ...)
1265 operator== [[nodiscard]] (const variant<_Types...>& __lhs,
1266 const variant<_Types...>& __rhs)
1268 namespace __variant = __detail::__variant;
1269 return __variant::__compare(true, __lhs, __rhs,
1270 [](auto&& __l, auto&& __r) -> bool {
1275 template<typename... _Types>
1276#if __cpp_lib_concepts
1277 requires ((requires (const _Types& __t) {
1278 { __t != __t } -> convertible_to<bool>; }) && ...)
1281 operator!= [[nodiscard]] (const variant<_Types...>& __lhs,
1282 const variant<_Types...>& __rhs)
1284 namespace __variant = __detail::__variant;
1285 return __variant::__compare(true, __lhs, __rhs,
1286 [](auto&& __l, auto&& __r) -> bool {
1291 template<typename... _Types>
1292#if __cpp_lib_concepts
1293 requires ((requires (const _Types& __t) {
1294 { __t < __t } -> convertible_to<bool>; }) && ...)
1297 operator< [[nodiscard]] (const variant<_Types...>& __lhs,
1298 const variant<_Types...>& __rhs)
1300 namespace __variant = __detail::__variant;
1301 return __variant::__compare(true, __lhs, __rhs,
1302 [](auto&& __l, auto&& __r) -> bool {
1307 template<typename... _Types>
1308#if __cpp_lib_concepts
1309 requires ((requires (const _Types& __t) {
1310 { __t <= __t } -> convertible_to<bool>; }) && ...)
1313 operator<= [[nodiscard]] (const variant<_Types...>& __lhs,
1314 const variant<_Types...>& __rhs)
1316 namespace __variant = __detail::__variant;
1317 return __variant::__compare(true, __lhs, __rhs,
1318 [](auto&& __l, auto&& __r) -> bool {
1323 template<typename... _Types>
1324#if __cpp_lib_concepts
1325 requires ((requires (const _Types& __t) {
1326 { __t > __t } -> convertible_to<bool>; }) && ...)
1329 operator> [[nodiscard]] (const variant<_Types...>& __lhs,
1330 const variant<_Types...>& __rhs)
1332 namespace __variant = __detail::__variant;
1333 return __variant::__compare(true, __lhs, __rhs,
1334 [](auto&& __l, auto&& __r) -> bool {
1339 template<typename... _Types>
1340#if __cpp_lib_concepts
1341 requires ((requires (const _Types& __t) {
1342 { __t >= __t } -> convertible_to<bool>; }) && ...)
1345 operator>= [[nodiscard]] (const variant<_Types...>& __lhs,
1346 const variant<_Types...>& __rhs)
1348 namespace __variant = __detail::__variant;
1349 return __variant::__compare(true, __lhs, __rhs,
1350 [](auto&& __l, auto&& __r) -> bool {
1355#ifdef __cpp_lib_three_way_comparison
1356 template<typename... _Types>
1357 requires (three_way_comparable<_Types> && ...)
1359 common_comparison_category_t<compare_three_way_result_t<_Types>...>
1360 operator<=>(const variant<_Types...>& __v, const variant<_Types...>& __w)
1362 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1363 = strong_ordering::equal;
1364 namespace __variant = __detail::__variant;
1365 return __variant::__compare(__ret, __v, __w,
1366 [](auto&& __l, auto&& __r) {
1372 template<typename _Visitor, typename... _Variants>
1373 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1374 visit(_Visitor&&, _Variants&&...);
1376#if __cplusplus > 201703L
1377 template<typename _Res, typename _Visitor, typename... _Variants>
1379 visit(_Visitor&&, _Variants&&...);
1382 template<typename... _Types>
1383 _GLIBCXX20_CONSTEXPR
1384 inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1385 && (is_swappable_v<_Types> && ...)>
1386 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1387 noexcept(noexcept(__lhs.swap(__rhs)))
1388 { __lhs.swap(__rhs); }
1390 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1391 // 2766. Swapping non-swappable types
1392 template<typename... _Types>
1393 enable_if_t<!((is_move_constructible_v<_Types> && ...)
1394 && (is_swappable_v<_Types> && ...))>
1395 swap(variant<_Types...>&, variant<_Types...>&) = delete;
1397 [[noreturn]] void __throw_bad_variant_access(unsigned);
1399 class bad_variant_access : public exception
1402 bad_variant_access() noexcept { }
1404 const char* what() const noexcept override
1405 { return _M_reason; }
1408 // Must only be called with a string literal
1409 bad_variant_access(const char* __reason) noexcept : _M_reason(__reason) { }
1411 // Must point to a string with static storage duration:
1412 const char* _M_reason = "bad variant access";
1414 friend void __throw_bad_variant_access([[maybe_unused]] unsigned __n)
1416 [[maybe_unused]] static constexpr const char* __reasons[] = {
1417 "std::get: wrong index for variant",
1418 "std::get: variant is valueless",
1419 "std::visit: variant is valueless",
1420 "std::visit<R>: variant is valueless",
1422 _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__reasons[__n % 4u]));
1426 template<typename... _Types>
1428 : private __detail::__variant::_Variant_base<_Types...>,
1429 private _Enable_copy_move<
1430 __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1431 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1432 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1433 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1437 template <typename... _UTypes, typename _Tp>
1438 friend _GLIBCXX20_CONSTEXPR decltype(auto)
1439 __variant_cast(_Tp&&);
1441 static_assert(sizeof...(_Types) > 0,
1442 "variant must have at least one alternative");
1443 static_assert(((std::is_object_v<_Types> && !is_array_v<_Types>) && ...),
1444 "variant alternatives must be non-array object types");
1446 using _Base = __detail::__variant::_Variant_base<_Types...>;
1448 template<typename _Tp>
1449 static constexpr bool __not_self
1450 = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1452 template<typename _Tp>
1453 static constexpr bool
1454 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1456 template<typename _Tp>
1457 static constexpr size_t __accepted_index
1458 = __detail::__variant::__accepted_index<_Tp, variant>;
1460 template<size_t _Np, typename = enable_if_t<(_Np < sizeof...(_Types))>>
1461 using __to_type = typename _Nth_type<_Np, _Types...>::type;
1463 template<typename _Tp, typename = enable_if_t<__not_self<_Tp>>>
1464 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1466 template<typename _Tp>
1467 static constexpr size_t __index_of
1468 = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1470 using _Traits = __detail::__variant::_Traits<_Types...>;
1472 template<typename _Tp>
1473 static constexpr bool __not_in_place_tag
1474 = !__is_in_place_type_v<__remove_cvref_t<_Tp>>
1475 && !__is_in_place_index_v<__remove_cvref_t<_Tp>>;
1479 variant() requires is_default_constructible_v<__to_type<0>> = default;
1481 template<typename _Tp0 = __to_type<0>,
1482 typename = enable_if_t<is_default_constructible_v<_Tp0>>>
1484 variant() noexcept(is_nothrow_default_constructible_v<__to_type<0>>)
1488 variant(const variant& __rhs) = default;
1489 variant(variant&&) = default;
1490 variant& operator=(const variant&) = default;
1491 variant& operator=(variant&&) = default;
1492 _GLIBCXX20_CONSTEXPR ~variant() = default;
1494 template<typename _Tp,
1495 typename = enable_if_t<sizeof...(_Types) != 0>,
1496 typename = enable_if_t<__not_in_place_tag<_Tp>>,
1497 typename _Tj = __accepted_type<_Tp&&>,
1498 typename = enable_if_t<__exactly_once<_Tj>
1499 && is_constructible_v<_Tj, _Tp>>>
1502 noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1503 : variant(in_place_index<__accepted_index<_Tp>>,
1504 std::forward<_Tp>(__t))
1507 template<typename _Tp, typename... _Args,
1508 typename = enable_if_t<__exactly_once<_Tp>
1509 && is_constructible_v<_Tp, _Args...>>>
1511 variant(in_place_type_t<_Tp>, _Args&&... __args)
1512 : variant(in_place_index<__index_of<_Tp>>,
1513 std::forward<_Args>(__args)...)
1516 template<typename _Tp, typename _Up, typename... _Args,
1517 typename = enable_if_t<__exactly_once<_Tp>
1518 && is_constructible_v<_Tp,
1519 initializer_list<_Up>&, _Args...>>>
1521 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1523 : variant(in_place_index<__index_of<_Tp>>, __il,
1524 std::forward<_Args>(__args)...)
1527 template<size_t _Np, typename... _Args,
1528 typename _Tp = __to_type<_Np>,
1529 typename = enable_if_t<is_constructible_v<_Tp, _Args...>>>
1531 variant(in_place_index_t<_Np>, _Args&&... __args)
1532 : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...)
1535 template<size_t _Np, typename _Up, typename... _Args,
1536 typename _Tp = __to_type<_Np>,
1537 typename = enable_if_t<is_constructible_v<_Tp,
1538 initializer_list<_Up>&,
1541 variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1543 : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...)
1546 template<typename _Tp>
1547 _GLIBCXX20_CONSTEXPR
1548 enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1549 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1550 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1552 operator=(_Tp&& __rhs)
1553 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1554 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1556 constexpr auto __index = __accepted_index<_Tp>;
1557 if (index() == __index)
1558 std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1561 using _Tj = __accepted_type<_Tp&&>;
1562 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1563 || !is_nothrow_move_constructible_v<_Tj>)
1564 this->emplace<__index>(std::forward<_Tp>(__rhs));
1566 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1567 // 3585. converting assignment with immovable alternative
1568 this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs)));
1573 template<typename _Tp, typename... _Args>
1574 _GLIBCXX20_CONSTEXPR
1575 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1577 emplace(_Args&&... __args)
1579 constexpr size_t __index = __index_of<_Tp>;
1580 return this->emplace<__index>(std::forward<_Args>(__args)...);
1583 template<typename _Tp, typename _Up, typename... _Args>
1584 _GLIBCXX20_CONSTEXPR
1585 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1586 && __exactly_once<_Tp>,
1588 emplace(initializer_list<_Up> __il, _Args&&... __args)
1590 constexpr size_t __index = __index_of<_Tp>;
1591 return this->emplace<__index>(__il, std::forward<_Args>(__args)...);
1594 template<size_t _Np, typename... _Args>
1595 _GLIBCXX20_CONSTEXPR
1596 enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>,
1598 emplace(_Args&&... __args)
1600 namespace __variant = std::__detail::__variant;
1601 using type = typename _Nth_type<_Np, _Types...>::type;
1602 // Provide the strong exception-safety guarantee when possible,
1603 // to avoid becoming valueless.
1604 if constexpr (is_nothrow_constructible_v<type, _Args...>)
1606 __variant::__emplace<_Np>(*this, std::forward<_Args>(__args)...);
1608 else if constexpr (is_scalar_v<type>)
1610 // This might invoke a potentially-throwing conversion operator:
1611 const type __tmp(std::forward<_Args>(__args)...);
1612 // But this won't throw:
1613 __variant::__emplace<_Np>(*this, __tmp);
1615 else if constexpr (__variant::_Never_valueless_alt<type>()
1616 && _Traits::_S_move_assign)
1618 // This construction might throw:
1619 variant __tmp(in_place_index<_Np>,
1620 std::forward<_Args>(__args)...);
1621 // But _Never_valueless_alt<type> means this won't:
1622 *this = std::move(__tmp);
1626 // This case only provides the basic exception-safety guarantee,
1627 // i.e. the variant can become valueless.
1628 __variant::__emplace<_Np>(*this, std::forward<_Args>(__args)...);
1630 return std::get<_Np>(*this);
1633 template<size_t _Np, typename _Up, typename... _Args>
1634 _GLIBCXX20_CONSTEXPR
1635 enable_if_t<is_constructible_v<__to_type<_Np>,
1636 initializer_list<_Up>&, _Args...>,
1638 emplace(initializer_list<_Up> __il, _Args&&... __args)
1640 namespace __variant = std::__detail::__variant;
1641 using type = typename _Nth_type<_Np, _Types...>::type;
1642 // Provide the strong exception-safety guarantee when possible,
1643 // to avoid becoming valueless.
1644 if constexpr (is_nothrow_constructible_v<type,
1645 initializer_list<_Up>&,
1648 __variant::__emplace<_Np>(*this, __il,
1649 std::forward<_Args>(__args)...);
1651 else if constexpr (__variant::_Never_valueless_alt<type>()
1652 && _Traits::_S_move_assign)
1654 // This construction might throw:
1655 variant __tmp(in_place_index<_Np>, __il,
1656 std::forward<_Args>(__args)...);
1657 // But _Never_valueless_alt<type> means this won't:
1658 *this = std::move(__tmp);
1662 // This case only provides the basic exception-safety guarantee,
1663 // i.e. the variant can become valueless.
1664 __variant::__emplace<_Np>(*this, __il,
1665 std::forward<_Args>(__args)...);
1667 return std::get<_Np>(*this);
1670 template<size_t _Np, typename... _Args>
1671 enable_if_t<!(_Np < sizeof...(_Types))> emplace(_Args&&...) = delete;
1673 template<typename _Tp, typename... _Args>
1674 enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) = delete;
1676 constexpr bool valueless_by_exception() const noexcept
1677 { return !this->_M_valid(); }
1679 constexpr size_t index() const noexcept
1681 using __index_type = typename _Base::__index_type;
1682 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1683 return this->_M_index;
1684 else if constexpr (sizeof...(_Types) <= __index_type(-1) / 2)
1685 return make_signed_t<__index_type>(this->_M_index);
1687 return size_t(__index_type(this->_M_index + 1)) - 1;
1690 _GLIBCXX20_CONSTEXPR
1692 swap(variant& __rhs)
1693 noexcept((__is_nothrow_swappable<_Types>::value && ...)
1694 && is_nothrow_move_constructible_v<variant>)
1696 static_assert((is_move_constructible_v<_Types> && ...));
1698 // Handle this here to simplify the visitation.
1699 if (__rhs.valueless_by_exception()) [[__unlikely__]]
1701 if (!this->valueless_by_exception()) [[__likely__]]
1706 namespace __variant = __detail::__variant;
1708 __variant::__raw_idx_visit(
1709 [this, &__rhs](auto&& __rhs_mem, auto __rhs_index) mutable
1711 constexpr size_t __j = __rhs_index;
1712 if constexpr (__j != variant_npos)
1714 if (this->index() == __j)
1717 swap(std::get<__j>(*this), __rhs_mem);
1721 auto __tmp(std::move(__rhs_mem));
1723 if constexpr (_Traits::_S_trivial_move_assign)
1724 __rhs = std::move(*this);
1726 __variant::__raw_idx_visit(
1727 [&__rhs](auto&& __this_mem, auto __this_index) mutable
1729 constexpr size_t __k = __this_index;
1730 if constexpr (__k != variant_npos)
1731 __variant::__emplace<__k>(__rhs,
1732 std::move(__this_mem));
1735 __variant::__emplace<__j>(*this, std::move(__tmp));
1741#if __cpp_lib_variant >= 202306L // >= C++26
1742 // [variant.visit], visitation
1744 /** Simple visitation for a single variant
1746 * To visit a single variant you can use `var.visit(visitor)`
1747 * instead of `std::visit(visitor, var)`.
1751 template<int = 0, typename _Self, typename _Visitor>
1752 constexpr decltype(auto)
1753 visit(this _Self&& __self, _Visitor&& __vis)
1755 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1756 const variant, variant>;
1757 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1759 return std::visit(std::forward<_Visitor>(__vis), (_Var)__self);
1762 /** Simple visitation for a single variant, with explicit return type
1764 * To visit a single variant you can use `var.visit<R>(visitor)`
1765 * instead of `std::visit<R>(visitor, var)`.
1769 template<typename _Res, typename _Self, typename _Visitor>
1771 visit(this _Self&& __self, _Visitor&& __vis)
1773 using _CVar = __conditional_t<is_const_v<remove_reference_t<_Self>>,
1774 const variant, variant>;
1775 using _Var = __conditional_t<is_rvalue_reference_v<_Self&&>,
1777 return std::visit<_Res>(std::forward<_Visitor>(__vis), (_Var)__self);
1782 template<size_t _Np, typename _Vp>
1783 friend constexpr decltype(auto)
1784 __detail::__variant::__get(_Vp&& __v) noexcept;
1787 template<size_t _Np, typename... _Types>
1788 constexpr variant_alternative_t<_Np, variant<_Types...>>&
1789 get(variant<_Types...>& __v)
1791 static_assert(_Np < sizeof...(_Types),
1792 "The index must be in [0, number of alternatives)");
1793 if (__v.index() != _Np)
1794 __throw_bad_variant_access(__v.valueless_by_exception());
1795 return __detail::__variant::__get<_Np>(__v);
1798 template<size_t _Np, typename... _Types>
1799 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1800 get(variant<_Types...>&& __v)
1802 static_assert(_Np < sizeof...(_Types),
1803 "The index must be in [0, number of alternatives)");
1804 if (__v.index() != _Np)
1805 __throw_bad_variant_access(__v.valueless_by_exception());
1806 return __detail::__variant::__get<_Np>(std::move(__v));
1809 template<size_t _Np, typename... _Types>
1810 constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1811 get(const variant<_Types...>& __v)
1813 static_assert(_Np < sizeof...(_Types),
1814 "The index must be in [0, number of alternatives)");
1815 if (__v.index() != _Np)
1816 __throw_bad_variant_access(__v.valueless_by_exception());
1817 return __detail::__variant::__get<_Np>(__v);
1820 template<size_t _Np, typename... _Types>
1821 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1822 get(const variant<_Types...>&& __v)
1824 static_assert(_Np < sizeof...(_Types),
1825 "The index must be in [0, number of alternatives)");
1826 if (__v.index() != _Np)
1827 __throw_bad_variant_access(__v.valueless_by_exception());
1828 return __detail::__variant::__get<_Np>(std::move(__v));
1831 /// @cond undocumented
1832 template<typename _Result_type, typename _Visitor, typename... _Variants>
1833 constexpr decltype(auto)
1834 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1836 // Get the silly case of visiting no variants out of the way first.
1837 if constexpr (sizeof...(_Variants) == 0)
1839 if constexpr (is_void_v<_Result_type>)
1840 return (void) std::forward<_Visitor>(__visitor)();
1842 return std::forward<_Visitor>(__visitor)();
1846 constexpr size_t __max = 11; // "These go to eleven."
1848 // The type of the first variant in the pack.
1849 using _V0 = typename _Nth_type<0, _Variants...>::type;
1850 // The number of alternatives in that first variant.
1851 constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
1853 if constexpr (sizeof...(_Variants) > 1 || __n > __max)
1855 // Use a jump table for the general case.
1856 constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1857 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1859 auto __func_ptr = __vtable._M_access(__variants.index()...);
1860 return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1861 std::forward<_Variants>(__variants)...);
1863 else // We have a single variant with a small number of alternatives.
1865 // A name for the first variant in the pack.
1867 = [](_V0& __v, ...) -> _V0& { return __v; }(__variants...);
1869 using __detail::__variant::_Multi_array;
1870 using __detail::__variant::__gen_vtable_impl;
1871 using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0&&)>;
1873#ifdef _GLIBCXX_DEBUG
1874# define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap
1876# define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable
1879#define _GLIBCXX_VISIT_CASE(N) \
1882 if constexpr (N < __n) \
1884 return __gen_vtable_impl<_Ma, index_sequence<N>>:: \
1885 __visit_invoke(std::forward<_Visitor>(__visitor), \
1886 std::forward<_V0>(__v0)); \
1888 else _GLIBCXX_VISIT_UNREACHABLE(); \
1891 switch (__v0.index())
1893 _GLIBCXX_VISIT_CASE(0)
1894 _GLIBCXX_VISIT_CASE(1)
1895 _GLIBCXX_VISIT_CASE(2)
1896 _GLIBCXX_VISIT_CASE(3)
1897 _GLIBCXX_VISIT_CASE(4)
1898 _GLIBCXX_VISIT_CASE(5)
1899 _GLIBCXX_VISIT_CASE(6)
1900 _GLIBCXX_VISIT_CASE(7)
1901 _GLIBCXX_VISIT_CASE(8)
1902 _GLIBCXX_VISIT_CASE(9)
1903 _GLIBCXX_VISIT_CASE(10)
1905 using __detail::__variant::__variant_idx_cookie;
1906 using __detail::__variant::__variant_cookie;
1907 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
1908 || is_same_v<_Result_type, __variant_cookie>)
1910 using _Npos = index_sequence<variant_npos>;
1911 return __gen_vtable_impl<_Ma, _Npos>::
1912 __visit_invoke(std::forward<_Visitor>(__visitor),
1913 std::forward<_V0>(__v0));
1916 _GLIBCXX_VISIT_UNREACHABLE();
1918 _GLIBCXX_VISIT_UNREACHABLE();
1920#undef _GLIBCXX_VISIT_CASE
1921#undef _GLIBCXX_VISIT_UNREACHABLE
1927 template<typename _Visitor, typename... _Variants>
1928 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1929 visit(_Visitor&& __visitor, _Variants&&... __variants)
1931 namespace __variant = std::__detail::__variant;
1933 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1934 __throw_bad_variant_access(2);
1937 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1939 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1941 if constexpr (sizeof...(_Variants) == 1)
1943 using _Vp = decltype(__variant::__as(std::declval<_Variants>()...));
1945 constexpr bool __visit_rettypes_match = __detail::__variant::
1946 __check_visitor_results<_Visitor, _Vp>(
1947 make_index_sequence<variant_size_v<remove_reference_t<_Vp>>>());
1948 if constexpr (!__visit_rettypes_match)
1950 static_assert(__visit_rettypes_match,
1951 "std::visit requires the visitor to have the same "
1952 "return type for all alternatives of a variant");
1956 return std::__do_visit<_Tag>(
1957 std::forward<_Visitor>(__visitor),
1958 static_cast<_Vp>(__variants)...);
1961 return std::__do_visit<_Tag>(
1962 std::forward<_Visitor>(__visitor),
1963 __variant::__as(std::forward<_Variants>(__variants))...);
1966#if __cplusplus > 201703L
1967 template<typename _Res, typename _Visitor, typename... _Variants>
1969 visit(_Visitor&& __visitor, _Variants&&... __variants)
1971 namespace __variant = std::__detail::__variant;
1973 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1974 __throw_bad_variant_access(3);
1976 return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor),
1977 __variant::__as(std::forward<_Variants>(__variants))...);
1981 /// @cond undocumented
1982 template<typename... _Types>
1983 struct __variant_hash
1985#if __cplusplus < 202002L
1986 using result_type [[__deprecated__]] = size_t;
1987 using argument_type [[__deprecated__]] = variant<_Types...>;
1991 operator()(const variant<_Types...>& __t) const
1992 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1995 __detail::__variant::__raw_visit(
1996 [&__t, &__ret](auto&& __t_mem) mutable
1998 using _Type = __remove_cvref_t<decltype(__t_mem)>;
1999 if constexpr (!is_same_v<_Type,
2000 __detail::__variant::__variant_cookie>)
2001 __ret = std::hash<size_t>{}(__t.index())
2002 + std::hash<_Type>{}(__t_mem);
2004 __ret = std::hash<size_t>{}(__t.index());
2011 template<typename... _Types>
2012 struct hash<variant<_Types...>>
2013 : __conditional_t<(__is_hash_enabled_for<remove_const_t<_Types>> && ...),
2014 __variant_hash<_Types...>,
2015 __hash_not_enabled<variant<_Types...>>>
2016#if ! _GLIBCXX_INLINE_VERSION
2017 , __detail::__variant::_Variant_hash_base<variant<_Types...>,
2018 index_sequence_for<_Types...>>
2022 template<typename... _Types>
2023 struct __is_fast_hash<hash<variant<_Types...>>>
2024 : bool_constant<(__is_fast_hash<_Types>::value && ...)>
2027_GLIBCXX_END_NAMESPACE_VERSION
2030#endif // __cpp_lib_variant
2031#endif // _GLIBCXX_VARIANT