1// <variant> -*- C++ -*-
3// Copyright (C) 2016-2021 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
32#pragma GCC system_header
34#if __cplusplus >= 201703L
38#include <bits/enable_special_members.h>
39#include <bits/functexcept.h>
41#include <bits/functional_hash.h>
42#include <bits/invoke.h>
43#include <ext/aligned_buffer.h>
44#include <bits/parse_numbers.h>
45#include <bits/stl_iterator_base_types.h>
46#include <bits/stl_iterator_base_funcs.h>
47#include <bits/stl_construct.h>
48#if __cplusplus > 201703L
52namespace std _GLIBCXX_VISIBILITY(default)
54_GLIBCXX_BEGIN_NAMESPACE_VERSION
60 template<size_t _Np, typename... _Types>
63 template<size_t _Np, typename _First, typename... _Rest>
64 struct _Nth_type<_Np, _First, _Rest...>
65 : _Nth_type<_Np-1, _Rest...> { };
67 template<typename _First, typename... _Rest>
68 struct _Nth_type<0, _First, _Rest...>
69 { using type = _First; };
71} // namespace __variant
72} // namespace __detail
74#define __cpp_lib_variant 202102L
76 template<typename... _Types> class tuple;
77 template<typename... _Types> class variant;
78 template <typename> struct hash;
80 template<typename _Variant>
83 template<typename _Variant>
84 struct variant_size<const _Variant> : variant_size<_Variant> {};
86 template<typename _Variant>
87 struct variant_size<volatile _Variant> : variant_size<_Variant> {};
89 template<typename _Variant>
90 struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
92 template<typename... _Types>
93 struct variant_size<variant<_Types...>>
94 : std::integral_constant<size_t, sizeof...(_Types)> {};
96 template<typename _Variant>
97 inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
99 template<size_t _Np, typename _Variant>
100 struct variant_alternative;
102 template<size_t _Np, typename _First, typename... _Rest>
103 struct variant_alternative<_Np, variant<_First, _Rest...>>
104 : variant_alternative<_Np-1, variant<_Rest...>> {};
106 template<typename _First, typename... _Rest>
107 struct variant_alternative<0, variant<_First, _Rest...>>
108 { using type = _First; };
110 template<size_t _Np, typename _Variant>
111 using variant_alternative_t =
112 typename variant_alternative<_Np, _Variant>::type;
114 template<size_t _Np, typename _Variant>
115 struct variant_alternative<_Np, const _Variant>
116 { using type = add_const_t<variant_alternative_t<_Np, _Variant>>; };
118 template<size_t _Np, typename _Variant>
119 struct variant_alternative<_Np, volatile _Variant>
120 { using type = add_volatile_t<variant_alternative_t<_Np, _Variant>>; };
122 template<size_t _Np, typename _Variant>
123 struct variant_alternative<_Np, const volatile _Variant>
124 { using type = add_cv_t<variant_alternative_t<_Np, _Variant>>; };
126 inline constexpr size_t variant_npos = -1;
128 template<size_t _Np, typename... _Types>
129 constexpr variant_alternative_t<_Np, variant<_Types...>>&
130 get(variant<_Types...>&);
132 template<size_t _Np, typename... _Types>
133 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
134 get(variant<_Types...>&&);
136 template<size_t _Np, typename... _Types>
137 constexpr variant_alternative_t<_Np, variant<_Types...>> const&
138 get(const variant<_Types...>&);
140 template<size_t _Np, typename... _Types>
141 constexpr variant_alternative_t<_Np, variant<_Types...>> const&&
142 get(const variant<_Types...>&&);
144 template<typename _Result_type, typename _Visitor, typename... _Variants>
145 constexpr decltype(auto)
146 __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
148 template <typename... _Types, typename _Tp>
150 __variant_cast(_Tp&& __rhs)
152 if constexpr (is_lvalue_reference_v<_Tp>)
154 if constexpr (is_const_v<remove_reference_t<_Tp>>)
155 return static_cast<const variant<_Types...>&>(__rhs);
157 return static_cast<variant<_Types...>&>(__rhs);
160 return static_cast<variant<_Types...>&&>(__rhs);
167 // Returns the first appearance of _Tp in _Types.
168 // Returns sizeof...(_Types) if _Tp is not in _Types.
169 template<typename _Tp, typename... _Types>
170 struct __index_of : std::integral_constant<size_t, 0> {};
172 template<typename _Tp, typename... _Types>
173 inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value;
175 template<typename _Tp, typename _First, typename... _Rest>
176 struct __index_of<_Tp, _First, _Rest...> :
177 std::integral_constant<size_t, is_same_v<_Tp, _First>
178 ? 0 : __index_of_v<_Tp, _Rest...> + 1> {};
180 // used for raw visitation
181 struct __variant_cookie {};
182 // used for raw visitation with indices passed in
183 struct __variant_idx_cookie { using type = __variant_idx_cookie; };
184 // Used to enable deduction (and same-type checking) for std::visit:
185 template<typename _Tp> struct __deduce_visit_result { using type = _Tp; };
187 // Visit variants that might be valueless.
188 template<typename _Visitor, typename... _Variants>
190 __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
192 std::__do_visit<__variant_cookie>(std::forward<_Visitor>(__visitor),
193 std::forward<_Variants>(__variants)...);
196 // Visit variants that might be valueless, passing indices to the visitor.
197 template<typename _Visitor, typename... _Variants>
199 __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
201 std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor),
202 std::forward<_Variants>(__variants)...);
205 // The __as function templates implement the exposition-only "as-variant"
207 template<typename... _Types>
208 constexpr std::variant<_Types...>&
209 __as(std::variant<_Types...>& __v) noexcept
212 template<typename... _Types>
213 constexpr const std::variant<_Types...>&
214 __as(const std::variant<_Types...>& __v) noexcept
217 template<typename... _Types>
218 constexpr std::variant<_Types...>&&
219 __as(std::variant<_Types...>&& __v) noexcept
220 { return std::move(__v); }
222 template<typename... _Types>
223 constexpr const std::variant<_Types...>&&
224 __as(const std::variant<_Types...>&& __v) noexcept
225 { return std::move(__v); }
227 // _Uninitialized<T> is guaranteed to be a trivially destructible type,
229 template<typename _Type, bool = std::is_trivially_destructible_v<_Type>>
230 struct _Uninitialized;
232 template<typename _Type>
233 struct _Uninitialized<_Type, true>
235 template<typename... _Args>
237 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
238 : _M_storage(std::forward<_Args>(__args)...)
241 constexpr const _Type& _M_get() const & noexcept
242 { return _M_storage; }
244 constexpr _Type& _M_get() & noexcept
245 { return _M_storage; }
247 constexpr const _Type&& _M_get() const && noexcept
248 { return std::move(_M_storage); }
250 constexpr _Type&& _M_get() && noexcept
251 { return std::move(_M_storage); }
256 template<typename _Type>
257 struct _Uninitialized<_Type, false>
259 template<typename... _Args>
261 _Uninitialized(in_place_index_t<0>, _Args&&... __args)
263 ::new ((void*)std::addressof(_M_storage))
264 _Type(std::forward<_Args>(__args)...);
267 const _Type& _M_get() const & noexcept
268 { return *_M_storage._M_ptr(); }
270 _Type& _M_get() & noexcept
271 { return *_M_storage._M_ptr(); }
273 const _Type&& _M_get() const && noexcept
274 { return std::move(*_M_storage._M_ptr()); }
276 _Type&& _M_get() && noexcept
277 { return std::move(*_M_storage._M_ptr()); }
279 __gnu_cxx::__aligned_membuf<_Type> _M_storage;
282 template<typename _Union>
283 constexpr decltype(auto)
284 __get(in_place_index_t<0>, _Union&& __u) noexcept
285 { return std::forward<_Union>(__u)._M_first._M_get(); }
287 template<size_t _Np, typename _Union>
288 constexpr decltype(auto)
289 __get(in_place_index_t<_Np>, _Union&& __u) noexcept
291 return __variant::__get(in_place_index<_Np-1>,
292 std::forward<_Union>(__u)._M_rest);
295 // Returns the typed storage for __v.
296 template<size_t _Np, typename _Variant>
297 constexpr decltype(auto)
298 __get(_Variant&& __v) noexcept
300 return __variant::__get(std::in_place_index<_Np>,
301 std::forward<_Variant>(__v)._M_u);
304 template<typename... _Types>
307 static constexpr bool _S_default_ctor =
308 is_default_constructible_v<typename _Nth_type<0, _Types...>::type>;
309 static constexpr bool _S_copy_ctor =
310 (is_copy_constructible_v<_Types> && ...);
311 static constexpr bool _S_move_ctor =
312 (is_move_constructible_v<_Types> && ...);
313 static constexpr bool _S_copy_assign =
315 && (is_copy_assignable_v<_Types> && ...);
316 static constexpr bool _S_move_assign =
318 && (is_move_assignable_v<_Types> && ...);
320 static constexpr bool _S_trivial_dtor =
321 (is_trivially_destructible_v<_Types> && ...);
322 static constexpr bool _S_trivial_copy_ctor =
323 (is_trivially_copy_constructible_v<_Types> && ...);
324 static constexpr bool _S_trivial_move_ctor =
325 (is_trivially_move_constructible_v<_Types> && ...);
326 static constexpr bool _S_trivial_copy_assign =
327 _S_trivial_dtor && _S_trivial_copy_ctor
328 && (is_trivially_copy_assignable_v<_Types> && ...);
329 static constexpr bool _S_trivial_move_assign =
330 _S_trivial_dtor && _S_trivial_move_ctor
331 && (is_trivially_move_assignable_v<_Types> && ...);
333 // The following nothrow traits are for non-trivial SMFs. Trivial SMFs
334 // are always nothrow.
335 static constexpr bool _S_nothrow_default_ctor =
336 is_nothrow_default_constructible_v<
337 typename _Nth_type<0, _Types...>::type>;
338 static constexpr bool _S_nothrow_copy_ctor = false;
339 static constexpr bool _S_nothrow_move_ctor =
340 (is_nothrow_move_constructible_v<_Types> && ...);
341 static constexpr bool _S_nothrow_copy_assign = false;
342 static constexpr bool _S_nothrow_move_assign =
344 && (is_nothrow_move_assignable_v<_Types> && ...);
347 // Defines members and ctors.
348 template<typename... _Types>
349 union _Variadic_union { };
351 template<typename _First, typename... _Rest>
352 union _Variadic_union<_First, _Rest...>
354 constexpr _Variadic_union() : _M_rest() { }
356 template<typename... _Args>
357 constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args)
358 : _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
361 template<size_t _Np, typename... _Args>
362 constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
363 : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
366 _Uninitialized<_First> _M_first;
367 _Variadic_union<_Rest...> _M_rest;
370 // _Never_valueless_alt is true for variant alternatives that can
371 // always be placed in a variant without it becoming valueless.
373 // For suitably-small, trivially copyable types we can create temporaries
374 // on the stack and then memcpy them into place.
375 template<typename _Tp>
376 struct _Never_valueless_alt
377 : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
380 // Specialize _Never_valueless_alt for other types which have a
381 // non-throwing and cheap move construction and move assignment operator,
382 // so that emplacing the type will provide the strong exception-safety
383 // guarantee, by creating and moving a temporary.
384 // Whether _Never_valueless_alt<T> is true or not affects the ABI of a
385 // variant using that alternative, so we can't change the value later!
387 // True if every alternative in _Types... can be emplaced in a variant
388 // without it becoming valueless. If this is true, variant<_Types...>
389 // can never be valueless, which enables some minor optimizations.
390 template <typename... _Types>
391 constexpr bool __never_valueless()
393 return _Traits<_Types...>::_S_move_assign
394 && (_Never_valueless_alt<_Types>::value && ...);
397 // Defines index and the dtor, possibly trivial.
398 template<bool __trivially_destructible, typename... _Types>
399 struct _Variant_storage;
401 template <typename... _Types>
402 using __select_index =
403 typename __select_int::_Select_int_base<sizeof...(_Types),
405 unsigned short>::type::value_type;
407 template<typename... _Types>
408 struct _Variant_storage<false, _Types...>
412 : _M_index(static_cast<__index_type>(variant_npos))
415 template<size_t _Np, typename... _Args>
417 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
418 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
424 if (!_M_valid()) [[unlikely]]
427 std::__do_visit<void>([](auto&& __this_mem) mutable
429 std::_Destroy(std::__addressof(__this_mem));
430 }, __variant_cast<_Types...>(*this));
432 _M_index = static_cast<__index_type>(variant_npos);
439 _M_valid() const noexcept
441 if constexpr (__variant::__never_valueless<_Types...>())
443 return this->_M_index != __index_type(variant_npos);
446 _Variadic_union<_Types...> _M_u;
447 using __index_type = __select_index<_Types...>;
448 __index_type _M_index;
451 template<typename... _Types>
452 struct _Variant_storage<true, _Types...>
456 : _M_index(static_cast<__index_type>(variant_npos))
459 template<size_t _Np, typename... _Args>
461 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
462 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
466 void _M_reset() noexcept
467 { _M_index = static_cast<__index_type>(variant_npos); }
470 _M_valid() const noexcept
472 if constexpr (__variant::__never_valueless<_Types...>())
474 return this->_M_index != static_cast<__index_type>(variant_npos);
477 _Variadic_union<_Types...> _M_u;
478 using __index_type = __select_index<_Types...>;
479 __index_type _M_index;
482 template<typename... _Types>
483 using _Variant_storage_alias =
484 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
486 template<typename _Tp, typename _Up>
487 void __variant_construct_single(_Tp&& __lhs, _Up&& __rhs_mem)
489 void* __storage = std::addressof(__lhs._M_u);
490 using _Type = remove_reference_t<decltype(__rhs_mem)>;
491 if constexpr (!is_same_v<_Type, __variant_cookie>)
493 _Type(std::forward<decltype(__rhs_mem)>(__rhs_mem));
496 template<typename... _Types, typename _Tp, typename _Up>
497 void __variant_construct(_Tp&& __lhs, _Up&& __rhs)
499 __lhs._M_index = __rhs._M_index;
500 __variant::__raw_visit([&__lhs](auto&& __rhs_mem) mutable
502 __variant_construct_single(std::forward<_Tp>(__lhs),
503 std::forward<decltype(__rhs_mem)>(__rhs_mem));
504 }, __variant_cast<_Types...>(std::forward<_Up>(__rhs)));
507 // The following are (Copy|Move) (ctor|assign) layers for forwarding
508 // triviality and handling non-trivial SMF behaviors.
510 template<bool, typename... _Types>
511 struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
513 using _Base = _Variant_storage_alias<_Types...>;
516 _Copy_ctor_base(const _Copy_ctor_base& __rhs)
517 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
519 __variant_construct<_Types...>(*this, __rhs);
522 _Copy_ctor_base(_Copy_ctor_base&&) = default;
523 _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default;
524 _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default;
527 template<typename... _Types>
528 struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
530 using _Base = _Variant_storage_alias<_Types...>;
534 template<typename... _Types>
535 using _Copy_ctor_alias =
536 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
538 template<bool, typename... _Types>
539 struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
541 using _Base = _Copy_ctor_alias<_Types...>;
544 _Move_ctor_base(_Move_ctor_base&& __rhs)
545 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
547 __variant_construct<_Types...>(*this, std::move(__rhs));
550 template<typename _Up>
551 void _M_destructive_move(unsigned short __rhs_index, _Up&& __rhs)
554 __variant_construct_single(*this, std::forward<_Up>(__rhs));
555 this->_M_index = __rhs_index;
558 template<typename _Up>
559 void _M_destructive_copy(unsigned short __rhs_index, const _Up& __rhs)
562 __variant_construct_single(*this, __rhs);
563 this->_M_index = __rhs_index;
566 _Move_ctor_base(const _Move_ctor_base&) = default;
567 _Move_ctor_base& operator=(const _Move_ctor_base&) = default;
568 _Move_ctor_base& operator=(_Move_ctor_base&&) = default;
571 template<typename... _Types>
572 struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
574 using _Base = _Copy_ctor_alias<_Types...>;
577 template<typename _Up>
578 void _M_destructive_move(unsigned short __rhs_index, _Up&& __rhs)
581 __variant_construct_single(*this, std::forward<_Up>(__rhs));
582 this->_M_index = __rhs_index;
585 template<typename _Up>
586 void _M_destructive_copy(unsigned short __rhs_index, const _Up& __rhs)
589 __variant_construct_single(*this, __rhs);
590 this->_M_index = __rhs_index;
594 template<typename... _Types>
595 using _Move_ctor_alias =
596 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
598 template<bool, typename... _Types>
599 struct _Copy_assign_base : _Move_ctor_alias<_Types...>
601 using _Base = _Move_ctor_alias<_Types...>;
605 operator=(const _Copy_assign_base& __rhs)
606 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
608 __variant::__raw_idx_visit(
609 [this](auto&& __rhs_mem, auto __rhs_index) mutable
611 if constexpr (__rhs_index != variant_npos)
613 if (this->_M_index == __rhs_index)
614 __variant::__get<__rhs_index>(*this) = __rhs_mem;
617 using __rhs_type = __remove_cvref_t<decltype(__rhs_mem)>;
618 if constexpr (is_nothrow_copy_constructible_v<__rhs_type>
619 || !is_nothrow_move_constructible_v<__rhs_type>)
620 // The standard says this->emplace<__rhs_type>(__rhs_mem)
621 // should be used here, but _M_destructive_copy is
622 // equivalent in this case. Either copy construction
623 // doesn't throw, so _M_destructive_copy gives strong
624 // exception safety guarantee, or both copy construction
625 // and move construction can throw, so emplace only gives
626 // basic exception safety anyway.
627 this->_M_destructive_copy(__rhs_index, __rhs_mem);
629 __variant_cast<_Types...>(*this)
630 = variant<_Types...>(std::in_place_index<__rhs_index>,
636 }, __variant_cast<_Types...>(__rhs));
640 _Copy_assign_base(const _Copy_assign_base&) = default;
641 _Copy_assign_base(_Copy_assign_base&&) = default;
642 _Copy_assign_base& operator=(_Copy_assign_base&&) = default;
645 template<typename... _Types>
646 struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
648 using _Base = _Move_ctor_alias<_Types...>;
652 template<typename... _Types>
653 using _Copy_assign_alias =
654 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
656 template<bool, typename... _Types>
657 struct _Move_assign_base : _Copy_assign_alias<_Types...>
659 using _Base = _Copy_assign_alias<_Types...>;
663 operator=(_Move_assign_base&& __rhs)
664 noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
666 __variant::__raw_idx_visit(
667 [this](auto&& __rhs_mem, auto __rhs_index) mutable
669 if constexpr (__rhs_index != variant_npos)
671 if (this->_M_index == __rhs_index)
672 __variant::__get<__rhs_index>(*this) = std::move(__rhs_mem);
674 __variant_cast<_Types...>(*this)
675 .template emplace<__rhs_index>(std::move(__rhs_mem));
679 }, __variant_cast<_Types...>(__rhs));
683 _Move_assign_base(const _Move_assign_base&) = default;
684 _Move_assign_base(_Move_assign_base&&) = default;
685 _Move_assign_base& operator=(const _Move_assign_base&) = default;
688 template<typename... _Types>
689 struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
691 using _Base = _Copy_assign_alias<_Types...>;
695 template<typename... _Types>
696 using _Move_assign_alias =
697 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
699 template<typename... _Types>
700 struct _Variant_base : _Move_assign_alias<_Types...>
702 using _Base = _Move_assign_alias<_Types...>;
706 noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
707 : _Variant_base(in_place_index<0>) { }
709 template<size_t _Np, typename... _Args>
711 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
712 : _Base(__i, std::forward<_Args>(__args)...)
715 _Variant_base(const _Variant_base&) = default;
716 _Variant_base(_Variant_base&&) = default;
717 _Variant_base& operator=(const _Variant_base&) = default;
718 _Variant_base& operator=(_Variant_base&&) = default;
721 // For how many times does _Tp appear in _Tuple?
722 template<typename _Tp, typename _Tuple>
723 struct __tuple_count;
725 template<typename _Tp, typename _Tuple>
726 inline constexpr size_t __tuple_count_v =
727 __tuple_count<_Tp, _Tuple>::value;
729 template<typename _Tp, typename... _Types>
730 struct __tuple_count<_Tp, tuple<_Types...>>
731 : integral_constant<size_t, 0> { };
733 template<typename _Tp, typename _First, typename... _Rest>
734 struct __tuple_count<_Tp, tuple<_First, _Rest...>>
737 __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
739 // TODO: Reuse this in <tuple> ?
740 template<typename _Tp, typename... _Types>
741 inline constexpr bool __exactly_once =
742 __tuple_count_v<_Tp, tuple<_Types...>> == 1;
744 // Helper used to check for valid conversions that don't involve narrowing.
745 template<typename _Ti> struct _Arr { _Ti _M_x[1]; };
747 // "Build an imaginary function FUN(Ti) for each alternative type Ti"
748 template<size_t _Ind, typename _Tp, typename _Ti, typename = void>
751 // This function means 'using _Build_FUN<I, T, Ti>::_S_fun;' is valid,
752 // but only static functions will be considered in the call below.
756 // "... for which Ti x[] = {std::forward<T>(t)}; is well-formed."
757 template<size_t _Ind, typename _Tp, typename _Ti>
758 struct _Build_FUN<_Ind, _Tp, _Ti,
759 void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>>
761 // This is the FUN function for type _Ti, with index _Ind
762 static integral_constant<size_t, _Ind> _S_fun(_Ti);
765 template<typename _Tp, typename _Variant,
766 typename = make_index_sequence<variant_size_v<_Variant>>>
769 template<typename _Tp, typename... _Ti, size_t... _Ind>
770 struct _Build_FUNs<_Tp, variant<_Ti...>, index_sequence<_Ind...>>
771 : _Build_FUN<_Ind, _Tp, _Ti>...
773 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
776 // The index j of the overload FUN(Tj) selected by overload resolution
777 // for FUN(std::forward<_Tp>(t))
778 template<typename _Tp, typename _Variant>
780 = decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>()));
782 // The index selected for FUN(std::forward<T>(t)), or variant_npos if none.
783 template<typename _Tp, typename _Variant, typename = void>
784 struct __accepted_index
785 : integral_constant<size_t, variant_npos>
788 template<typename _Tp, typename _Variant>
789 struct __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
790 : _FUN_type<_Tp, _Variant>
793 template <typename _Maybe_variant_cookie, typename _Variant>
794 struct _Extra_visit_slot_needed
796 template <typename> struct _Variant_never_valueless;
798 template <typename... _Types>
799 struct _Variant_never_valueless<variant<_Types...>>
800 : bool_constant<__variant::__never_valueless<_Types...>()> {};
802 static constexpr bool value =
803 (is_same_v<_Maybe_variant_cookie, __variant_cookie>
804 || is_same_v<_Maybe_variant_cookie, __variant_idx_cookie>)
805 && !_Variant_never_valueless<__remove_cvref_t<_Variant>>::value;
808 // Used for storing a multi-dimensional vtable.
809 template<typename _Tp, size_t... _Dimensions>
812 // Partial specialization with rank zero, stores a single _Tp element.
813 template<typename _Tp>
814 struct _Multi_array<_Tp>
817 struct __untag_result
819 { using element_type = _Tp; };
821 template <typename... _Args>
822 struct __untag_result<const void(*)(_Args...)>
824 { using element_type = void(*)(_Args...); };
826 template <typename... _Args>
827 struct __untag_result<__variant_cookie(*)(_Args...)>
829 { using element_type = void(*)(_Args...); };
831 template <typename... _Args>
832 struct __untag_result<__variant_idx_cookie(*)(_Args...)>
834 { using element_type = void(*)(_Args...); };
836 template <typename _Res, typename... _Args>
837 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
839 { using element_type = _Res(*)(_Args...); };
841 using __result_is_deduced = __untag_result<_Tp>;
843 constexpr const typename __untag_result<_Tp>::element_type&
847 typename __untag_result<_Tp>::element_type _M_data;
850 // Partial specialization with rank >= 1.
851 template<typename _Ret,
853 typename... _Variants,
854 size_t __first, size_t... __rest>
855 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
857 static constexpr size_t __index =
858 sizeof...(_Variants) - sizeof...(__rest) - 1;
860 using _Variant = typename _Nth_type<__index, _Variants...>::type;
862 static constexpr int __do_cookie =
863 _Extra_visit_slot_needed<_Ret, _Variant>::value ? 1 : 0;
865 using _Tp = _Ret(*)(_Visitor, _Variants...);
867 template<typename... _Args>
868 constexpr decltype(auto)
869 _M_access(size_t __first_index, _Args... __rest_indices) const
871 return _M_arr[__first_index + __do_cookie]
872 ._M_access(__rest_indices...);
875 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
878 // Creates a multi-dimensional vtable recursively.
881 // visit([](auto, auto){},
882 // variant<int, char>(), // typedef'ed as V1
883 // variant<float, double, long double>()) // typedef'ed as V2
884 // will trigger instantiations of:
885 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>,
886 // tuple<V1&&, V2&&>, std::index_sequence<>>
887 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
888 // tuple<V1&&, V2&&>, std::index_sequence<0>>
889 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
890 // tuple<V1&&, V2&&>, std::index_sequence<0, 0>>
891 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
892 // tuple<V1&&, V2&&>, std::index_sequence<0, 1>>
893 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
894 // tuple<V1&&, V2&&>, std::index_sequence<0, 2>>
895 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
896 // tuple<V1&&, V2&&>, std::index_sequence<1>>
897 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
898 // tuple<V1&&, V2&&>, std::index_sequence<1, 0>>
899 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
900 // tuple<V1&&, V2&&>, std::index_sequence<1, 1>>
901 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
902 // tuple<V1&&, V2&&>, std::index_sequence<1, 2>>
903 // The returned multi-dimensional vtable can be fast accessed by the visitor
904 // using index calculation.
905 template<typename _Array_type, typename _Index_seq>
906 struct __gen_vtable_impl;
908 // Defines the _S_apply() member that returns a _Multi_array populated
909 // with function pointers that perform the visitation expressions e(m)
910 // for each valid pack of indexes into the variant types _Variants.
912 // This partial specialization builds up the index sequences by recursively
913 // calling _S_apply() on the next specialization of __gen_vtable_impl.
914 // The base case of the recursion defines the actual function pointers.
915 template<typename _Result_type, typename _Visitor, size_t... __dimensions,
916 typename... _Variants, size_t... __indices>
917 struct __gen_vtable_impl<
918 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
919 std::index_sequence<__indices...>>
922 remove_reference_t<typename _Nth_type<sizeof...(__indices),
923 _Variants...>::type>;
925 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
928 static constexpr _Array_type
931 _Array_type __vtable{};
933 __vtable, make_index_sequence<variant_size_v<_Next>>());
937 template<size_t... __var_indices>
938 static constexpr void
939 _S_apply_all_alts(_Array_type& __vtable,
940 std::index_sequence<__var_indices...>)
942 if constexpr (_Extra_visit_slot_needed<_Result_type, _Next>::value)
943 (_S_apply_single_alt<true, __var_indices>(
944 __vtable._M_arr[__var_indices + 1],
945 &(__vtable._M_arr[0])), ...);
947 (_S_apply_single_alt<false, __var_indices>(
948 __vtable._M_arr[__var_indices]), ...);
951 template<bool __do_cookie, size_t __index, typename _Tp>
952 static constexpr void
953 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element = nullptr)
955 if constexpr (__do_cookie)
957 __element = __gen_vtable_impl<
959 std::index_sequence<__indices..., __index>>::_S_apply();
960 *__cookie_element = __gen_vtable_impl<
962 std::index_sequence<__indices..., variant_npos>>::_S_apply();
966 auto __tmp_element = __gen_vtable_impl<
967 remove_reference_t<decltype(__element)>,
968 std::index_sequence<__indices..., __index>>::_S_apply();
969 static_assert(is_same_v<_Tp, decltype(__tmp_element)>,
970 "std::visit requires the visitor to have the same "
971 "return type for all alternatives of a variant");
972 __element = __tmp_element;
977 // This partial specialization is the base case for the recursion.
978 // It populates a _Multi_array element with the address of a function
979 // that invokes the visitor with the alternatives specified by __indices.
980 template<typename _Result_type, typename _Visitor, typename... _Variants,
982 struct __gen_vtable_impl<
983 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
984 std::index_sequence<__indices...>>
987 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
989 template<size_t __index, typename _Variant>
990 static constexpr decltype(auto)
991 __element_by_index_or_cookie(_Variant&& __var) noexcept
993 if constexpr (__index != variant_npos)
994 return __variant::__get<__index>(std::forward<_Variant>(__var));
996 return __variant_cookie{};
999 static constexpr decltype(auto)
1000 __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1002 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1003 // For raw visitation using indices, pass the indices to the visitor
1004 // and discard the return value:
1005 std::__invoke(std::forward<_Visitor>(__visitor),
1006 __element_by_index_or_cookie<__indices>(
1007 std::forward<_Variants>(__vars))...,
1008 integral_constant<size_t, __indices>()...);
1009 else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1010 // For raw visitation without indices, and discard the return value:
1011 std::__invoke(std::forward<_Visitor>(__visitor),
1012 __element_by_index_or_cookie<__indices>(
1013 std::forward<_Variants>(__vars))...);
1014 else if constexpr (_Array_type::__result_is_deduced::value)
1015 // For the usual std::visit case deduce the return value:
1016 return std::__invoke(std::forward<_Visitor>(__visitor),
1017 __element_by_index_or_cookie<__indices>(
1018 std::forward<_Variants>(__vars))...);
1019 else // for std::visit<R> use INVOKE<R>
1020 return std::__invoke_r<_Result_type>(
1021 std::forward<_Visitor>(__visitor),
1022 __variant::__get<__indices>(std::forward<_Variants>(__vars))...);
1025 static constexpr auto
1028 if constexpr (_Array_type::__result_is_deduced::value)
1030 constexpr bool __visit_ret_type_mismatch =
1031 !is_same_v<typename _Result_type::type,
1032 decltype(__visit_invoke(std::declval<_Visitor>(),
1033 std::declval<_Variants>()...))>;
1034 if constexpr (__visit_ret_type_mismatch)
1036 struct __cannot_match {};
1037 return __cannot_match{};
1040 return _Array_type{&__visit_invoke};
1043 return _Array_type{&__visit_invoke};
1047 template<typename _Result_type, typename _Visitor, typename... _Variants>
1051 _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1052 variant_size_v<remove_reference_t<_Variants>>...>;
1054 static constexpr _Array_type _S_vtable
1055 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1058 template<size_t _Np, typename _Tp>
1059 struct _Base_dedup : public _Tp { };
1061 template<typename _Variant, typename __indices>
1062 struct _Variant_hash_base;
1064 template<typename... _Types, size_t... __indices>
1065 struct _Variant_hash_base<variant<_Types...>,
1066 std::index_sequence<__indices...>>
1067 : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
1069 // Equivalent to decltype(get<_Np>(as-variant(declval<_Variant>())))
1070 template<size_t _Np, typename _Variant,
1071 typename _AsV = decltype(__variant::__as(std::declval<_Variant>())),
1072 typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>>
1074 = conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1076 // Return type of std::visit.
1077 template<typename _Visitor, typename... _Variants>
1078 using __visit_result_t
1079 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1081 template<typename _Tp, typename... _Types>
1082 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1084 template <typename _Visitor, typename _Variant, size_t... _Idxs>
1085 constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>)
1087 return __same_types<
1088 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1092 template<size_t _Np, typename _Variant, typename... _Args>
1094 __construct_by_index(_Variant& __v, _Args&&... __args)
1096 auto&& __storage = __detail::__variant::__get<_Np>(__v);
1097 ::new ((void*)std::addressof(__storage))
1098 remove_reference_t<decltype(__storage)>
1099 (std::forward<_Args>(__args)...);
1100 // Construction didn't throw, so can set the new index now:
1104} // namespace __variant
1105} // namespace __detail
1107 template<typename _Tp, typename... _Types>
1109 holds_alternative(const variant<_Types...>& __v) noexcept
1111 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1112 "T must occur exactly once in alternatives");
1113 return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>;
1116 template<typename _Tp, typename... _Types>
1117 constexpr _Tp& get(variant<_Types...>& __v)
1119 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1120 "T must occur exactly once in alternatives");
1121 static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1122 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
1125 template<typename _Tp, typename... _Types>
1126 constexpr _Tp&& get(variant<_Types...>&& __v)
1128 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1129 "T must occur exactly once in alternatives");
1130 static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1131 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
1135 template<typename _Tp, typename... _Types>
1136 constexpr const _Tp& get(const variant<_Types...>& __v)
1138 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1139 "T must occur exactly once in alternatives");
1140 static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1141 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
1144 template<typename _Tp, typename... _Types>
1145 constexpr const _Tp&& get(const variant<_Types...>&& __v)
1147 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1148 "T must occur exactly once in alternatives");
1149 static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1150 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
1154 template<size_t _Np, typename... _Types>
1155 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1156 get_if(variant<_Types...>* __ptr) noexcept
1158 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1159 static_assert(_Np < sizeof...(_Types),
1160 "The index must be in [0, number of alternatives)");
1161 static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void");
1162 if (__ptr && __ptr->index() == _Np)
1163 return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
1167 template<size_t _Np, typename... _Types>
1169 add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
1170 get_if(const variant<_Types...>* __ptr) noexcept
1172 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1173 static_assert(_Np < sizeof...(_Types),
1174 "The index must be in [0, number of alternatives)");
1175 static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void");
1176 if (__ptr && __ptr->index() == _Np)
1177 return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
1181 template<typename _Tp, typename... _Types>
1182 constexpr add_pointer_t<_Tp>
1183 get_if(variant<_Types...>* __ptr) noexcept
1185 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1186 "T must occur exactly once in alternatives");
1187 static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1188 return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
1192 template<typename _Tp, typename... _Types>
1193 constexpr add_pointer_t<const _Tp>
1194 get_if(const variant<_Types...>* __ptr) noexcept
1196 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1197 "T must occur exactly once in alternatives");
1198 static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1199 return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
1203 struct monostate { };
1205#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1206 template<typename... _Types> \
1207 constexpr bool operator __OP(const variant<_Types...>& __lhs, \
1208 const variant<_Types...>& __rhs) \
1210 bool __ret = true; \
1211 __detail::__variant::__raw_idx_visit( \
1212 [&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \
1214 if constexpr (__rhs_index != variant_npos) \
1216 if (__lhs.index() == __rhs_index) \
1218 auto& __this_mem = std::get<__rhs_index>(__lhs); \
1219 __ret = __this_mem __OP __rhs_mem; \
1222 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
1225 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
1230 _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1231 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1232 _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1233 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1234 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1235 _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1237#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1239 constexpr bool operator==(monostate, monostate) noexcept { return true; }
1241#ifdef __cpp_lib_three_way_comparison
1242 template<typename... _Types>
1243 requires (three_way_comparable<_Types> && ...)
1245 common_comparison_category_t<compare_three_way_result_t<_Types>...>
1246 operator<=>(const variant<_Types...>& __v, const variant<_Types...>& __w)
1248 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1249 = strong_ordering::equal;
1251 __detail::__variant::__raw_idx_visit(
1252 [&__ret, &__v] (auto&& __w_mem, auto __w_index) mutable
1254 if constexpr (__w_index != variant_npos)
1256 if (__v.index() == __w_index)
1258 auto& __this_mem = std::get<__w_index>(__v);
1259 __ret = __this_mem <=> __w_mem;
1263 __ret = (__v.index() + 1) <=> (__w_index + 1);
1268 constexpr strong_ordering
1269 operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; }
1271 constexpr bool operator!=(monostate, monostate) noexcept { return false; }
1272 constexpr bool operator<(monostate, monostate) noexcept { return false; }
1273 constexpr bool operator>(monostate, monostate) noexcept { return false; }
1274 constexpr bool operator<=(monostate, monostate) noexcept { return true; }
1275 constexpr bool operator>=(monostate, monostate) noexcept { return true; }
1278 template<typename _Visitor, typename... _Variants>
1279 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1280 visit(_Visitor&&, _Variants&&...);
1282 template<typename... _Types>
1283 inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1284 && (is_swappable_v<_Types> && ...)>
1285 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1286 noexcept(noexcept(__lhs.swap(__rhs)))
1287 { __lhs.swap(__rhs); }
1289 template<typename... _Types>
1290 enable_if_t<!((is_move_constructible_v<_Types> && ...)
1291 && (is_swappable_v<_Types> && ...))>
1292 swap(variant<_Types...>&, variant<_Types...>&) = delete;
1294 class bad_variant_access : public exception
1297 bad_variant_access() noexcept { }
1299 const char* what() const noexcept override
1300 { return _M_reason; }
1303 bad_variant_access(const char* __reason) noexcept : _M_reason(__reason) { }
1305 // Must point to a string with static storage duration:
1306 const char* _M_reason = "bad variant access";
1308 friend void __throw_bad_variant_access(const char* __what);
1311 // Must only be called with a string literal
1313 __throw_bad_variant_access(const char* __what)
1314 { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1317 __throw_bad_variant_access(bool __valueless)
1319 if (__valueless) [[__unlikely__]]
1320 __throw_bad_variant_access("std::get: variant is valueless");
1322 __throw_bad_variant_access("std::get: wrong index for variant");
1325 template<typename... _Types>
1327 : private __detail::__variant::_Variant_base<_Types...>,
1328 private _Enable_default_constructor<
1329 __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1330 variant<_Types...>>,
1331 private _Enable_copy_move<
1332 __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1333 __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1334 __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1335 __detail::__variant::_Traits<_Types...>::_S_move_assign,
1339 template <typename... _UTypes, typename _Tp>
1340 friend decltype(auto) __variant_cast(_Tp&&);
1341 template<size_t _Np, typename _Variant, typename... _Args>
1343 __detail::__variant::__construct_by_index(_Variant& __v,
1346 static_assert(sizeof...(_Types) > 0,
1347 "variant must have at least one alternative");
1348 static_assert(!(std::is_reference_v<_Types> || ...),
1349 "variant must have no reference alternative");
1350 static_assert(!(std::is_void_v<_Types> || ...),
1351 "variant must have no void alternative");
1353 using _Base = __detail::__variant::_Variant_base<_Types...>;
1354 using _Default_ctor_enabler =
1355 _Enable_default_constructor<
1356 __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1357 variant<_Types...>>;
1359 template<typename _Tp>
1360 static constexpr bool __not_self
1361 = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1363 template<typename _Tp>
1364 static constexpr bool
1365 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1367 template<typename _Tp>
1368 static constexpr size_t __accepted_index
1369 = __detail::__variant::__accepted_index<_Tp, variant>::value;
1371 template<size_t _Np, typename = enable_if_t<(_Np < sizeof...(_Types))>>
1372 using __to_type = variant_alternative_t<_Np, variant>;
1374 template<typename _Tp, typename = enable_if_t<__not_self<_Tp>>>
1375 using __accepted_type = __to_type<__accepted_index<_Tp>>;
1377 template<typename _Tp>
1378 static constexpr size_t __index_of =
1379 __detail::__variant::__index_of_v<_Tp, _Types...>;
1381 using _Traits = __detail::__variant::_Traits<_Types...>;
1383 template<typename _Tp>
1384 struct __is_in_place_tag : false_type { };
1385 template<typename _Tp>
1386 struct __is_in_place_tag<in_place_type_t<_Tp>> : true_type { };
1387 template<size_t _Np>
1388 struct __is_in_place_tag<in_place_index_t<_Np>> : true_type { };
1390 template<typename _Tp>
1391 static constexpr bool __not_in_place_tag
1392 = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value;
1395 variant() = default;
1396 variant(const variant& __rhs) = default;
1397 variant(variant&&) = default;
1398 variant& operator=(const variant&) = default;
1399 variant& operator=(variant&&) = default;
1400 ~variant() = default;
1402 template<typename _Tp,
1403 typename = enable_if_t<sizeof...(_Types) != 0>,
1404 typename = enable_if_t<__not_in_place_tag<_Tp>>,
1405 typename _Tj = __accepted_type<_Tp&&>,
1406 typename = enable_if_t<__exactly_once<_Tj>
1407 && is_constructible_v<_Tj, _Tp>>>
1410 noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1411 : variant(in_place_index<__accepted_index<_Tp>>,
1412 std::forward<_Tp>(__t))
1415 template<typename _Tp, typename... _Args,
1416 typename = enable_if_t<__exactly_once<_Tp>
1417 && is_constructible_v<_Tp, _Args...>>>
1419 variant(in_place_type_t<_Tp>, _Args&&... __args)
1420 : variant(in_place_index<__index_of<_Tp>>,
1421 std::forward<_Args>(__args)...)
1424 template<typename _Tp, typename _Up, typename... _Args,
1425 typename = enable_if_t<__exactly_once<_Tp>
1426 && is_constructible_v<_Tp,
1427 initializer_list<_Up>&, _Args...>>>
1429 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1431 : variant(in_place_index<__index_of<_Tp>>, __il,
1432 std::forward<_Args>(__args)...)
1435 template<size_t _Np, typename... _Args,
1436 typename _Tp = __to_type<_Np>,
1437 typename = enable_if_t<is_constructible_v<_Tp, _Args...>>>
1439 variant(in_place_index_t<_Np>, _Args&&... __args)
1440 : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
1441 _Default_ctor_enabler(_Enable_default_constructor_tag{})
1444 template<size_t _Np, typename _Up, typename... _Args,
1445 typename _Tp = __to_type<_Np>,
1446 typename = enable_if_t<is_constructible_v<_Tp,
1447 initializer_list<_Up>&,
1450 variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1452 : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1453 _Default_ctor_enabler(_Enable_default_constructor_tag{})
1456 template<typename _Tp>
1457 enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1458 && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1459 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1461 operator=(_Tp&& __rhs)
1462 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1463 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1465 constexpr auto __index = __accepted_index<_Tp>;
1466 if (index() == __index)
1467 std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1470 using _Tj = __accepted_type<_Tp&&>;
1471 if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1472 || !is_nothrow_move_constructible_v<_Tj>)
1473 this->emplace<__index>(std::forward<_Tp>(__rhs));
1475 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1476 // 3585. converting assignment with immovable alternative
1477 this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs)));
1482 template<typename _Tp, typename... _Args>
1483 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1485 emplace(_Args&&... __args)
1487 constexpr size_t __index = __index_of<_Tp>;
1488 return this->emplace<__index>(std::forward<_Args>(__args)...);
1491 template<typename _Tp, typename _Up, typename... _Args>
1492 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1493 && __exactly_once<_Tp>,
1495 emplace(initializer_list<_Up> __il, _Args&&... __args)
1497 constexpr size_t __index = __index_of<_Tp>;
1498 return this->emplace<__index>(__il, std::forward<_Args>(__args)...);
1501 template<size_t _Np, typename... _Args>
1502 enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1504 variant_alternative_t<_Np, variant>&>
1505 emplace(_Args&&... __args)
1507 static_assert(_Np < sizeof...(_Types),
1508 "The index must be in [0, number of alternatives)");
1509 using type = variant_alternative_t<_Np, variant>;
1510 namespace __variant = std::__detail::__variant;
1511 // Provide the strong exception-safety guarantee when possible,
1512 // to avoid becoming valueless.
1513 if constexpr (is_nothrow_constructible_v<type, _Args...>)
1516 __variant::__construct_by_index<_Np>(*this,
1517 std::forward<_Args>(__args)...);
1519 else if constexpr (is_scalar_v<type>)
1521 // This might invoke a potentially-throwing conversion operator:
1522 const type __tmp(std::forward<_Args>(__args)...);
1523 // But these steps won't throw:
1525 __variant::__construct_by_index<_Np>(*this, __tmp);
1527 else if constexpr (__variant::_Never_valueless_alt<type>()
1528 && _Traits::_S_move_assign)
1530 // This construction might throw:
1531 variant __tmp(in_place_index<_Np>,
1532 std::forward<_Args>(__args)...);
1533 // But _Never_valueless_alt<type> means this won't:
1534 *this = std::move(__tmp);
1538 // This case only provides the basic exception-safety guarantee,
1539 // i.e. the variant can become valueless.
1541 __variant::__construct_by_index<_Np>(*this,
1542 std::forward<_Args>(__args)...);
1544 return std::get<_Np>(*this);
1547 template<size_t _Np, typename _Up, typename... _Args>
1548 enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1549 initializer_list<_Up>&, _Args...>,
1550 variant_alternative_t<_Np, variant>&>
1551 emplace(initializer_list<_Up> __il, _Args&&... __args)
1553 static_assert(_Np < sizeof...(_Types),
1554 "The index must be in [0, number of alternatives)");
1555 using type = variant_alternative_t<_Np, variant>;
1556 namespace __variant = std::__detail::__variant;
1557 // Provide the strong exception-safety guarantee when possible,
1558 // to avoid becoming valueless.
1559 if constexpr (is_nothrow_constructible_v<type,
1560 initializer_list<_Up>&,
1564 __variant::__construct_by_index<_Np>(*this, __il,
1565 std::forward<_Args>(__args)...);
1567 else if constexpr (__variant::_Never_valueless_alt<type>()
1568 && _Traits::_S_move_assign)
1570 // This construction might throw:
1571 variant __tmp(in_place_index<_Np>, __il,
1572 std::forward<_Args>(__args)...);
1573 // But _Never_valueless_alt<type> means this won't:
1574 *this = std::move(__tmp);
1578 // This case only provides the basic exception-safety guarantee,
1579 // i.e. the variant can become valueless.
1581 __variant::__construct_by_index<_Np>(*this, __il,
1582 std::forward<_Args>(__args)...);
1584 return std::get<_Np>(*this);
1587 constexpr bool valueless_by_exception() const noexcept
1588 { return !this->_M_valid(); }
1590 constexpr size_t index() const noexcept
1592 using __index_type = typename _Base::__index_type;
1593 if constexpr (__detail::__variant::__never_valueless<_Types...>())
1594 return this->_M_index;
1595 else if constexpr (sizeof...(_Types) <= __index_type(-1) / 2)
1596 return make_signed_t<__index_type>(this->_M_index);
1598 return size_t(__index_type(this->_M_index + 1)) - 1;
1602 swap(variant& __rhs)
1603 noexcept((__is_nothrow_swappable<_Types>::value && ...)
1604 && is_nothrow_move_constructible_v<variant>)
1606 __detail::__variant::__raw_idx_visit(
1607 [this, &__rhs](auto&& __rhs_mem, auto __rhs_index) mutable
1609 if constexpr (__rhs_index != variant_npos)
1611 if (this->index() == __rhs_index)
1614 std::get<__rhs_index>(*this);
1616 swap(__this_mem, __rhs_mem);
1620 if (!this->valueless_by_exception()) [[__likely__]]
1622 auto __tmp(std::move(__rhs_mem));
1623 __rhs = std::move(*this);
1624 this->_M_destructive_move(__rhs_index,
1629 this->_M_destructive_move(__rhs_index,
1630 std::move(__rhs_mem));
1637 if (!this->valueless_by_exception()) [[__likely__]]
1639 __rhs = std::move(*this);
1648#if defined(__clang__) && __clang_major__ <= 7
1650 using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852
1654 template<size_t _Np, typename _Vp>
1655 friend constexpr decltype(auto)
1656 __detail::__variant::__get(_Vp&& __v) noexcept;
1658#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1659 template<typename... _Tp> \
1660 friend constexpr bool \
1661 operator __OP(const variant<_Tp...>& __lhs, \
1662 const variant<_Tp...>& __rhs);
1664 _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1665 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1666 _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1667 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1668 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1669 _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1671#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1674 template<size_t _Np, typename... _Types>
1675 constexpr variant_alternative_t<_Np, variant<_Types...>>&
1676 get(variant<_Types...>& __v)
1678 static_assert(_Np < sizeof...(_Types),
1679 "The index must be in [0, number of alternatives)");
1680 if (__v.index() != _Np)
1681 __throw_bad_variant_access(__v.valueless_by_exception());
1682 return __detail::__variant::__get<_Np>(__v);
1685 template<size_t _Np, typename... _Types>
1686 constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1687 get(variant<_Types...>&& __v)
1689 static_assert(_Np < sizeof...(_Types),
1690 "The index must be in [0, number of alternatives)");
1691 if (__v.index() != _Np)
1692 __throw_bad_variant_access(__v.valueless_by_exception());
1693 return __detail::__variant::__get<_Np>(std::move(__v));
1696 template<size_t _Np, typename... _Types>
1697 constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1698 get(const variant<_Types...>& __v)
1700 static_assert(_Np < sizeof...(_Types),
1701 "The index must be in [0, number of alternatives)");
1702 if (__v.index() != _Np)
1703 __throw_bad_variant_access(__v.valueless_by_exception());
1704 return __detail::__variant::__get<_Np>(__v);
1707 template<size_t _Np, typename... _Types>
1708 constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1709 get(const variant<_Types...>&& __v)
1711 static_assert(_Np < sizeof...(_Types),
1712 "The index must be in [0, number of alternatives)");
1713 if (__v.index() != _Np)
1714 __throw_bad_variant_access(__v.valueless_by_exception());
1715 return __detail::__variant::__get<_Np>(std::move(__v));
1718 /// @cond undocumented
1719 template<typename _Result_type, typename _Visitor, typename... _Variants>
1720 constexpr decltype(auto)
1721 __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1723 constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1724 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1726 auto __func_ptr = __vtable._M_access(__variants.index()...);
1727 return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1728 std::forward<_Variants>(__variants)...);
1732 template<typename _Visitor, typename... _Variants>
1733 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1734 visit(_Visitor&& __visitor, _Variants&&... __variants)
1736 namespace __variant = std::__detail::__variant;
1738 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1739 __throw_bad_variant_access("std::visit: variant is valueless");
1742 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1744 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1746 if constexpr (sizeof...(_Variants) == 1)
1748 using _Vp = decltype(__variant::__as(std::declval<_Variants>()...));
1750 constexpr bool __visit_rettypes_match = __detail::__variant::
1751 __check_visitor_results<_Visitor, _Vp>(
1752 make_index_sequence<variant_size_v<remove_reference_t<_Vp>>>());
1753 if constexpr (!__visit_rettypes_match)
1755 static_assert(__visit_rettypes_match,
1756 "std::visit requires the visitor to have the same "
1757 "return type for all alternatives of a variant");
1761 return std::__do_visit<_Tag>(
1762 std::forward<_Visitor>(__visitor),
1763 static_cast<_Vp>(__variants)...);
1766 return std::__do_visit<_Tag>(
1767 std::forward<_Visitor>(__visitor),
1768 __variant::__as(std::forward<_Variants>(__variants))...);
1771#if __cplusplus > 201703L
1772 template<typename _Res, typename _Visitor, typename... _Variants>
1774 visit(_Visitor&& __visitor, _Variants&&... __variants)
1776 namespace __variant = std::__detail::__variant;
1778 if ((__variant::__as(__variants).valueless_by_exception() || ...))
1779 __throw_bad_variant_access("std::visit<R>: variant is valueless");
1781 return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor),
1782 __variant::__as(std::forward<_Variants>(__variants))...);
1786 /// @cond undocumented
1787 template<bool, typename... _Types>
1788 struct __variant_hash_call_base_impl
1791 operator()(const variant<_Types...>& __t) const
1792 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1795 __detail::__variant::__raw_visit(
1796 [&__t, &__ret](auto&& __t_mem) mutable
1798 using _Type = __remove_cvref_t<decltype(__t_mem)>;
1799 if constexpr (!is_same_v<_Type,
1800 __detail::__variant::__variant_cookie>)
1801 __ret = std::hash<size_t>{}(__t.index())
1802 + std::hash<_Type>{}(__t_mem);
1804 __ret = std::hash<size_t>{}(__t.index());
1810 template<typename... _Types>
1811 struct __variant_hash_call_base_impl<false, _Types...> {};
1813 template<typename... _Types>
1814 using __variant_hash_call_base =
1815 __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
1816 __enable_hash_call &&...), _Types...>;
1819 template<typename... _Types>
1820 struct hash<variant<_Types...>>
1821 : private __detail::__variant::_Variant_hash_base<
1822 variant<_Types...>, std::index_sequence_for<_Types...>>,
1823 public __variant_hash_call_base<_Types...>
1825 using result_type [[__deprecated__]] = size_t;
1826 using argument_type [[__deprecated__]] = variant<_Types...>;
1830 struct hash<monostate>
1832 using result_type [[__deprecated__]] = size_t;
1833 using argument_type [[__deprecated__]] = monostate;
1836 operator()(const monostate&) const noexcept
1838 constexpr size_t __magic_monostate_hash = -7777;
1839 return __magic_monostate_hash;
1843 template<typename... _Types>
1844 struct __is_fast_hash<hash<variant<_Types...>>>
1845 : bool_constant<(__is_fast_hash<_Types>::value && ...)>
1848_GLIBCXX_END_NAMESPACE_VERSION
1853#endif // _GLIBCXX_VARIANT