PR libstdc++/84769 qualify std::get and std::get_if to avoid ADL
[official-gcc.git] / libstdc++-v3 / include / std / variant
blob4aba131cb731ab45e6e0a0c5fdac20c036582d69
1 // <variant> -*- C++ -*-
3 // Copyright (C) 2016-2018 Free Software Foundation, Inc.
4 //
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)
9 // any later version.
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/>.
25 /** @file variant
26  *  This is the <variant> C++ Library header.
27  */
29 #ifndef _GLIBCXX_VARIANT
30 #define _GLIBCXX_VARIANT 1
32 #pragma GCC system_header
34 #if __cplusplus >= 201703L
36 #include <type_traits>
37 #include <utility>
38 #include <bits/enable_special_members.h>
39 #include <bits/functexcept.h>
40 #include <bits/move.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>
49 namespace std _GLIBCXX_VISIBILITY(default)
51 _GLIBCXX_BEGIN_NAMESPACE_VERSION
53 namespace __detail
55 namespace __variant
57   template<size_t _Np, typename... _Types>
58     struct _Nth_type;
60   template<size_t _Np, typename _First, typename... _Rest>
61     struct _Nth_type<_Np, _First, _Rest...>
62     : _Nth_type<_Np-1, _Rest...> { };
64   template<typename _First, typename... _Rest>
65     struct _Nth_type<0, _First, _Rest...>
66     { using type = _First; };
68 } // namespace __variant
69 } // namespace __detail
71 #define __cpp_lib_variant 201603
73   template<typename... _Types> class tuple;
74   template<typename... _Types> class variant;
75   template <typename> struct hash;
77   template<typename _Variant>
78     struct variant_size;
80   template<typename _Variant>
81     struct variant_size<const _Variant> : variant_size<_Variant> {};
83   template<typename _Variant>
84     struct variant_size<volatile _Variant> : variant_size<_Variant> {};
86   template<typename _Variant>
87     struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
89   template<typename... _Types>
90     struct variant_size<variant<_Types...>>
91     : std::integral_constant<size_t, sizeof...(_Types)> {};
93   template<typename _Variant>
94     inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
96   template<size_t _Np, typename _Variant>
97     struct variant_alternative;
99   template<size_t _Np, typename _First, typename... _Rest>
100     struct variant_alternative<_Np, variant<_First, _Rest...>>
101     : variant_alternative<_Np-1, variant<_Rest...>> {};
103   template<typename _First, typename... _Rest>
104     struct variant_alternative<0, variant<_First, _Rest...>>
105     { using type = _First; };
107   template<size_t _Np, typename _Variant>
108     using variant_alternative_t =
109       typename variant_alternative<_Np, _Variant>::type;
111   template<size_t _Np, typename _Variant>
112     struct variant_alternative<_Np, const _Variant>
113     { using type = add_const_t<variant_alternative_t<_Np, _Variant>>; };
115   template<size_t _Np, typename _Variant>
116     struct variant_alternative<_Np, volatile _Variant>
117     { using type = add_volatile_t<variant_alternative_t<_Np, _Variant>>; };
119   template<size_t _Np, typename _Variant>
120     struct variant_alternative<_Np, const volatile _Variant>
121     { using type = add_cv_t<variant_alternative_t<_Np, _Variant>>; };
123   inline constexpr size_t variant_npos = -1;
125   template<size_t _Np, typename... _Types>
126     constexpr variant_alternative_t<_Np, variant<_Types...>>&
127     get(variant<_Types...>&);
129   template<size_t _Np, typename... _Types>
130     constexpr variant_alternative_t<_Np, variant<_Types...>>&&
131     get(variant<_Types...>&&);
133   template<size_t _Np, typename... _Types>
134     constexpr variant_alternative_t<_Np, variant<_Types...>> const&
135     get(const variant<_Types...>&);
137   template<size_t _Np, typename... _Types>
138     constexpr variant_alternative_t<_Np, variant<_Types...>> const&&
139     get(const variant<_Types...>&&);
141 namespace __detail
143 namespace __variant
145   // Returns the first apparence of _Tp in _Types.
146   // Returns sizeof...(_Types) if _Tp is not in _Types.
147   template<typename _Tp, typename... _Types>
148     struct __index_of : std::integral_constant<size_t, 0> {};
150   template<typename _Tp, typename... _Types>
151     inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value;
153   template<typename _Tp, typename _First, typename... _Rest>
154     struct __index_of<_Tp, _First, _Rest...> :
155       std::integral_constant<size_t, is_same_v<_Tp, _First>
156         ? 0 : __index_of_v<_Tp, _Rest...> + 1> {};
158   // _Uninitialized<T> is guaranteed to be a literal type, even if T is not.
159   // We have to do this, because [basic.types]p10.5.3 (n4606) is not implemented
160   // yet. When it's implemented, _Uninitialized<T> can be changed to the alias
161   // to T, therefore equivalent to being removed entirely.
162   //
163   // Another reason we may not want to remove _Uninitialzied<T> may be that, we
164   // want _Uninitialized<T> to be trivially destructible, no matter whether T
165   // is; but we will see.
166   template<typename _Type, bool = std::is_literal_type_v<_Type>>
167     struct _Uninitialized;
169   template<typename _Type>
170     struct _Uninitialized<_Type, true>
171     {
172       template<typename... _Args>
173       constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args)
174       : _M_storage(std::forward<_Args>(__args)...)
175       { }
177       constexpr const _Type& _M_get() const &
178       { return _M_storage; }
180       constexpr _Type& _M_get() &
181       { return _M_storage; }
183       constexpr const _Type&& _M_get() const &&
184       { return std::move(_M_storage); }
186       constexpr _Type&& _M_get() &&
187       { return std::move(_M_storage); }
189       _Type _M_storage;
190     };
192   template<typename _Type>
193     struct _Uninitialized<_Type, false>
194     {
195       template<typename... _Args>
196       constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args)
197       { ::new (&_M_storage) _Type(std::forward<_Args>(__args)...); }
199       const _Type& _M_get() const &
200       { return *_M_storage._M_ptr(); }
202       _Type& _M_get() &
203       { return *_M_storage._M_ptr(); }
205       const _Type&& _M_get() const &&
206       { return std::move(*_M_storage._M_ptr()); }
208       _Type&& _M_get() &&
209       { return std::move(*_M_storage._M_ptr()); }
211       __gnu_cxx::__aligned_membuf<_Type> _M_storage;
212     };
214   template<typename _Ref>
215     _Ref __ref_cast(void* __ptr)
216     {
217       return static_cast<_Ref>(*static_cast<remove_reference_t<_Ref>*>(__ptr));
218     }
220   template<typename _Union>
221     constexpr decltype(auto) __get(in_place_index_t<0>, _Union&& __u)
222     { return std::forward<_Union>(__u)._M_first._M_get(); }
224   template<size_t _Np, typename _Union>
225     constexpr decltype(auto) __get(in_place_index_t<_Np>, _Union&& __u)
226     { return __get(in_place_index<_Np-1>, std::forward<_Union>(__u)._M_rest); }
228   // Returns the typed storage for __v.
229   template<size_t _Np, typename _Variant>
230     constexpr decltype(auto) __get(_Variant&& __v)
231     {
232       return __get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u);
233     }
235   // Various functions as "vtable" entries, where those vtables are used by
236   // polymorphic operations.
237   template<typename _Lhs, typename _Rhs>
238     void
239     __erased_ctor(void* __lhs, void* __rhs)
240     {
241       using _Type = remove_reference_t<_Lhs>;
242       ::new (__lhs) _Type(__variant::__ref_cast<_Rhs>(__rhs));
243     }
245   template<typename _Variant, size_t _Np>
246     void
247     __erased_dtor(_Variant&& __v)
248     { std::_Destroy(std::__addressof(__get<_Np>(__v))); }
250   template<typename _Lhs, typename _Rhs>
251     void
252     __erased_assign(void* __lhs, void* __rhs)
253     {
254       __variant::__ref_cast<_Lhs>(__lhs) = __variant::__ref_cast<_Rhs>(__rhs);
255     }
257   template<typename _Lhs, typename _Rhs>
258     void
259     __erased_swap(void* __lhs, void* __rhs)
260     {
261       using std::swap;
262       swap(__variant::__ref_cast<_Lhs>(__lhs),
263            __variant::__ref_cast<_Rhs>(__rhs));
264     }
266 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
267   template<typename _Variant, size_t _Np> \
268     constexpr bool \
269     __erased_##__NAME(const _Variant& __lhs, const _Variant& __rhs) \
270     { \
271       return __get<_Np>(std::forward<_Variant>(__lhs)) \
272           __OP __get<_Np>(std::forward<_Variant>(__rhs)); \
273     }
275   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
276   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
277   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
278   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
279   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
280   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
282 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
284   template<typename _Tp>
285     size_t
286     __erased_hash(void* __t)
287     {
288       return std::hash<remove_cv_t<remove_reference_t<_Tp>>>{}(
289           __variant::__ref_cast<_Tp>(__t));
290     }
292   template<typename... _Types>
293     struct _Traits
294     {
295       static constexpr bool _S_default_ctor =
296           is_default_constructible_v<typename _Nth_type<0, _Types...>::type>;
297       static constexpr bool _S_copy_ctor =
298           (is_copy_constructible_v<_Types> && ...);
299       static constexpr bool _S_move_ctor =
300           (is_move_constructible_v<_Types> && ...);
301       static constexpr bool _S_copy_assign =
302           _S_copy_ctor && _S_move_ctor
303           && (is_copy_assignable_v<_Types> && ...);
304       static constexpr bool _S_move_assign =
305           _S_move_ctor
306           && (is_move_assignable_v<_Types> && ...);
308       static constexpr bool _S_trivial_dtor =
309           (is_trivially_destructible_v<_Types> && ...);
310       static constexpr bool _S_trivial_copy_ctor =
311           (is_trivially_copy_constructible_v<_Types> && ...);
312       static constexpr bool _S_trivial_move_ctor =
313           (is_trivially_move_constructible_v<_Types> && ...);
314       static constexpr bool _S_trivial_copy_assign =
315           _S_trivial_dtor && (is_trivially_copy_assignable_v<_Types> && ...);
316       static constexpr bool _S_trivial_move_assign =
317           _S_trivial_dtor && (is_trivially_move_assignable_v<_Types> && ...);
319       // The following nothrow traits are for non-trivial SMFs. Trivial SMFs
320       // are always nothrow.
321       static constexpr bool _S_nothrow_default_ctor =
322           is_nothrow_default_constructible_v<
323               typename _Nth_type<0, _Types...>::type>;
324       static constexpr bool _S_nothrow_copy_ctor = false;
325       static constexpr bool _S_nothrow_move_ctor =
326           (is_nothrow_move_constructible_v<_Types> && ...);
327       static constexpr bool _S_nothrow_copy_assign = false;
328       static constexpr bool _S_nothrow_move_assign =
329           _S_nothrow_move_ctor && (is_nothrow_move_assignable_v<_Types> && ...);
330     };
332   // Defines members and ctors.
333   template<typename... _Types>
334     union _Variadic_union { };
336   template<typename _First, typename... _Rest>
337     union _Variadic_union<_First, _Rest...>
338     {
339       constexpr _Variadic_union() : _M_rest() { }
341       template<typename... _Args>
342         constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args)
343         : _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
344         { }
346       template<size_t _Np, typename... _Args>
347         constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
348         : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
349         { }
351       _Uninitialized<_First> _M_first;
352       _Variadic_union<_Rest...> _M_rest;
353     };
355   // Defines index and the dtor, possibly trivial.
356   template<bool __trivially_destructible, typename... _Types>
357     struct _Variant_storage;
359   template <typename... _Types>
360   using __select_index =
361     typename __select_int::_Select_int_base<sizeof...(_Types)+1,
362                                             unsigned char,
363                                             unsigned short>
364     ::type::value_type;
366   template<typename... _Types>
367     struct _Variant_storage<false, _Types...>
368     {
369       template<size_t... __indices>
370         static constexpr void (*_S_vtable[])(const _Variant_storage&) =
371             { &__erased_dtor<const _Variant_storage&, __indices>... };
373       constexpr _Variant_storage() : _M_index(variant_npos) { }
375       template<size_t _Np, typename... _Args>
376         constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
377         : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
378         _M_index(_Np)
379         { }
381       template<size_t... __indices>
382         constexpr void _M_reset_impl(std::index_sequence<__indices...>)
383         {
384           if (_M_index != __index_type(variant_npos))
385             _S_vtable<__indices...>[_M_index](*this);
386         }
388       void _M_reset()
389       {
390         _M_reset_impl(std::index_sequence_for<_Types...>{});
391         _M_index = variant_npos;
392       }
394       ~_Variant_storage()
395       { _M_reset(); }
397       void*
398       _M_storage() const
399       {
400         return const_cast<void*>(static_cast<const void*>(
401             std::addressof(_M_u)));
402       }
404       constexpr bool
405       _M_valid() const noexcept
406       {
407         return this->_M_index != __index_type(variant_npos);
408       }
410       _Variadic_union<_Types...> _M_u;
411       using __index_type = __select_index<_Types...>;
412       __index_type _M_index;
413     };
415   template<typename... _Types>
416     struct _Variant_storage<true, _Types...>
417     {
418       constexpr _Variant_storage() : _M_index(variant_npos) { }
420       template<size_t _Np, typename... _Args>
421         constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
422         : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
423         _M_index(_Np)
424         { }
426       void _M_reset()
427       { _M_index = variant_npos; }
429       void*
430       _M_storage() const
431       {
432         return const_cast<void*>(static_cast<const void*>(
433             std::addressof(_M_u)));
434       }
436       constexpr bool
437       _M_valid() const noexcept
438       {
439         return this->_M_index != __index_type(variant_npos);
440       }
442       _Variadic_union<_Types...> _M_u;
443       using __index_type = __select_index<_Types...>;
444       __index_type _M_index;
445     };
447   template<typename... _Types>
448     using _Variant_storage_alias =
449         _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
451   // The following are (Copy|Move) (ctor|assign) layers for forwarding
452   // triviality and handling non-trivial SMF behaviors.
454   template<bool, typename... _Types>
455     struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
456     {
457       using _Base = _Variant_storage_alias<_Types...>;
458       using _Base::_Base;
460       _Copy_ctor_base(const _Copy_ctor_base& __rhs)
461           noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
462       {
463         if (__rhs._M_valid())
464           {
465             static constexpr void (*_S_vtable[])(void*, void*) =
466               { &__erased_ctor<_Types&, const _Types&>... };
467             _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
468             this->_M_index = __rhs._M_index;
469           }
470       }
472       _Copy_ctor_base(_Copy_ctor_base&&) = default;
473       _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default;
474       _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default;
475     };
477   template<typename... _Types>
478     struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
479     {
480       using _Base = _Variant_storage_alias<_Types...>;
481       using _Base::_Base;
482     };
484   template<typename... _Types>
485     using _Copy_ctor_alias =
486         _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
488   template<bool, typename... _Types>
489     struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
490     {
491       using _Base = _Copy_ctor_alias<_Types...>;
492       using _Base::_Base;
494       _Move_ctor_base(_Move_ctor_base&& __rhs)
495           noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
496       {
497         if (__rhs._M_valid())
498           {
499             static constexpr void (*_S_vtable[])(void*, void*) =
500               { &__erased_ctor<_Types&, _Types&&>... };
501             _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
502             this->_M_index = __rhs._M_index;
503           }
504       }
506       _Move_ctor_base(const _Move_ctor_base&) = default;
507       _Move_ctor_base& operator=(const _Move_ctor_base&) = default;
508       _Move_ctor_base& operator=(_Move_ctor_base&&) = default;
509     };
511   template<typename... _Types>
512     struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
513     {
514       using _Base = _Copy_ctor_alias<_Types...>;
515       using _Base::_Base;
516     };
518   template<typename... _Types>
519     using _Move_ctor_alias =
520         _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
522   template<bool, typename... _Types>
523     struct _Copy_assign_base : _Move_ctor_alias<_Types...>
524     {
525       using _Base = _Move_ctor_alias<_Types...>;
526       using _Base::_Base;
528       _Copy_assign_base&
529       operator=(const _Copy_assign_base& __rhs)
530           noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
531       {
532         if (this->_M_index == __rhs._M_index)
533           {
534             if (__rhs._M_valid())
535               {
536                 static constexpr void (*_S_vtable[])(void*, void*) =
537                   { &__erased_assign<_Types&, const _Types&>... };
538                 _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
539               }
540           }
541         else
542           {
543             _Copy_assign_base __tmp(__rhs);
544             this->~_Copy_assign_base();
545             __try
546               {
547                 ::new (this) _Copy_assign_base(std::move(__tmp));
548               }
549             __catch (...)
550               {
551                 this->_M_index = variant_npos;
552                 __throw_exception_again;
553               }
554           }
555         __glibcxx_assert(this->_M_index == __rhs._M_index);
556         return *this;
557       }
559       _Copy_assign_base(const _Copy_assign_base&) = default;
560       _Copy_assign_base(_Copy_assign_base&&) = default;
561       _Copy_assign_base& operator=(_Copy_assign_base&&) = default;
562     };
564   template<typename... _Types>
565     struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
566     {
567       using _Base = _Move_ctor_alias<_Types...>;
568       using _Base::_Base;
569     };
571   template<typename... _Types>
572     using _Copy_assign_alias =
573         _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign,
574                           _Types...>;
576   template<bool, typename... _Types>
577     struct _Move_assign_base : _Copy_assign_alias<_Types...>
578     {
579       using _Base = _Copy_assign_alias<_Types...>;
580       using _Base::_Base;
582       void _M_destructive_move(_Move_assign_base&& __rhs)
583       {
584         this->~_Move_assign_base();
585         __try
586           {
587             ::new (this) _Move_assign_base(std::move(__rhs));
588           }
589         __catch (...)
590           {
591             this->_M_index = variant_npos;
592             __throw_exception_again;
593           }
594       }
596       _Move_assign_base&
597       operator=(_Move_assign_base&& __rhs)
598           noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
599       {
600         if (this->_M_index == __rhs._M_index)
601           {
602             if (__rhs._M_valid())
603               {
604                 static constexpr void (*_S_vtable[])(void*, void*) =
605                   { &__erased_assign<_Types&, const _Types&>... };
606                 _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
607               }
608           }
609         else
610           {
611             _Move_assign_base __tmp(__rhs);
612             this->~_Move_assign_base();
613             __try
614               {
615                 ::new (this) _Move_assign_base(std::move(__tmp));
616               }
617             __catch (...)
618               {
619                 this->_M_index = variant_npos;
620                 __throw_exception_again;
621               }
622           }
623         __glibcxx_assert(this->_M_index == __rhs._M_index);
624         return *this;
625       }
627       _Move_assign_base(const _Move_assign_base&) = default;
628       _Move_assign_base(_Move_assign_base&&) = default;
629       _Move_assign_base& operator=(const _Move_assign_base&) = default;
630     };
632   template<typename... _Types>
633     struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
634     {
635       using _Base = _Copy_assign_alias<_Types...>;
636       using _Base::_Base;
637     };
639   template<typename... _Types>
640     using _Move_assign_alias =
641         _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign,
642                           _Types...>;
644   template<typename... _Types>
645     struct _Variant_base : _Move_assign_alias<_Types...>
646     {
647       using _Base = _Move_assign_alias<_Types...>;
649       constexpr
650       _Variant_base()
651           noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
652       : _Variant_base(in_place_index<0>) { }
654       template<size_t _Np, typename... _Args>
655         constexpr explicit
656         _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
657         : _Base(__i, std::forward<_Args>(__args)...)
658         { }
660       _Variant_base(const _Variant_base&) = default;
661       _Variant_base(_Variant_base&&) = default;
662       _Variant_base& operator=(const _Variant_base&) = default;
663       _Variant_base& operator=(_Variant_base&&) = default;
664     };
666   // For how many times does _Tp appear in _Tuple?
667   template<typename _Tp, typename _Tuple>
668     struct __tuple_count;
670   template<typename _Tp, typename _Tuple>
671     inline constexpr size_t __tuple_count_v =
672       __tuple_count<_Tp, _Tuple>::value;
674   template<typename _Tp, typename... _Types>
675     struct __tuple_count<_Tp, tuple<_Types...>>
676     : integral_constant<size_t, 0> { };
678   template<typename _Tp, typename _First, typename... _Rest>
679     struct __tuple_count<_Tp, tuple<_First, _Rest...>>
680     : integral_constant<
681         size_t,
682         __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
684   // TODO: Reuse this in <tuple> ?
685   template<typename _Tp, typename... _Types>
686     inline constexpr bool __exactly_once =
687       __tuple_count_v<_Tp, tuple<_Types...>> == 1;
689   // Takes _Types and create an overloaded _S_fun for each type.
690   // If a type appears more than once in _Types, create only one overload.
691   template<typename... _Types>
692     struct __overload_set
693     { static void _S_fun(); };
695   template<typename _First, typename... _Rest>
696     struct __overload_set<_First, _Rest...> : __overload_set<_Rest...>
697     {
698       using __overload_set<_Rest...>::_S_fun;
699       static integral_constant<size_t, sizeof...(_Rest)> _S_fun(_First);
700     };
702   template<typename... _Rest>
703     struct __overload_set<void, _Rest...> : __overload_set<_Rest...>
704     {
705       using __overload_set<_Rest...>::_S_fun;
706     };
708   // Helper for variant(_Tp&&) and variant::operator=(_Tp&&).
709   // __accepted_index maps the arbitrary _Tp to an alternative type in _Variant.
710   template<typename _Tp, typename _Variant, typename = void>
711     struct __accepted_index
712     { static constexpr size_t value = variant_npos; };
714   template<typename _Tp, typename... _Types>
715     struct __accepted_index<
716       _Tp, variant<_Types...>,
717       decltype(__overload_set<_Types...>::_S_fun(std::declval<_Tp>()),
718                std::declval<void>())>
719     {
720       static constexpr size_t value = sizeof...(_Types) - 1
721         - decltype(__overload_set<_Types...>::
722                    _S_fun(std::declval<_Tp>()))::value;
723     };
725   // Returns the raw storage for __v.
726   template<typename _Variant>
727     void* __get_storage(_Variant&& __v)
728     { return __v._M_storage(); }
730   // Used for storing multi-dimensional vtable.
731   template<typename _Tp, size_t... _Dimensions>
732     struct _Multi_array
733     {
734       constexpr const _Tp&
735       _M_access() const
736       { return _M_data; }
738       _Tp _M_data;
739     };
741   template<typename _Tp, size_t __first, size_t... __rest>
742     struct _Multi_array<_Tp, __first, __rest...>
743     {
744       template<typename... _Args>
745         constexpr const _Tp&
746         _M_access(size_t __first_index, _Args... __rest_indices) const
747         { return _M_arr[__first_index]._M_access(__rest_indices...); }
749       _Multi_array<_Tp, __rest...> _M_arr[__first];
750     };
752   // Creates a multi-dimensional vtable recursively.
753   //
754   // For example,
755   // visit([](auto, auto){},
756   //       variant<int, char>(),  // typedef'ed as V1
757   //       variant<float, double, long double>())  // typedef'ed as V2
758   // will trigger instantiations of:
759   // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>,
760   //                   tuple<V1&&, V2&&>, std::index_sequence<>>
761   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
762   //                     tuple<V1&&, V2&&>, std::index_sequence<0>>
763   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
764   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 0>>
765   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
766   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 1>>
767   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
768   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 2>>
769   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
770   //                     tuple<V1&&, V2&&>, std::index_sequence<1>>
771   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
772   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 0>>
773   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
774   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 1>>
775   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
776   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 2>>
777   // The returned multi-dimensional vtable can be fast accessed by the visitor
778   // using index calculation.
779   template<typename _Array_type, typename _Variant_tuple, typename _Index_seq>
780     struct __gen_vtable_impl;
782   template<typename _Result_type, typename _Visitor, size_t... __dimensions,
783            typename... _Variants, size_t... __indices>
784     struct __gen_vtable_impl<
785         _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
786         tuple<_Variants...>, std::index_sequence<__indices...>>
787     {
788       using _Next =
789           remove_reference_t<typename _Nth_type<sizeof...(__indices),
790                              _Variants...>::type>;
791       using _Array_type =
792           _Multi_array<_Result_type (*)(_Visitor, _Variants...),
793                        __dimensions...>;
795       static constexpr _Array_type
796       _S_apply()
797       {
798         _Array_type __vtable{};
799         _S_apply_all_alts(
800           __vtable, make_index_sequence<variant_size_v<_Next>>());
801         return __vtable;
802       }
804       template<size_t... __var_indices>
805         static constexpr void
806         _S_apply_all_alts(_Array_type& __vtable,
807                           std::index_sequence<__var_indices...>)
808         {
809           (_S_apply_single_alt<__var_indices>(
810              __vtable._M_arr[__var_indices]), ...);
811         }
813       template<size_t __index, typename _Tp>
814         static constexpr void
815         _S_apply_single_alt(_Tp& __element)
816         {
817           using _Alternative = variant_alternative_t<__index, _Next>;
818           __element = __gen_vtable_impl<
819             remove_reference_t<
820               decltype(__element)>, tuple<_Variants...>,
821               std::index_sequence<__indices..., __index>>::_S_apply();
822         }
823     };
825   template<typename _Result_type, typename _Visitor, typename... _Variants,
826            size_t... __indices>
827     struct __gen_vtable_impl<
828       _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
829                    tuple<_Variants...>, std::index_sequence<__indices...>>
830     {
831       using _Array_type =
832           _Multi_array<_Result_type (*)(_Visitor&&, _Variants...)>;
834       decltype(auto)
835       static constexpr __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
836       {
837         return __invoke(std::forward<_Visitor>(__visitor),
838                         std::get<__indices>(
839                             std::forward<_Variants>(__vars))...);
840       }
842       static constexpr auto
843       _S_apply()
844       { return _Array_type{&__visit_invoke}; }
845     };
847   template<typename _Result_type, typename _Visitor, typename... _Variants>
848     struct __gen_vtable
849     {
850       using _Func_ptr = _Result_type (*)(_Visitor&&, _Variants...);
851       using _Array_type =
852           _Multi_array<_Func_ptr,
853                        variant_size_v<remove_reference_t<_Variants>>...>;
855       static constexpr _Array_type
856       _S_apply()
857       {
858         return __gen_vtable_impl<_Array_type, tuple<_Variants...>,
859                                  std::index_sequence<>>::_S_apply();
860       }
862       static constexpr auto _S_vtable = _S_apply();
863     };
865   template<size_t _Np, typename _Tp>
866     struct _Base_dedup : public _Tp { };
868   template<typename _Variant, typename __indices>
869     struct _Variant_hash_base;
871   template<typename... _Types, size_t... __indices>
872     struct _Variant_hash_base<variant<_Types...>,
873                               std::index_sequence<__indices...>>
874     : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
876 } // namespace __variant
877 } // namespace __detail
879   template<typename _Tp, typename... _Types>
880     inline constexpr bool holds_alternative(const variant<_Types...>& __v)
881     noexcept
882     {
883       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
884                     "T should occur for exactly once in alternatives");
885       return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>;
886     }
888   template<typename _Tp, typename... _Types>
889     constexpr inline _Tp& get(variant<_Types...>& __v)
890     {
891       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
892                     "T should occur for exactly once in alternatives");
893       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
894       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
895     }
897   template<typename _Tp, typename... _Types>
898     constexpr inline _Tp&& get(variant<_Types...>&& __v)
899     {
900       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
901                     "T should occur for exactly once in alternatives");
902       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
903       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
904         std::move(__v));
905     }
907   template<typename _Tp, typename... _Types>
908     constexpr inline const _Tp& get(const variant<_Types...>& __v)
909     {
910       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
911                     "T should occur for exactly once in alternatives");
912       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
913       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
914     }
916   template<typename _Tp, typename... _Types>
917     constexpr inline const _Tp&& get(const variant<_Types...>&& __v)
918     {
919       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
920                     "T should occur for exactly once in alternatives");
921       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
922       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
923         std::move(__v));
924     }
926   template<size_t _Np, typename... _Types>
927     constexpr inline
928     add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
929     get_if(variant<_Types...>* __ptr) noexcept
930     {
931       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
932       static_assert(_Np < sizeof...(_Types),
933                     "The index should be in [0, number of alternatives)");
934       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
935       if (__ptr && __ptr->index() == _Np)
936         return &__detail::__variant::__get<_Np>(*__ptr);
937       return nullptr;
938     }
940   template<size_t _Np, typename... _Types>
941     constexpr inline
942     add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
943     get_if(const variant<_Types...>* __ptr) noexcept
944     {
945       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
946       static_assert(_Np < sizeof...(_Types),
947                     "The index should be in [0, number of alternatives)");
948       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
949       if (__ptr && __ptr->index() == _Np)
950         return &__detail::__variant::__get<_Np>(*__ptr);
951       return nullptr;
952     }
954   template<typename _Tp, typename... _Types>
955     constexpr inline add_pointer_t<_Tp>
956     get_if(variant<_Types...>* __ptr) noexcept
957     {
958       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
959                     "T should occur for exactly once in alternatives");
960       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
961       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
962           __ptr);
963     }
965   template<typename _Tp, typename... _Types>
966     constexpr inline add_pointer_t<const _Tp>
967     get_if(const variant<_Types...>* __ptr)
968     noexcept
969     {
970       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
971                     "T should occur for exactly once in alternatives");
972       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
973       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
974           __ptr);
975     }
977   struct monostate { };
979 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
980   template<typename... _Types> \
981     constexpr bool operator __OP(const variant<_Types...>& __lhs, \
982                                  const variant<_Types...>& __rhs) \
983     { \
984       return __lhs._M_##__NAME(__rhs, std::index_sequence_for<_Types...>{}); \
985     } \
987   constexpr bool operator __OP(monostate, monostate) noexcept \
988   { return 0 __OP 0; }
990   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
991   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
992   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
993   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
994   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
995   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
997 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
999   template<typename _Visitor, typename... _Variants>
1000     constexpr decltype(auto) visit(_Visitor&&, _Variants&&...);
1002   template<typename... _Types>
1003     inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1004                         && (is_swappable_v<_Types> && ...)>
1005     swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1006     noexcept(noexcept(__lhs.swap(__rhs)))
1007     { __lhs.swap(__rhs); }
1009   template<typename... _Types>
1010     enable_if_t<!((is_move_constructible_v<_Types> && ...)
1011                    && (is_swappable_v<_Types> && ...))>
1012     swap(variant<_Types...>&, variant<_Types...>&) = delete;
1014   class bad_variant_access : public exception
1015   {
1016   public:
1017     bad_variant_access() noexcept : _M_reason("Unknown reason") { }
1018     const char* what() const noexcept override
1019     { return _M_reason; }
1021   private:
1022     bad_variant_access(const char* __reason) : _M_reason(__reason) { }
1024     const char* _M_reason;
1026     friend void __throw_bad_variant_access(const char* __what);
1027   };
1029   inline void
1030   __throw_bad_variant_access(const char* __what)
1031   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1033   template<typename... _Types>
1034     class variant
1035     : private __detail::__variant::_Variant_base<_Types...>,
1036       private _Enable_default_constructor<
1037         __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1038           variant<_Types...>>,
1039       private _Enable_copy_move<
1040         __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1041         __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1042         __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1043         __detail::__variant::_Traits<_Types...>::_S_move_assign,
1044         variant<_Types...>>
1045     {
1046     private:
1047       static_assert(sizeof...(_Types) > 0,
1048                     "variant must have at least one alternative");
1049       static_assert(!(std::is_reference_v<_Types> || ...),
1050                     "variant must have no reference alternative");
1051       static_assert(!(std::is_void_v<_Types> || ...),
1052                     "variant must have no void alternative");
1054       using _Base = __detail::__variant::_Variant_base<_Types...>;
1055       using _Default_ctor_enabler =
1056         _Enable_default_constructor<
1057           __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1058             variant<_Types...>>;
1060       template<typename _Tp>
1061         static constexpr bool
1062         __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1064       template<typename _Tp>
1065         static constexpr size_t __accepted_index =
1066           __detail::__variant::__accepted_index<_Tp&&, variant>::value;
1068       template<size_t _Np, bool = _Np < sizeof...(_Types)>
1069         struct __to_type_impl;
1071       template<size_t _Np>
1072         struct __to_type_impl<_Np, true>
1073         { using type = variant_alternative_t<_Np, variant>; };
1075       template<size_t _Np>
1076         using __to_type = typename __to_type_impl<_Np>::type;
1078       template<typename _Tp>
1079         using __accepted_type = __to_type<__accepted_index<_Tp>>;
1081       template<typename _Tp>
1082         static constexpr size_t __index_of =
1083           __detail::__variant::__index_of_v<_Tp, _Types...>;
1085       using _Traits = __detail::__variant::_Traits<_Types...>;
1087     public:
1088       variant() = default;
1089       variant(const variant& __rhs) = default;
1090       variant(variant&&) = default;
1091       variant& operator=(const variant&) = default;
1092       variant& operator=(variant&&) = default;
1093       ~variant() = default;
1095       template<typename _Tp,
1096                typename = enable_if_t<!is_same_v<decay_t<_Tp>, variant>>,
1097                typename = enable_if_t<(sizeof...(_Types)>0)>,
1098                typename = enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1099                           && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>>>
1100         constexpr
1101         variant(_Tp&& __t)
1102         noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1103         : variant(in_place_index<__accepted_index<_Tp&&>>,
1104                   std::forward<_Tp>(__t))
1105         { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
1107       template<typename _Tp, typename... _Args,
1108                typename = enable_if_t<__exactly_once<_Tp>
1109                           && is_constructible_v<_Tp, _Args&&...>>>
1110         constexpr explicit
1111         variant(in_place_type_t<_Tp>, _Args&&... __args)
1112         : variant(in_place_index<__index_of<_Tp>>,
1113                   std::forward<_Args>(__args)...)
1114         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1116       template<typename _Tp, typename _Up, typename... _Args,
1117                typename = enable_if_t<__exactly_once<_Tp>
1118                           && is_constructible_v<
1119                             _Tp, initializer_list<_Up>&, _Args&&...>>>
1120         constexpr explicit
1121         variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1122                 _Args&&... __args)
1123         : variant(in_place_index<__index_of<_Tp>>, __il,
1124                   std::forward<_Args>(__args)...)
1125         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1127       template<size_t _Np, typename... _Args,
1128                typename = enable_if_t<
1129                  is_constructible_v<__to_type<_Np>, _Args&&...>>>
1130         constexpr explicit
1131         variant(in_place_index_t<_Np>, _Args&&... __args)
1132         : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
1133         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1134         { __glibcxx_assert(index() == _Np); }
1136       template<size_t _Np, typename _Up, typename... _Args,
1137                typename = enable_if_t<is_constructible_v<__to_type<_Np>,
1138                                       initializer_list<_Up>&, _Args&&...>>>
1139         constexpr explicit
1140         variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1141                 _Args&&... __args)
1142         : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1143         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1144         { __glibcxx_assert(index() == _Np); }
1146       template<typename _Tp>
1147         enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1148                     && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>
1149                     && is_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1150                     && !is_same_v<decay_t<_Tp>, variant>, variant&>
1151         operator=(_Tp&& __rhs)
1152         noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1153                  && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1154         {
1155           constexpr auto __index = __accepted_index<_Tp&&>;
1156           if (index() == __index)
1157             std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1158           else
1159             this->emplace<__index>(std::forward<_Tp>(__rhs));
1160           __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this));
1161           return *this;
1162         }
1164       template<typename _Tp, typename... _Args>
1165         enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1166                     _Tp&>
1167         emplace(_Args&&... __args)
1168         {
1169           auto& ret =
1170             this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...);
1171           __glibcxx_assert(holds_alternative<_Tp>(*this));
1172           return ret;
1173         }
1175       template<typename _Tp, typename _Up, typename... _Args>
1176         enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1177                     && __exactly_once<_Tp>,
1178                     _Tp&>
1179         emplace(initializer_list<_Up> __il, _Args&&... __args)
1180         {
1181           auto& ret =
1182             this->emplace<__index_of<_Tp>>(__il,
1183                                            std::forward<_Args>(__args)...);
1184           __glibcxx_assert(holds_alternative<_Tp>(*this));
1185           return ret;
1186         }
1188       template<size_t _Np, typename... _Args>
1189         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1190                                        _Args...>,
1191                     variant_alternative_t<_Np, variant>&>
1192         emplace(_Args&&... __args)
1193         {
1194           static_assert(_Np < sizeof...(_Types),
1195                         "The index should be in [0, number of alternatives)");
1196           this->~variant();
1197           __try
1198             {
1199               ::new (this) variant(in_place_index<_Np>,
1200                                    std::forward<_Args>(__args)...);
1201             }
1202           __catch (...)
1203             {
1204               this->_M_index = variant_npos;
1205               __throw_exception_again;
1206             }
1207           __glibcxx_assert(index() == _Np);
1208           return std::get<_Np>(*this);
1209         }
1211       template<size_t _Np, typename _Up, typename... _Args>
1212         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1213                                        initializer_list<_Up>&, _Args...>,
1214                     variant_alternative_t<_Np, variant>&>
1215         emplace(initializer_list<_Up> __il, _Args&&... __args)
1216         {
1217           static_assert(_Np < sizeof...(_Types),
1218                         "The index should be in [0, number of alternatives)");
1219           this->~variant();
1220           __try
1221             {
1222               ::new (this) variant(in_place_index<_Np>, __il,
1223                                    std::forward<_Args>(__args)...);
1224             }
1225           __catch (...)
1226             {
1227               this->_M_index = variant_npos;
1228               __throw_exception_again;
1229             }
1230           __glibcxx_assert(index() == _Np);
1231           return std::get<_Np>(*this);
1232         }
1234       constexpr bool valueless_by_exception() const noexcept
1235       { return !this->_M_valid(); }
1237       constexpr size_t index() const noexcept
1238       {
1239         if (this->_M_index ==
1240             typename _Base::__index_type(variant_npos))
1241           return variant_npos;
1242         return this->_M_index;
1243       }
1245       void
1246       swap(variant& __rhs)
1247       noexcept((__is_nothrow_swappable<_Types>::value && ...)
1248                && is_nothrow_move_constructible_v<variant>)
1249       {
1250         if (this->index() == __rhs.index())
1251           {
1252             if (this->_M_valid())
1253               {
1254                 static constexpr void (*_S_vtable[])(void*, void*) =
1255                   { &__detail::__variant::__erased_swap<_Types&, _Types&>... };
1256                 _S_vtable[__rhs._M_index](this->_M_storage(),
1257                                           __rhs._M_storage());
1258               }
1259           }
1260         else if (!this->_M_valid())
1261           {
1262             this->_M_destructive_move(std::move(__rhs));
1263             __rhs._M_reset();
1264           }
1265         else if (!__rhs._M_valid())
1266           {
1267             __rhs._M_destructive_move(std::move(*this));
1268             this->_M_reset();
1269           }
1270         else
1271           {
1272             auto __tmp = std::move(__rhs);
1273             __rhs._M_destructive_move(std::move(*this));
1274             this->_M_destructive_move(std::move(__tmp));
1275           }
1276       }
1278     private:
1279 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1280       template<size_t... __indices> \
1281         static constexpr bool \
1282         (*_S_erased_##__NAME[])(const variant&, const variant&) = \
1283           { &__detail::__variant::__erased_##__NAME< \
1284                 const variant&, __indices>... }; \
1285       template<size_t... __indices> \
1286         constexpr inline bool \
1287         _M_##__NAME(const variant& __rhs, \
1288                     std::index_sequence<__indices...>) const \
1289         { \
1290           auto __lhs_index = this->index(); \
1291           auto __rhs_index = __rhs.index(); \
1292           if (__lhs_index != __rhs_index || valueless_by_exception()) \
1293             /* Modulo addition. */ \
1294             return __lhs_index + 1 __OP __rhs_index + 1; \
1295           return _S_erased_##__NAME<__indices...>[__lhs_index](*this, __rhs); \
1296         }
1298       _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1299       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1300       _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1301       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1302       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1303       _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1305 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1307       template<size_t _Np, typename _Vp>
1308         friend constexpr decltype(auto) __detail::__variant::__get(_Vp&& __v);
1310       template<typename _Vp>
1311         friend void* __detail::__variant::__get_storage(_Vp&& __v);
1313 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1314       template<typename... _Tp> \
1315         friend constexpr bool \
1316         operator __OP(const variant<_Tp...>& __lhs, \
1317                       const variant<_Tp...>& __rhs);
1319       _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1320       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1321       _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1322       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1323       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1324       _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1326 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1327     };
1329   template<size_t _Np, typename... _Types>
1330     constexpr variant_alternative_t<_Np, variant<_Types...>>&
1331     get(variant<_Types...>& __v)
1332     {
1333       static_assert(_Np < sizeof...(_Types),
1334                     "The index should be in [0, number of alternatives)");
1335       if (__v.index() != _Np)
1336         __throw_bad_variant_access("Unexpected index");
1337       return __detail::__variant::__get<_Np>(__v);
1338     }
1340   template<size_t _Np, typename... _Types>
1341     constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1342     get(variant<_Types...>&& __v)
1343     {
1344       static_assert(_Np < sizeof...(_Types),
1345                     "The index should be in [0, number of alternatives)");
1346       if (__v.index() != _Np)
1347         __throw_bad_variant_access("Unexpected index");
1348       return __detail::__variant::__get<_Np>(std::move(__v));
1349     }
1351   template<size_t _Np, typename... _Types>
1352     constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1353     get(const variant<_Types...>& __v)
1354     {
1355       static_assert(_Np < sizeof...(_Types),
1356                     "The index should be in [0, number of alternatives)");
1357       if (__v.index() != _Np)
1358         __throw_bad_variant_access("Unexpected index");
1359       return __detail::__variant::__get<_Np>(__v);
1360     }
1362   template<size_t _Np, typename... _Types>
1363     constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1364     get(const variant<_Types...>&& __v)
1365     {
1366       static_assert(_Np < sizeof...(_Types),
1367                     "The index should be in [0, number of alternatives)");
1368       if (__v.index() != _Np)
1369         __throw_bad_variant_access("Unexpected index");
1370       return __detail::__variant::__get<_Np>(std::move(__v));
1371     }
1373   template<typename _Visitor, typename... _Variants>
1374     constexpr decltype(auto)
1375     visit(_Visitor&& __visitor, _Variants&&... __variants)
1376     {
1377       if ((__variants.valueless_by_exception() || ...))
1378         __throw_bad_variant_access("Unexpected index");
1380       using _Result_type =
1381         decltype(std::forward<_Visitor>(__visitor)(
1382             get<0>(std::forward<_Variants>(__variants))...));
1384       constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1385         _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1387       auto __func_ptr = __vtable._M_access(__variants.index()...);
1388       return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1389                            std::forward<_Variants>(__variants)...);
1390     }
1392   template<bool, typename... _Types>
1393     struct __variant_hash_call_base_impl
1394     {
1395       size_t
1396       operator()(const variant<_Types...>& __t) const
1397       noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1398       {
1399         if (!__t.valueless_by_exception())
1400           {
1401             namespace __edv = __detail::__variant;
1402             static constexpr size_t (*_S_vtable[])(void*) =
1403               { &__edv::__erased_hash<const _Types&>... };
1404             return hash<size_t>{}(__t.index())
1405               + _S_vtable[__t.index()](__edv::__get_storage(__t));
1406           }
1407         return hash<size_t>{}(__t.index());
1408       }
1409     };
1411   template<typename... _Types>
1412     struct __variant_hash_call_base_impl<false, _Types...> {};
1414   template<typename... _Types>
1415     using __variant_hash_call_base =
1416     __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
1417                                    __enable_hash_call &&...), _Types...>;
1419   template<typename... _Types>
1420     struct hash<variant<_Types...>>
1421     : private __detail::__variant::_Variant_hash_base<
1422         variant<_Types...>, std::index_sequence_for<_Types...>>,
1423       public __variant_hash_call_base<_Types...>
1424     {
1425       using result_type [[__deprecated__]] = size_t;
1426       using argument_type [[__deprecated__]] = variant<_Types...>;
1427     };
1429   template<>
1430     struct hash<monostate>
1431     {
1432       using result_type [[__deprecated__]] = size_t;
1433       using argument_type [[__deprecated__]] = monostate;
1435       size_t
1436       operator()(const monostate& __t) const noexcept
1437       {
1438         constexpr size_t __magic_monostate_hash = -7777;
1439         return __magic_monostate_hash;
1440       }
1441     };
1443   template<typename... _Types>
1444     struct __is_fast_hash<hash<variant<_Types...>>>
1445     : bool_constant<(__is_fast_hash<_Types>::value && ...)>
1446     { };
1448 _GLIBCXX_END_NAMESPACE_VERSION
1449 } // namespace std
1451 #endif // C++17
1453 #endif // _GLIBCXX_VARIANT