Daily bump.
[official-gcc.git] / libstdc++-v3 / include / std / variant
blob2d86a704c63e3c3449b2a3a460853d0f77cba427
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     {
227       return __variant::__get(in_place_index<_Np-1>,
228                               std::forward<_Union>(__u)._M_rest);
229     }
231   // Returns the typed storage for __v.
232   template<size_t _Np, typename _Variant>
233     constexpr decltype(auto) __get(_Variant&& __v)
234     {
235       return __variant::__get(std::in_place_index<_Np>,
236                               std::forward<_Variant>(__v)._M_u);
237     }
239   // Various functions as "vtable" entries, where those vtables are used by
240   // polymorphic operations.
241   template<typename _Lhs, typename _Rhs>
242     void
243     __erased_ctor(void* __lhs, void* __rhs)
244     {
245       using _Type = remove_reference_t<_Lhs>;
246       ::new (__lhs) _Type(__variant::__ref_cast<_Rhs>(__rhs));
247     }
249   template<typename _Variant, size_t _Np>
250     void
251     __erased_dtor(_Variant&& __v)
252     { std::_Destroy(std::__addressof(__variant::__get<_Np>(__v))); }
254   template<typename _Lhs, typename _Rhs>
255     void
256     __erased_assign(void* __lhs, void* __rhs)
257     {
258       __variant::__ref_cast<_Lhs>(__lhs) = __variant::__ref_cast<_Rhs>(__rhs);
259     }
261   template<typename _Lhs, typename _Rhs>
262     void
263     __erased_swap(void* __lhs, void* __rhs)
264     {
265       using std::swap;
266       swap(__variant::__ref_cast<_Lhs>(__lhs),
267            __variant::__ref_cast<_Rhs>(__rhs));
268     }
270 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
271   template<typename _Variant, size_t _Np> \
272     constexpr bool \
273     __erased_##__NAME(const _Variant& __lhs, const _Variant& __rhs) \
274     { \
275       return __variant::__get<_Np>(std::forward<_Variant>(__lhs)) \
276           __OP __variant::__get<_Np>(std::forward<_Variant>(__rhs)); \
277     }
279   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
280   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
281   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
282   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
283   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
284   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
286 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
288   template<typename _Tp>
289     size_t
290     __erased_hash(void* __t)
291     {
292       return std::hash<__remove_cvref_t<_Tp>>{}(
293           __variant::__ref_cast<_Tp>(__t));
294     }
296   template<typename... _Types>
297     struct _Traits
298     {
299       static constexpr bool _S_default_ctor =
300           is_default_constructible_v<typename _Nth_type<0, _Types...>::type>;
301       static constexpr bool _S_copy_ctor =
302           (is_copy_constructible_v<_Types> && ...);
303       static constexpr bool _S_move_ctor =
304           (is_move_constructible_v<_Types> && ...);
305       static constexpr bool _S_copy_assign =
306           _S_copy_ctor && _S_move_ctor
307           && (is_copy_assignable_v<_Types> && ...);
308       static constexpr bool _S_move_assign =
309           _S_move_ctor
310           && (is_move_assignable_v<_Types> && ...);
312       static constexpr bool _S_trivial_dtor =
313           (is_trivially_destructible_v<_Types> && ...);
314       static constexpr bool _S_trivial_copy_ctor =
315           (is_trivially_copy_constructible_v<_Types> && ...);
316       static constexpr bool _S_trivial_move_ctor =
317           (is_trivially_move_constructible_v<_Types> && ...);
318       static constexpr bool _S_trivial_copy_assign =
319           _S_trivial_dtor && (is_trivially_copy_assignable_v<_Types> && ...);
320       static constexpr bool _S_trivial_move_assign =
321           _S_trivial_dtor && (is_trivially_move_assignable_v<_Types> && ...);
323       // The following nothrow traits are for non-trivial SMFs. Trivial SMFs
324       // are always nothrow.
325       static constexpr bool _S_nothrow_default_ctor =
326           is_nothrow_default_constructible_v<
327               typename _Nth_type<0, _Types...>::type>;
328       static constexpr bool _S_nothrow_copy_ctor = false;
329       static constexpr bool _S_nothrow_move_ctor =
330           (is_nothrow_move_constructible_v<_Types> && ...);
331       static constexpr bool _S_nothrow_copy_assign = false;
332       static constexpr bool _S_nothrow_move_assign =
333           _S_nothrow_move_ctor && (is_nothrow_move_assignable_v<_Types> && ...);
334     };
336   // Defines members and ctors.
337   template<typename... _Types>
338     union _Variadic_union { };
340   template<typename _First, typename... _Rest>
341     union _Variadic_union<_First, _Rest...>
342     {
343       constexpr _Variadic_union() : _M_rest() { }
345       template<typename... _Args>
346         constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args)
347         : _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
348         { }
350       template<size_t _Np, typename... _Args>
351         constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
352         : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
353         { }
355       _Uninitialized<_First> _M_first;
356       _Variadic_union<_Rest...> _M_rest;
357     };
359   // Defines index and the dtor, possibly trivial.
360   template<bool __trivially_destructible, typename... _Types>
361     struct _Variant_storage;
363   template <typename... _Types>
364   using __select_index =
365     typename __select_int::_Select_int_base<sizeof...(_Types) + 1,
366                                             unsigned char,
367                                             unsigned short>::type::value_type;
369   template<typename... _Types>
370     struct _Variant_storage<false, _Types...>
371     {
372       template<size_t... __indices>
373         static constexpr void (*_S_vtable[])(const _Variant_storage&) =
374             { &__erased_dtor<const _Variant_storage&, __indices>... };
376       constexpr _Variant_storage() : _M_index(variant_npos) { }
378       template<size_t _Np, typename... _Args>
379         constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
380         : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
381         _M_index(_Np)
382         { }
384       template<size_t... __indices>
385         constexpr void _M_reset_impl(std::index_sequence<__indices...>)
386         {
387           if (_M_index != __index_type(variant_npos))
388             _S_vtable<__indices...>[_M_index](*this);
389         }
391       void _M_reset()
392       {
393         _M_reset_impl(std::index_sequence_for<_Types...>{});
394         _M_index = variant_npos;
395       }
397       ~_Variant_storage()
398       { _M_reset(); }
400       void*
401       _M_storage() const
402       {
403         return const_cast<void*>(static_cast<const void*>(
404             std::addressof(_M_u)));
405       }
407       constexpr bool
408       _M_valid() const noexcept
409       {
410         return this->_M_index != __index_type(variant_npos);
411       }
413       _Variadic_union<_Types...> _M_u;
414       using __index_type = __select_index<_Types...>;
415       __index_type _M_index;
416     };
418   template<typename... _Types>
419     struct _Variant_storage<true, _Types...>
420     {
421       constexpr _Variant_storage() : _M_index(variant_npos) { }
423       template<size_t _Np, typename... _Args>
424         constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
425         : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
426         _M_index(_Np)
427         { }
429       void _M_reset()
430       { _M_index = variant_npos; }
432       void*
433       _M_storage() const
434       {
435         return const_cast<void*>(static_cast<const void*>(
436             std::addressof(_M_u)));
437       }
439       constexpr bool
440       _M_valid() const noexcept
441       {
442         return this->_M_index != __index_type(variant_npos);
443       }
445       _Variadic_union<_Types...> _M_u;
446       using __index_type = __select_index<_Types...>;
447       __index_type _M_index;
448     };
450   template<typename... _Types>
451     using _Variant_storage_alias =
452         _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
454   // The following are (Copy|Move) (ctor|assign) layers for forwarding
455   // triviality and handling non-trivial SMF behaviors.
457   template<bool, typename... _Types>
458     struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
459     {
460       using _Base = _Variant_storage_alias<_Types...>;
461       using _Base::_Base;
463       _Copy_ctor_base(const _Copy_ctor_base& __rhs)
464           noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
465       {
466         if (__rhs._M_valid())
467           {
468             static constexpr void (*_S_vtable[])(void*, void*) =
469               { &__erased_ctor<_Types&, const _Types&>... };
470             _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
471             this->_M_index = __rhs._M_index;
472           }
473       }
475       _Copy_ctor_base(_Copy_ctor_base&&) = default;
476       _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default;
477       _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default;
478     };
480   template<typename... _Types>
481     struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
482     {
483       using _Base = _Variant_storage_alias<_Types...>;
484       using _Base::_Base;
485     };
487   template<typename... _Types>
488     using _Copy_ctor_alias =
489         _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
491   template<bool, typename... _Types>
492     struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
493     {
494       using _Base = _Copy_ctor_alias<_Types...>;
495       using _Base::_Base;
497       _Move_ctor_base(_Move_ctor_base&& __rhs)
498           noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
499       {
500         if (__rhs._M_valid())
501           {
502             static constexpr void (*_S_vtable[])(void*, void*) =
503               { &__erased_ctor<_Types&, _Types&&>... };
504             _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
505             this->_M_index = __rhs._M_index;
506           }
507       }
509       void _M_destructive_move(_Move_ctor_base&& __rhs)
510       {
511         this->~_Move_ctor_base();
512         __try
513           {
514             ::new (this) _Move_ctor_base(std::move(__rhs));
515           }
516         __catch (...)
517           {
518             this->_M_index = variant_npos;
519             __throw_exception_again;
520           }
521       }
523       _Move_ctor_base(const _Move_ctor_base&) = default;
524       _Move_ctor_base& operator=(const _Move_ctor_base&) = default;
525       _Move_ctor_base& operator=(_Move_ctor_base&&) = default;
526     };
528   template<typename... _Types>
529     struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
530     {
531       using _Base = _Copy_ctor_alias<_Types...>;
532       using _Base::_Base;
534       void _M_destructive_move(_Move_ctor_base&& __rhs)
535       {
536         this->~_Move_ctor_base();
537         ::new (this) _Move_ctor_base(std::move(__rhs));
538       }
539     };
541   template<typename... _Types>
542     using _Move_ctor_alias =
543         _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
545   template<bool, typename... _Types>
546     struct _Copy_assign_base : _Move_ctor_alias<_Types...>
547     {
548       using _Base = _Move_ctor_alias<_Types...>;
549       using _Base::_Base;
551       _Copy_assign_base&
552       operator=(const _Copy_assign_base& __rhs)
553           noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
554       {
555         if (this->_M_index == __rhs._M_index)
556           {
557             if (__rhs._M_valid())
558               {
559                 static constexpr void (*_S_vtable[])(void*, void*) =
560                   { &__erased_assign<_Types&, const _Types&>... };
561                 _S_vtable[__rhs._M_index](this->_M_storage(),
562                                           __rhs._M_storage());
563               }
564           }
565         else
566           {
567             _Copy_assign_base __tmp(__rhs);
568             this->_M_destructive_move(std::move(__tmp));
569           }
570         __glibcxx_assert(this->_M_index == __rhs._M_index);
571         return *this;
572       }
574       _Copy_assign_base(const _Copy_assign_base&) = default;
575       _Copy_assign_base(_Copy_assign_base&&) = default;
576       _Copy_assign_base& operator=(_Copy_assign_base&&) = default;
577     };
579   template<typename... _Types>
580     struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
581     {
582       using _Base = _Move_ctor_alias<_Types...>;
583       using _Base::_Base;
584     };
586   template<typename... _Types>
587     using _Copy_assign_alias =
588         _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign,
589                           _Types...>;
591   template<bool, typename... _Types>
592     struct _Move_assign_base : _Copy_assign_alias<_Types...>
593     {
594       using _Base = _Copy_assign_alias<_Types...>;
595       using _Base::_Base;
597       _Move_assign_base&
598       operator=(_Move_assign_base&& __rhs)
599           noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
600       {
601         if (this->_M_index == __rhs._M_index)
602           {
603             if (__rhs._M_valid())
604               {
605                 static constexpr void (*_S_vtable[])(void*, void*) =
606                   { &__erased_assign<_Types&, _Types&&>... };
607                 _S_vtable[__rhs._M_index]
608                   (this->_M_storage(), __rhs._M_storage());
609               }
610           }
611         else
612           {
613             _Move_assign_base __tmp(std::move(__rhs));
614             this->_M_destructive_move(std::move(__tmp));
615           }
616         __glibcxx_assert(this->_M_index == __rhs._M_index);
617         return *this;
618       }
620       _Move_assign_base(const _Move_assign_base&) = default;
621       _Move_assign_base(_Move_assign_base&&) = default;
622       _Move_assign_base& operator=(const _Move_assign_base&) = default;
623     };
625   template<typename... _Types>
626     struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
627     {
628       using _Base = _Copy_assign_alias<_Types...>;
629       using _Base::_Base;
630     };
632   template<typename... _Types>
633     using _Move_assign_alias =
634         _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign,
635                           _Types...>;
637   template<typename... _Types>
638     struct _Variant_base : _Move_assign_alias<_Types...>
639     {
640       using _Base = _Move_assign_alias<_Types...>;
642       constexpr
643       _Variant_base()
644           noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
645       : _Variant_base(in_place_index<0>) { }
647       template<size_t _Np, typename... _Args>
648         constexpr explicit
649         _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
650         : _Base(__i, std::forward<_Args>(__args)...)
651         { }
653       _Variant_base(const _Variant_base&) = default;
654       _Variant_base(_Variant_base&&) = default;
655       _Variant_base& operator=(const _Variant_base&) = default;
656       _Variant_base& operator=(_Variant_base&&) = default;
657     };
659   // For how many times does _Tp appear in _Tuple?
660   template<typename _Tp, typename _Tuple>
661     struct __tuple_count;
663   template<typename _Tp, typename _Tuple>
664     inline constexpr size_t __tuple_count_v =
665       __tuple_count<_Tp, _Tuple>::value;
667   template<typename _Tp, typename... _Types>
668     struct __tuple_count<_Tp, tuple<_Types...>>
669     : integral_constant<size_t, 0> { };
671   template<typename _Tp, typename _First, typename... _Rest>
672     struct __tuple_count<_Tp, tuple<_First, _Rest...>>
673     : integral_constant<
674         size_t,
675         __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
677   // TODO: Reuse this in <tuple> ?
678   template<typename _Tp, typename... _Types>
679     inline constexpr bool __exactly_once =
680       __tuple_count_v<_Tp, tuple<_Types...>> == 1;
682   // Takes _Types and create an overloaded _S_fun for each type.
683   // If a type appears more than once in _Types, create only one overload.
684   template<typename... _Types>
685     struct __overload_set
686     { static void _S_fun(); };
688   template<typename _First, typename... _Rest>
689     struct __overload_set<_First, _Rest...> : __overload_set<_Rest...>
690     {
691       using __overload_set<_Rest...>::_S_fun;
692       static integral_constant<size_t, sizeof...(_Rest)> _S_fun(_First);
693     };
695   template<typename... _Rest>
696     struct __overload_set<void, _Rest...> : __overload_set<_Rest...>
697     {
698       using __overload_set<_Rest...>::_S_fun;
699     };
701   // Helper for variant(_Tp&&) and variant::operator=(_Tp&&).
702   // __accepted_index maps an arbitrary _Tp to an alternative type in _Variant
703   // (or to variant_npos).
704   template<typename _Tp, typename _Variant, typename = void>
705     struct __accepted_index
706     { static constexpr size_t value = variant_npos; };
708   template<typename _Tp, typename... _Types>
709     struct __accepted_index<
710       _Tp, variant<_Types...>,
711       void_t<decltype(__overload_set<_Types...>::_S_fun(std::declval<_Tp>()))>>
712     {
713       static constexpr size_t value = sizeof...(_Types) - 1
714         - decltype(__overload_set<_Types...>::
715                    _S_fun(std::declval<_Tp>()))::value;
716     };
718   // Returns the raw storage for __v.
719   template<typename _Variant>
720     void* __get_storage(_Variant&& __v)
721     { return __v._M_storage(); }
723   // Used for storing multi-dimensional vtable.
724   template<typename _Tp, size_t... _Dimensions>
725     struct _Multi_array
726     {
727       constexpr const _Tp&
728       _M_access() const
729       { return _M_data; }
731       _Tp _M_data;
732     };
734   template<typename _Tp, size_t __first, size_t... __rest>
735     struct _Multi_array<_Tp, __first, __rest...>
736     {
737       template<typename... _Args>
738         constexpr const _Tp&
739         _M_access(size_t __first_index, _Args... __rest_indices) const
740         { return _M_arr[__first_index]._M_access(__rest_indices...); }
742       _Multi_array<_Tp, __rest...> _M_arr[__first];
743     };
745   // Creates a multi-dimensional vtable recursively.
746   //
747   // For example,
748   // visit([](auto, auto){},
749   //       variant<int, char>(),  // typedef'ed as V1
750   //       variant<float, double, long double>())  // typedef'ed as V2
751   // will trigger instantiations of:
752   // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>,
753   //                   tuple<V1&&, V2&&>, std::index_sequence<>>
754   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
755   //                     tuple<V1&&, V2&&>, std::index_sequence<0>>
756   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
757   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 0>>
758   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
759   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 1>>
760   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
761   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 2>>
762   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
763   //                     tuple<V1&&, V2&&>, std::index_sequence<1>>
764   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
765   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 0>>
766   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
767   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 1>>
768   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
769   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 2>>
770   // The returned multi-dimensional vtable can be fast accessed by the visitor
771   // using index calculation.
772   template<typename _Array_type, typename _Variant_tuple, typename _Index_seq>
773     struct __gen_vtable_impl;
775   template<typename _Result_type, typename _Visitor, size_t... __dimensions,
776            typename... _Variants, size_t... __indices>
777     struct __gen_vtable_impl<
778         _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
779         tuple<_Variants...>, std::index_sequence<__indices...>>
780     {
781       using _Next =
782           remove_reference_t<typename _Nth_type<sizeof...(__indices),
783                              _Variants...>::type>;
784       using _Array_type =
785           _Multi_array<_Result_type (*)(_Visitor, _Variants...),
786                        __dimensions...>;
788       static constexpr _Array_type
789       _S_apply()
790       {
791         _Array_type __vtable{};
792         _S_apply_all_alts(
793           __vtable, make_index_sequence<variant_size_v<_Next>>());
794         return __vtable;
795       }
797       template<size_t... __var_indices>
798         static constexpr void
799         _S_apply_all_alts(_Array_type& __vtable,
800                           std::index_sequence<__var_indices...>)
801         {
802           (_S_apply_single_alt<__var_indices>(
803              __vtable._M_arr[__var_indices]), ...);
804         }
806       template<size_t __index, typename _Tp>
807         static constexpr void
808         _S_apply_single_alt(_Tp& __element)
809         {
810           using _Alternative = variant_alternative_t<__index, _Next>;
811           __element = __gen_vtable_impl<
812             remove_reference_t<
813               decltype(__element)>, tuple<_Variants...>,
814               std::index_sequence<__indices..., __index>>::_S_apply();
815         }
816     };
818   template<typename _Result_type, typename _Visitor, typename... _Variants,
819            size_t... __indices>
820     struct __gen_vtable_impl<
821       _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
822                    tuple<_Variants...>, std::index_sequence<__indices...>>
823     {
824       using _Array_type =
825           _Multi_array<_Result_type (*)(_Visitor&&, _Variants...)>;
827       decltype(auto)
828       static constexpr __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
829       {
830         return std::__invoke(std::forward<_Visitor>(__visitor),
831             std::get<__indices>(std::forward<_Variants>(__vars))...);
832       }
834       static constexpr auto
835       _S_apply()
836       { return _Array_type{&__visit_invoke}; }
837     };
839   template<typename _Result_type, typename _Visitor, typename... _Variants>
840     struct __gen_vtable
841     {
842       using _Func_ptr = _Result_type (*)(_Visitor&&, _Variants...);
843       using _Array_type =
844           _Multi_array<_Func_ptr,
845                        variant_size_v<remove_reference_t<_Variants>>...>;
847       static constexpr _Array_type
848       _S_apply()
849       {
850         return __gen_vtable_impl<_Array_type, tuple<_Variants...>,
851                                  std::index_sequence<>>::_S_apply();
852       }
854       static constexpr auto _S_vtable = _S_apply();
855     };
857   template<size_t _Np, typename _Tp>
858     struct _Base_dedup : public _Tp { };
860   template<typename _Variant, typename __indices>
861     struct _Variant_hash_base;
863   template<typename... _Types, size_t... __indices>
864     struct _Variant_hash_base<variant<_Types...>,
865                               std::index_sequence<__indices...>>
866     : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
868 } // namespace __variant
869 } // namespace __detail
871   template<typename _Tp, typename... _Types>
872     inline constexpr bool holds_alternative(const variant<_Types...>& __v)
873     noexcept
874     {
875       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
876                     "T should occur for exactly once in alternatives");
877       return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>;
878     }
880   template<typename _Tp, typename... _Types>
881     constexpr inline _Tp& get(variant<_Types...>& __v)
882     {
883       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
884                     "T should occur for exactly once in alternatives");
885       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
886       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
887     }
889   template<typename _Tp, typename... _Types>
890     constexpr inline _Tp&& get(variant<_Types...>&& __v)
891     {
892       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
893                     "T should occur for exactly once in alternatives");
894       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
895       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
896         std::move(__v));
897     }
899   template<typename _Tp, typename... _Types>
900     constexpr inline const _Tp& get(const variant<_Types...>& __v)
901     {
902       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
903                     "T should occur for exactly once in alternatives");
904       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
905       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
906     }
908   template<typename _Tp, typename... _Types>
909     constexpr inline const _Tp&& get(const variant<_Types...>&& __v)
910     {
911       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
912                     "T should occur for exactly once in alternatives");
913       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
914       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
915         std::move(__v));
916     }
918   template<size_t _Np, typename... _Types>
919     constexpr inline
920     add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
921     get_if(variant<_Types...>* __ptr) noexcept
922     {
923       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
924       static_assert(_Np < sizeof...(_Types),
925                     "The index should be in [0, number of alternatives)");
926       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
927       if (__ptr && __ptr->index() == _Np)
928         return &__detail::__variant::__get<_Np>(*__ptr);
929       return nullptr;
930     }
932   template<size_t _Np, typename... _Types>
933     constexpr inline
934     add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
935     get_if(const variant<_Types...>* __ptr) noexcept
936     {
937       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
938       static_assert(_Np < sizeof...(_Types),
939                     "The index should be in [0, number of alternatives)");
940       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
941       if (__ptr && __ptr->index() == _Np)
942         return &__detail::__variant::__get<_Np>(*__ptr);
943       return nullptr;
944     }
946   template<typename _Tp, typename... _Types>
947     constexpr inline add_pointer_t<_Tp>
948     get_if(variant<_Types...>* __ptr) noexcept
949     {
950       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
951                     "T should occur for exactly once in alternatives");
952       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
953       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
954           __ptr);
955     }
957   template<typename _Tp, typename... _Types>
958     constexpr inline add_pointer_t<const _Tp>
959     get_if(const variant<_Types...>* __ptr)
960     noexcept
961     {
962       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
963                     "T should occur for exactly once in alternatives");
964       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
965       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
966           __ptr);
967     }
969   struct monostate { };
971 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
972   template<typename... _Types> \
973     constexpr bool operator __OP(const variant<_Types...>& __lhs, \
974                                  const variant<_Types...>& __rhs) \
975     { \
976       return __lhs._M_##__NAME(__rhs, std::index_sequence_for<_Types...>{}); \
977     } \
979   constexpr bool operator __OP(monostate, monostate) noexcept \
980   { return 0 __OP 0; }
982   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
983   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
984   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
985   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
986   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
987   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
989 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
991   template<typename _Visitor, typename... _Variants>
992     constexpr decltype(auto) visit(_Visitor&&, _Variants&&...);
994   template<typename... _Types>
995     inline enable_if_t<(is_move_constructible_v<_Types> && ...)
996                         && (is_swappable_v<_Types> && ...)>
997     swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
998     noexcept(noexcept(__lhs.swap(__rhs)))
999     { __lhs.swap(__rhs); }
1001   template<typename... _Types>
1002     enable_if_t<!((is_move_constructible_v<_Types> && ...)
1003                    && (is_swappable_v<_Types> && ...))>
1004     swap(variant<_Types...>&, variant<_Types...>&) = delete;
1006   class bad_variant_access : public exception
1007   {
1008   public:
1009     bad_variant_access() noexcept : _M_reason("Unknown reason") { }
1010     const char* what() const noexcept override
1011     { return _M_reason; }
1013   private:
1014     bad_variant_access(const char* __reason) : _M_reason(__reason) { }
1016     const char* _M_reason;
1018     friend void __throw_bad_variant_access(const char* __what);
1019   };
1021   inline void
1022   __throw_bad_variant_access(const char* __what)
1023   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1025   template<typename... _Types>
1026     class variant
1027     : private __detail::__variant::_Variant_base<_Types...>,
1028       private _Enable_default_constructor<
1029         __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1030           variant<_Types...>>,
1031       private _Enable_copy_move<
1032         __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1033         __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1034         __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1035         __detail::__variant::_Traits<_Types...>::_S_move_assign,
1036         variant<_Types...>>
1037     {
1038     private:
1039       static_assert(sizeof...(_Types) > 0,
1040                     "variant must have at least one alternative");
1041       static_assert(!(std::is_reference_v<_Types> || ...),
1042                     "variant must have no reference alternative");
1043       static_assert(!(std::is_void_v<_Types> || ...),
1044                     "variant must have no void alternative");
1046       using _Base = __detail::__variant::_Variant_base<_Types...>;
1047       using _Default_ctor_enabler =
1048         _Enable_default_constructor<
1049           __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1050             variant<_Types...>>;
1052       template<typename _Tp>
1053         static constexpr bool
1054         __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1056       template<typename _Tp>
1057         static constexpr size_t __accepted_index =
1058           __detail::__variant::__accepted_index<_Tp&&, variant>::value;
1060       template<size_t _Np, bool = _Np < sizeof...(_Types)>
1061         struct __to_type_impl;
1063       template<size_t _Np>
1064         struct __to_type_impl<_Np, true>
1065         { using type = variant_alternative_t<_Np, variant>; };
1067       template<size_t _Np>
1068         using __to_type = typename __to_type_impl<_Np>::type;
1070       template<typename _Tp>
1071         using __accepted_type = __to_type<__accepted_index<_Tp>>;
1073       template<typename _Tp>
1074         static constexpr size_t __index_of =
1075           __detail::__variant::__index_of_v<_Tp, _Types...>;
1077       using _Traits = __detail::__variant::_Traits<_Types...>;
1079     public:
1080       variant() = default;
1081       variant(const variant& __rhs) = default;
1082       variant(variant&&) = default;
1083       variant& operator=(const variant&) = default;
1084       variant& operator=(variant&&) = default;
1085       ~variant() = default;
1087       template<typename _Tp,
1088                typename = enable_if_t<!is_same_v<decay_t<_Tp>, variant>>,
1089                typename = enable_if_t<(sizeof...(_Types)>0)>,
1090                typename = enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1091                           && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>>>
1092         constexpr
1093         variant(_Tp&& __t)
1094         noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1095         : variant(in_place_index<__accepted_index<_Tp&&>>,
1096                   std::forward<_Tp>(__t))
1097         { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
1099       template<typename _Tp, typename... _Args,
1100                typename = enable_if_t<__exactly_once<_Tp>
1101                           && is_constructible_v<_Tp, _Args&&...>>>
1102         constexpr explicit
1103         variant(in_place_type_t<_Tp>, _Args&&... __args)
1104         : variant(in_place_index<__index_of<_Tp>>,
1105                   std::forward<_Args>(__args)...)
1106         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1108       template<typename _Tp, typename _Up, typename... _Args,
1109                typename = enable_if_t<__exactly_once<_Tp>
1110                           && is_constructible_v<
1111                             _Tp, initializer_list<_Up>&, _Args&&...>>>
1112         constexpr explicit
1113         variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1114                 _Args&&... __args)
1115         : variant(in_place_index<__index_of<_Tp>>, __il,
1116                   std::forward<_Args>(__args)...)
1117         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1119       template<size_t _Np, typename... _Args,
1120                typename = enable_if_t<
1121                  is_constructible_v<__to_type<_Np>, _Args&&...>>>
1122         constexpr explicit
1123         variant(in_place_index_t<_Np>, _Args&&... __args)
1124         : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
1125         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1126         { __glibcxx_assert(index() == _Np); }
1128       template<size_t _Np, typename _Up, typename... _Args,
1129                typename = enable_if_t<is_constructible_v<__to_type<_Np>,
1130                                       initializer_list<_Up>&, _Args&&...>>>
1131         constexpr explicit
1132         variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1133                 _Args&&... __args)
1134         : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1135         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1136         { __glibcxx_assert(index() == _Np); }
1138       template<typename _Tp>
1139         enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1140                     && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>
1141                     && is_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1142                     && !is_same_v<decay_t<_Tp>, variant>, variant&>
1143         operator=(_Tp&& __rhs)
1144         noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1145                  && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1146         {
1147           constexpr auto __index = __accepted_index<_Tp&&>;
1148           if (index() == __index)
1149             std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1150           else
1151             this->emplace<__index>(std::forward<_Tp>(__rhs));
1152           __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this));
1153           return *this;
1154         }
1156       template<typename _Tp, typename... _Args>
1157         enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1158                     _Tp&>
1159         emplace(_Args&&... __args)
1160         {
1161           auto& ret =
1162             this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...);
1163           __glibcxx_assert(holds_alternative<_Tp>(*this));
1164           return ret;
1165         }
1167       template<typename _Tp, typename _Up, typename... _Args>
1168         enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1169                     && __exactly_once<_Tp>,
1170                     _Tp&>
1171         emplace(initializer_list<_Up> __il, _Args&&... __args)
1172         {
1173           auto& ret =
1174             this->emplace<__index_of<_Tp>>(__il,
1175                                            std::forward<_Args>(__args)...);
1176           __glibcxx_assert(holds_alternative<_Tp>(*this));
1177           return ret;
1178         }
1180       template<size_t _Np, typename... _Args>
1181         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1182                                        _Args...>,
1183                     variant_alternative_t<_Np, variant>&>
1184         emplace(_Args&&... __args)
1185         {
1186           static_assert(_Np < sizeof...(_Types),
1187                         "The index should be in [0, number of alternatives)");
1188           this->~variant();
1189           __try
1190             {
1191               ::new (this) variant(in_place_index<_Np>,
1192                                    std::forward<_Args>(__args)...);
1193             }
1194           __catch (...)
1195             {
1196               this->_M_index = variant_npos;
1197               __throw_exception_again;
1198             }
1199           __glibcxx_assert(index() == _Np);
1200           return std::get<_Np>(*this);
1201         }
1203       template<size_t _Np, typename _Up, typename... _Args>
1204         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1205                                        initializer_list<_Up>&, _Args...>,
1206                     variant_alternative_t<_Np, variant>&>
1207         emplace(initializer_list<_Up> __il, _Args&&... __args)
1208         {
1209           static_assert(_Np < sizeof...(_Types),
1210                         "The index should be in [0, number of alternatives)");
1211           this->~variant();
1212           __try
1213             {
1214               ::new (this) variant(in_place_index<_Np>, __il,
1215                                    std::forward<_Args>(__args)...);
1216             }
1217           __catch (...)
1218             {
1219               this->_M_index = variant_npos;
1220               __throw_exception_again;
1221             }
1222           __glibcxx_assert(index() == _Np);
1223           return std::get<_Np>(*this);
1224         }
1226       constexpr bool valueless_by_exception() const noexcept
1227       { return !this->_M_valid(); }
1229       constexpr size_t index() const noexcept
1230       {
1231         if (this->_M_index ==
1232             typename _Base::__index_type(variant_npos))
1233           return variant_npos;
1234         return this->_M_index;
1235       }
1237       void
1238       swap(variant& __rhs)
1239       noexcept((__is_nothrow_swappable<_Types>::value && ...)
1240                && is_nothrow_move_constructible_v<variant>)
1241       {
1242         if (this->index() == __rhs.index())
1243           {
1244             if (this->_M_valid())
1245               {
1246                 static constexpr void (*_S_vtable[])(void*, void*) =
1247                   { &__detail::__variant::__erased_swap<_Types&, _Types&>... };
1248                 _S_vtable[__rhs._M_index](this->_M_storage(),
1249                                           __rhs._M_storage());
1250               }
1251           }
1252         else if (!this->_M_valid())
1253           {
1254             this->_M_destructive_move(std::move(__rhs));
1255             __rhs._M_reset();
1256           }
1257         else if (!__rhs._M_valid())
1258           {
1259             __rhs._M_destructive_move(std::move(*this));
1260             this->_M_reset();
1261           }
1262         else
1263           {
1264             auto __tmp = std::move(__rhs);
1265             __rhs._M_destructive_move(std::move(*this));
1266             this->_M_destructive_move(std::move(__tmp));
1267           }
1268       }
1270     private:
1271 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1272       template<size_t... __indices> \
1273         static constexpr bool \
1274         (*_S_erased_##__NAME[])(const variant&, const variant&) = \
1275           { &__detail::__variant::__erased_##__NAME< \
1276                 const variant&, __indices>... }; \
1277       template<size_t... __indices> \
1278         constexpr inline bool \
1279         _M_##__NAME(const variant& __rhs, \
1280                     std::index_sequence<__indices...>) const \
1281         { \
1282           auto __lhs_index = this->index(); \
1283           auto __rhs_index = __rhs.index(); \
1284           if (__lhs_index != __rhs_index || valueless_by_exception()) \
1285             /* Modulo addition. */ \
1286             return __lhs_index + 1 __OP __rhs_index + 1; \
1287           return _S_erased_##__NAME<__indices...>[__lhs_index](*this, __rhs); \
1288         }
1290       _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1291       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1292       _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1293       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1294       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1295       _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1297 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1299 #ifdef __clang__
1300     public:
1301       using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852
1302     private:
1303 #endif
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             std::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