* gcc.dg/attr-alloc_size-11.c: UnXFAIL for visium-*-*.
[official-gcc.git] / libstdc++-v3 / include / std / variant
blob8f574f639243c2cc5fbbcd3f57a36132e6991124
1 // <variant> -*- C++ -*-
3 // Copyright (C) 2016-2017 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 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 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 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 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 get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(__ptr);
962     }
964   template<typename _Tp, typename... _Types>
965     constexpr inline add_pointer_t<const _Tp>
966     get_if(const variant<_Types...>* __ptr)
967     noexcept
968     {
969       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
970                     "T should occur for exactly once in alternatives");
971       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
972       return get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(__ptr);
973     }
975   struct monostate { };
977 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
978   template<typename... _Types> \
979     constexpr bool operator __OP(const variant<_Types...>& __lhs, \
980                                  const variant<_Types...>& __rhs) \
981     { \
982       return __lhs._M_##__NAME(__rhs, std::index_sequence_for<_Types...>{}); \
983     } \
985   constexpr bool operator __OP(monostate, monostate) noexcept \
986   { return 0 __OP 0; }
988   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
989   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
990   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
991   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
992   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
993   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
995 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
997   template<typename _Visitor, typename... _Variants>
998     constexpr decltype(auto) visit(_Visitor&&, _Variants&&...);
1000   template<typename... _Types>
1001     inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1002                         && (is_swappable_v<_Types> && ...)>
1003     swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1004     noexcept(noexcept(__lhs.swap(__rhs)))
1005     { __lhs.swap(__rhs); }
1007   template<typename... _Types>
1008     enable_if_t<!((is_move_constructible_v<_Types> && ...)
1009                    && (is_swappable_v<_Types> && ...))>
1010     swap(variant<_Types...>&, variant<_Types...>&) = delete;
1012   class bad_variant_access : public exception
1013   {
1014   public:
1015     bad_variant_access() noexcept : _M_reason("Unknown reason") { }
1016     const char* what() const noexcept override
1017     { return _M_reason; }
1019   private:
1020     bad_variant_access(const char* __reason) : _M_reason(__reason) { }
1022     const char* _M_reason;
1024     friend void __throw_bad_variant_access(const char* __what);
1025   };
1027   inline void
1028   __throw_bad_variant_access(const char* __what)
1029   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1031   template<typename... _Types>
1032     class variant
1033     : private __detail::__variant::_Variant_base<_Types...>,
1034       private _Enable_default_constructor<
1035         __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1036           variant<_Types...>>,
1037       private _Enable_copy_move<
1038         __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1039         __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1040         __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1041         __detail::__variant::_Traits<_Types...>::_S_move_assign,
1042         variant<_Types...>>
1043     {
1044     private:
1045       static_assert(sizeof...(_Types) > 0,
1046                     "variant must have at least one alternative");
1047       static_assert(!(std::is_reference_v<_Types> || ...),
1048                     "variant must have no reference alternative");
1049       static_assert(!(std::is_void_v<_Types> || ...),
1050                     "variant must have no void alternative");
1052       using _Base = __detail::__variant::_Variant_base<_Types...>;
1053       using _Default_ctor_enabler =
1054         _Enable_default_constructor<
1055           __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1056             variant<_Types...>>;
1058       template<typename _Tp>
1059         static constexpr bool
1060         __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1062       template<typename _Tp>
1063         static constexpr size_t __accepted_index =
1064           __detail::__variant::__accepted_index<_Tp&&, variant>::value;
1066       template<size_t _Np, bool = _Np < sizeof...(_Types)>
1067         struct __to_type_impl;
1069       template<size_t _Np>
1070         struct __to_type_impl<_Np, true>
1071         { using type = variant_alternative_t<_Np, variant>; };
1073       template<size_t _Np>
1074         using __to_type = typename __to_type_impl<_Np>::type;
1076       template<typename _Tp>
1077         using __accepted_type = __to_type<__accepted_index<_Tp>>;
1079       template<typename _Tp>
1080         static constexpr size_t __index_of =
1081           __detail::__variant::__index_of_v<_Tp, _Types...>;
1083       using _Traits = __detail::__variant::_Traits<_Types...>;
1085     public:
1086       variant() = default;
1087       variant(const variant& __rhs) = default;
1088       variant(variant&&) = default;
1089       variant& operator=(const variant&) = default;
1090       variant& operator=(variant&&) = default;
1091       ~variant() = default;
1093       template<typename _Tp,
1094                typename = enable_if_t<!is_same_v<decay_t<_Tp>, variant>>,
1095                typename = enable_if_t<(sizeof...(_Types)>0)>,
1096                typename = enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1097                           && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>>>
1098         constexpr
1099         variant(_Tp&& __t)
1100         noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1101         : variant(in_place_index<__accepted_index<_Tp&&>>,
1102                   std::forward<_Tp>(__t))
1103         { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
1105       template<typename _Tp, typename... _Args,
1106                typename = enable_if_t<__exactly_once<_Tp>
1107                           && is_constructible_v<_Tp, _Args&&...>>>
1108         constexpr explicit
1109         variant(in_place_type_t<_Tp>, _Args&&... __args)
1110         : variant(in_place_index<__index_of<_Tp>>,
1111                   std::forward<_Args>(__args)...)
1112         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1114       template<typename _Tp, typename _Up, typename... _Args,
1115                typename = enable_if_t<__exactly_once<_Tp>
1116                           && is_constructible_v<
1117                             _Tp, initializer_list<_Up>&, _Args&&...>>>
1118         constexpr explicit
1119         variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1120                 _Args&&... __args)
1121         : variant(in_place_index<__index_of<_Tp>>, __il,
1122                   std::forward<_Args>(__args)...)
1123         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1125       template<size_t _Np, typename... _Args,
1126                typename = enable_if_t<
1127                  is_constructible_v<__to_type<_Np>, _Args&&...>>>
1128         constexpr explicit
1129         variant(in_place_index_t<_Np>, _Args&&... __args)
1130         : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
1131         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1132         { __glibcxx_assert(index() == _Np); }
1134       template<size_t _Np, typename _Up, typename... _Args,
1135                typename = enable_if_t<is_constructible_v<__to_type<_Np>,
1136                                       initializer_list<_Up>&, _Args&&...>>>
1137         constexpr explicit
1138         variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1139                 _Args&&... __args)
1140         : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1141         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1142         { __glibcxx_assert(index() == _Np); }
1144       template<typename _Tp>
1145         enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1146                     && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>
1147                     && is_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1148                     && !is_same_v<decay_t<_Tp>, variant>, variant&>
1149         operator=(_Tp&& __rhs)
1150         noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1151                  && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1152         {
1153           constexpr auto __index = __accepted_index<_Tp&&>;
1154           if (index() == __index)
1155             std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1156           else
1157             this->emplace<__index>(std::forward<_Tp>(__rhs));
1158           __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this));
1159           return *this;
1160         }
1162       template<typename _Tp, typename... _Args>
1163         enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1164                     _Tp&>
1165         emplace(_Args&&... __args)
1166         {
1167           auto& ret =
1168             this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...);
1169           __glibcxx_assert(holds_alternative<_Tp>(*this));
1170           return ret;
1171         }
1173       template<typename _Tp, typename _Up, typename... _Args>
1174         enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1175                     && __exactly_once<_Tp>,
1176                     _Tp&>
1177         emplace(initializer_list<_Up> __il, _Args&&... __args)
1178         {
1179           auto& ret =
1180             this->emplace<__index_of<_Tp>>(__il,
1181                                            std::forward<_Args>(__args)...);
1182           __glibcxx_assert(holds_alternative<_Tp>(*this));
1183           return ret;
1184         }
1186       template<size_t _Np, typename... _Args>
1187         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1188                                        _Args...>,
1189                     variant_alternative_t<_Np, variant>&>
1190         emplace(_Args&&... __args)
1191         {
1192           static_assert(_Np < sizeof...(_Types),
1193                         "The index should be in [0, number of alternatives)");
1194           this->~variant();
1195           __try
1196             {
1197               ::new (this) variant(in_place_index<_Np>,
1198                                    std::forward<_Args>(__args)...);
1199             }
1200           __catch (...)
1201             {
1202               this->_M_index = variant_npos;
1203               __throw_exception_again;
1204             }
1205           __glibcxx_assert(index() == _Np);
1206           return std::get<_Np>(*this);
1207         }
1209       template<size_t _Np, typename _Up, typename... _Args>
1210         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1211                                        initializer_list<_Up>&, _Args...>,
1212                     variant_alternative_t<_Np, variant>&>
1213         emplace(initializer_list<_Up> __il, _Args&&... __args)
1214         {
1215           static_assert(_Np < sizeof...(_Types),
1216                         "The index should be in [0, number of alternatives)");
1217           this->~variant();
1218           __try
1219             {
1220               ::new (this) variant(in_place_index<_Np>, __il,
1221                                    std::forward<_Args>(__args)...);
1222             }
1223           __catch (...)
1224             {
1225               this->_M_index = variant_npos;
1226               __throw_exception_again;
1227             }
1228           __glibcxx_assert(index() == _Np);
1229           return std::get<_Np>(*this);
1230         }
1232       constexpr bool valueless_by_exception() const noexcept
1233       { return !this->_M_valid(); }
1235       constexpr size_t index() const noexcept
1236       {
1237         if (this->_M_index ==
1238             typename _Base::__index_type(variant_npos))
1239           return variant_npos;
1240         return this->_M_index;
1241       }
1243       void
1244       swap(variant& __rhs)
1245       noexcept((__is_nothrow_swappable<_Types>::value && ...)
1246                && is_nothrow_move_constructible_v<variant>)
1247       {
1248         if (this->index() == __rhs.index())
1249           {
1250             if (this->_M_valid())
1251               {
1252                 static constexpr void (*_S_vtable[])(void*, void*) =
1253                   { &__detail::__variant::__erased_swap<_Types&, _Types&>... };
1254                 _S_vtable[__rhs._M_index](this->_M_storage(),
1255                                           __rhs._M_storage());
1256               }
1257           }
1258         else if (!this->_M_valid())
1259           {
1260             this->_M_destructive_move(std::move(__rhs));
1261             __rhs._M_reset();
1262           }
1263         else if (!__rhs._M_valid())
1264           {
1265             __rhs._M_destructive_move(std::move(*this));
1266             this->_M_reset();
1267           }
1268         else
1269           {
1270             auto __tmp = std::move(__rhs);
1271             __rhs._M_destructive_move(std::move(*this));
1272             this->_M_destructive_move(std::move(__tmp));
1273           }
1274       }
1276     private:
1277 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1278       template<size_t... __indices> \
1279         static constexpr bool \
1280         (*_S_erased_##__NAME[])(const variant&, const variant&) = \
1281           { &__detail::__variant::__erased_##__NAME< \
1282                 const variant&, __indices>... }; \
1283       template<size_t... __indices> \
1284         constexpr inline bool \
1285         _M_##__NAME(const variant& __rhs, \
1286                     std::index_sequence<__indices...>) const \
1287         { \
1288           auto __lhs_index = this->index(); \
1289           auto __rhs_index = __rhs.index(); \
1290           if (__lhs_index != __rhs_index || valueless_by_exception()) \
1291             /* Modulo addition. */ \
1292             return __lhs_index + 1 __OP __rhs_index + 1; \
1293           return _S_erased_##__NAME<__indices...>[__lhs_index](*this, __rhs); \
1294         }
1296       _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1297       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1298       _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1299       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1300       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1301       _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1303 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1305       template<size_t _Np, typename _Vp>
1306         friend constexpr decltype(auto) __detail::__variant::__get(_Vp&& __v);
1308       template<typename _Vp>
1309         friend void* __detail::__variant::__get_storage(_Vp&& __v);
1311 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1312       template<typename... _Tp> \
1313         friend constexpr bool \
1314         operator __OP(const variant<_Tp...>& __lhs, \
1315                       const variant<_Tp...>& __rhs);
1317       _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1318       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1319       _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1320       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1321       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1322       _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1324 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1325     };
1327   template<size_t _Np, typename... _Types>
1328     constexpr variant_alternative_t<_Np, variant<_Types...>>&
1329     get(variant<_Types...>& __v)
1330     {
1331       static_assert(_Np < sizeof...(_Types),
1332                     "The index should be in [0, number of alternatives)");
1333       if (__v.index() != _Np)
1334         __throw_bad_variant_access("Unexpected index");
1335       return __detail::__variant::__get<_Np>(__v);
1336     }
1338   template<size_t _Np, typename... _Types>
1339     constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1340     get(variant<_Types...>&& __v)
1341     {
1342       static_assert(_Np < sizeof...(_Types),
1343                     "The index should be in [0, number of alternatives)");
1344       if (__v.index() != _Np)
1345         __throw_bad_variant_access("Unexpected index");
1346       return __detail::__variant::__get<_Np>(std::move(__v));
1347     }
1349   template<size_t _Np, typename... _Types>
1350     constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1351     get(const variant<_Types...>& __v)
1352     {
1353       static_assert(_Np < sizeof...(_Types),
1354                     "The index should be in [0, number of alternatives)");
1355       if (__v.index() != _Np)
1356         __throw_bad_variant_access("Unexpected index");
1357       return __detail::__variant::__get<_Np>(__v);
1358     }
1360   template<size_t _Np, typename... _Types>
1361     constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1362     get(const variant<_Types...>&& __v)
1363     {
1364       static_assert(_Np < sizeof...(_Types),
1365                     "The index should be in [0, number of alternatives)");
1366       if (__v.index() != _Np)
1367         __throw_bad_variant_access("Unexpected index");
1368       return __detail::__variant::__get<_Np>(std::move(__v));
1369     }
1371   template<typename _Visitor, typename... _Variants>
1372     constexpr decltype(auto)
1373     visit(_Visitor&& __visitor, _Variants&&... __variants)
1374     {
1375       if ((__variants.valueless_by_exception() || ...))
1376         __throw_bad_variant_access("Unexpected index");
1378       using _Result_type =
1379         decltype(std::forward<_Visitor>(__visitor)(
1380             get<0>(std::forward<_Variants>(__variants))...));
1382       constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1383         _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1385       auto __func_ptr = __vtable._M_access(__variants.index()...);
1386       return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1387                            std::forward<_Variants>(__variants)...);
1388     }
1390   template<bool, typename... _Types>
1391     struct __variant_hash_call_base_impl
1392     {
1393       size_t
1394       operator()(const variant<_Types...>& __t) const
1395       noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1396       {
1397         if (!__t.valueless_by_exception())
1398           {
1399             namespace __edv = __detail::__variant;
1400             static constexpr size_t (*_S_vtable[])(void*) =
1401               { &__edv::__erased_hash<const _Types&>... };
1402             return hash<size_t>{}(__t.index())
1403               + _S_vtable[__t.index()](__edv::__get_storage(__t));
1404           }
1405         return hash<size_t>{}(__t.index());
1406       }
1407     };
1409   template<typename... _Types>
1410     struct __variant_hash_call_base_impl<false, _Types...> {};
1412   template<typename... _Types>
1413     using __variant_hash_call_base =
1414     __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
1415                                    __enable_hash_call &&...), _Types...>;
1417   template<typename... _Types>
1418     struct hash<variant<_Types...>>
1419     : private __detail::__variant::_Variant_hash_base<
1420         variant<_Types...>, std::index_sequence_for<_Types...>>,
1421       public __variant_hash_call_base<_Types...>
1422     {
1423       using result_type [[__deprecated__]] = size_t;
1424       using argument_type [[__deprecated__]] = variant<_Types...>;
1425     };
1427   template<>
1428     struct hash<monostate>
1429     {
1430       using result_type [[__deprecated__]] = size_t;
1431       using argument_type [[__deprecated__]] = monostate;
1433       size_t
1434       operator()(const monostate& __t) const noexcept
1435       {
1436         constexpr size_t __magic_monostate_hash = -7777;
1437         return __magic_monostate_hash;
1438       }
1439     };
1441   template<typename... _Types>
1442     struct __is_fast_hash<hash<variant<_Types...>>>
1443     : bool_constant<(__is_fast_hash<_Types>::value && ...)>
1444     { };
1446 _GLIBCXX_END_NAMESPACE_VERSION
1447 } // namespace std
1449 #endif // C++17
1451 #endif // _GLIBCXX_VARIANT