Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / libstdc++-v3 / include / std / variant
1 // <variant> -*- C++ -*-
2
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.
10
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.
15
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.
19
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/>.
24
25 /** @file variant
26  *  This is the <variant> C++ Library header.
27  */
28
29 #ifndef _GLIBCXX_VARIANT
30 #define _GLIBCXX_VARIANT 1
31
32 #pragma GCC system_header
33
34 #if __cplusplus >= 201703L
35
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>
48
49 namespace std _GLIBCXX_VISIBILITY(default)
50 {
51 _GLIBCXX_BEGIN_NAMESPACE_VERSION
52
53 namespace __detail
54 {
55 namespace __variant
56 {
57   template<size_t _Np, typename... _Types>
58     struct _Nth_type;
59
60   template<size_t _Np, typename _First, typename... _Rest>
61     struct _Nth_type<_Np, _First, _Rest...>
62     : _Nth_type<_Np-1, _Rest...> { };
63
64   template<typename _First, typename... _Rest>
65     struct _Nth_type<0, _First, _Rest...>
66     { using type = _First; };
67
68 } // namespace __variant
69 } // namespace __detail
70
71 #define __cpp_lib_variant 201603
72
73   template<typename... _Types> class tuple;
74   template<typename... _Types> class variant;
75   template <typename> struct hash;
76
77   template<typename _Variant>
78     struct variant_size;
79
80   template<typename _Variant>
81     struct variant_size<const _Variant> : variant_size<_Variant> {};
82
83   template<typename _Variant>
84     struct variant_size<volatile _Variant> : variant_size<_Variant> {};
85
86   template<typename _Variant>
87     struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
88
89   template<typename... _Types>
90     struct variant_size<variant<_Types...>>
91     : std::integral_constant<size_t, sizeof...(_Types)> {};
92
93   template<typename _Variant>
94     inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
95
96   template<size_t _Np, typename _Variant>
97     struct variant_alternative;
98
99   template<size_t _Np, typename _First, typename... _Rest>
100     struct variant_alternative<_Np, variant<_First, _Rest...>>
101     : variant_alternative<_Np-1, variant<_Rest...>> {};
102
103   template<typename _First, typename... _Rest>
104     struct variant_alternative<0, variant<_First, _Rest...>>
105     { using type = _First; };
106
107   template<size_t _Np, typename _Variant>
108     using variant_alternative_t =
109       typename variant_alternative<_Np, _Variant>::type;
110
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>>; };
114
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>>; };
118
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>>; };
122
123   inline constexpr size_t variant_npos = -1;
124
125   template<size_t _Np, typename... _Types>
126     constexpr variant_alternative_t<_Np, variant<_Types...>>&
127     get(variant<_Types...>&);
128
129   template<size_t _Np, typename... _Types>
130     constexpr variant_alternative_t<_Np, variant<_Types...>>&&
131     get(variant<_Types...>&&);
132
133   template<size_t _Np, typename... _Types>
134     constexpr variant_alternative_t<_Np, variant<_Types...>> const&
135     get(const variant<_Types...>&);
136
137   template<size_t _Np, typename... _Types>
138     constexpr variant_alternative_t<_Np, variant<_Types...>> const&&
139     get(const variant<_Types...>&&);
140
141 namespace __detail
142 {
143 namespace __variant
144 {
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> {};
149
150   template<typename _Tp, typename... _Types>
151     inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value;
152
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> {};
157
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;
168
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       { }
176
177       constexpr const _Type& _M_get() const &
178       { return _M_storage; }
179
180       constexpr _Type& _M_get() &
181       { return _M_storage; }
182
183       constexpr const _Type&& _M_get() const &&
184       { return std::move(_M_storage); }
185
186       constexpr _Type&& _M_get() &&
187       { return std::move(_M_storage); }
188
189       _Type _M_storage;
190     };
191
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)...); }
198
199       const _Type& _M_get() const &
200       { return *_M_storage._M_ptr(); }
201
202       _Type& _M_get() &
203       { return *_M_storage._M_ptr(); }
204
205       const _Type&& _M_get() const &&
206       { return std::move(*_M_storage._M_ptr()); }
207
208       _Type&& _M_get() &&
209       { return std::move(*_M_storage._M_ptr()); }
210
211       __gnu_cxx::__aligned_membuf<_Type> _M_storage;
212     };
213
214   template<typename _Ref>
215     _Ref __ref_cast(void* __ptr)
216     {
217       return static_cast<_Ref>(*static_cast<remove_reference_t<_Ref>*>(__ptr));
218     }
219
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(); }
223
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     }
230
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     }
238
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     }
248
249   template<typename _Variant, size_t _Np>
250     void
251     __erased_dtor(_Variant&& __v)
252     { std::_Destroy(std::__addressof(__get<_Np>(__v))); }
253
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     }
260
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     }
269
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     }
278
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)
285
286 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
287
288   template<typename _Tp>
289     size_t
290     __erased_hash(void* __t)
291     {
292       return std::hash<remove_cv_t<remove_reference_t<_Tp>>>{}(
293           __variant::__ref_cast<_Tp>(__t));
294     }
295
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> && ...);
311
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> && ...);
322
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     };
335
336   // Defines members and ctors.
337   template<typename... _Types>
338     union _Variadic_union { };
339
340   template<typename _First, typename... _Rest>
341     union _Variadic_union<_First, _Rest...>
342     {
343       constexpr _Variadic_union() : _M_rest() { }
344
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         { }
349
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         { }
354
355       _Uninitialized<_First> _M_first;
356       _Variadic_union<_Rest...> _M_rest;
357     };
358
359   // Defines index and the dtor, possibly trivial.
360   template<bool __trivially_destructible, typename... _Types>
361     struct _Variant_storage;
362
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;
368
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>... };
375
376       constexpr _Variant_storage() : _M_index(variant_npos) { }
377
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         { }
383
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         }
390
391       void _M_reset()
392       {
393         _M_reset_impl(std::index_sequence_for<_Types...>{});
394         _M_index = variant_npos;
395       }
396
397       ~_Variant_storage()
398       { _M_reset(); }
399
400       void*
401       _M_storage() const
402       {
403         return const_cast<void*>(static_cast<const void*>(
404             std::addressof(_M_u)));
405       }
406
407       constexpr bool
408       _M_valid() const noexcept
409       {
410         return this->_M_index != __index_type(variant_npos);
411       }
412
413       _Variadic_union<_Types...> _M_u;
414       using __index_type = __select_index<_Types...>;
415       __index_type _M_index;
416     };
417
418   template<typename... _Types>
419     struct _Variant_storage<true, _Types...>
420     {
421       constexpr _Variant_storage() : _M_index(variant_npos) { }
422
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         { }
428
429       void _M_reset()
430       { _M_index = variant_npos; }
431
432       void*
433       _M_storage() const
434       {
435         return const_cast<void*>(static_cast<const void*>(
436             std::addressof(_M_u)));
437       }
438
439       constexpr bool
440       _M_valid() const noexcept
441       {
442         return this->_M_index != __index_type(variant_npos);
443       }
444
445       _Variadic_union<_Types...> _M_u;
446       using __index_type = __select_index<_Types...>;
447       __index_type _M_index;
448     };
449
450   template<typename... _Types>
451     using _Variant_storage_alias =
452         _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
453
454   // The following are (Copy|Move) (ctor|assign) layers for forwarding
455   // triviality and handling non-trivial SMF behaviors.
456
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;
462
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       }
474
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     };
479
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     };
486
487   template<typename... _Types>
488     using _Copy_ctor_alias =
489         _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
490
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;
496
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       }
508
509       _Move_ctor_base(const _Move_ctor_base&) = default;
510       _Move_ctor_base& operator=(const _Move_ctor_base&) = default;
511       _Move_ctor_base& operator=(_Move_ctor_base&&) = default;
512     };
513
514   template<typename... _Types>
515     struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
516     {
517       using _Base = _Copy_ctor_alias<_Types...>;
518       using _Base::_Base;
519     };
520
521   template<typename... _Types>
522     using _Move_ctor_alias =
523         _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
524
525   template<bool, typename... _Types>
526     struct _Copy_assign_base : _Move_ctor_alias<_Types...>
527     {
528       using _Base = _Move_ctor_alias<_Types...>;
529       using _Base::_Base;
530
531       _Copy_assign_base&
532       operator=(const _Copy_assign_base& __rhs)
533           noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
534       {
535         if (this->_M_index == __rhs._M_index)
536           {
537             if (__rhs._M_valid())
538               {
539                 static constexpr void (*_S_vtable[])(void*, void*) =
540                   { &__erased_assign<_Types&, const _Types&>... };
541                 _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
542               }
543           }
544         else
545           {
546             _Copy_assign_base __tmp(__rhs);
547             this->~_Copy_assign_base();
548             __try
549               {
550                 ::new (this) _Copy_assign_base(std::move(__tmp));
551               }
552             __catch (...)
553               {
554                 this->_M_index = variant_npos;
555                 __throw_exception_again;
556               }
557           }
558         __glibcxx_assert(this->_M_index == __rhs._M_index);
559         return *this;
560       }
561
562       _Copy_assign_base(const _Copy_assign_base&) = default;
563       _Copy_assign_base(_Copy_assign_base&&) = default;
564       _Copy_assign_base& operator=(_Copy_assign_base&&) = default;
565     };
566
567   template<typename... _Types>
568     struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
569     {
570       using _Base = _Move_ctor_alias<_Types...>;
571       using _Base::_Base;
572     };
573
574   template<typename... _Types>
575     using _Copy_assign_alias =
576         _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign,
577                           _Types...>;
578
579   template<bool, typename... _Types>
580     struct _Move_assign_base : _Copy_assign_alias<_Types...>
581     {
582       using _Base = _Copy_assign_alias<_Types...>;
583       using _Base::_Base;
584
585       void _M_destructive_move(_Move_assign_base&& __rhs)
586       {
587         this->~_Move_assign_base();
588         __try
589           {
590             ::new (this) _Move_assign_base(std::move(__rhs));
591           }
592         __catch (...)
593           {
594             this->_M_index = variant_npos;
595             __throw_exception_again;
596           }
597       }
598
599       _Move_assign_base&
600       operator=(_Move_assign_base&& __rhs)
601           noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
602       {
603         if (this->_M_index == __rhs._M_index)
604           {
605             if (__rhs._M_valid())
606               {
607                 static constexpr void (*_S_vtable[])(void*, void*) =
608                   { &__erased_assign<_Types&, _Types&&>... };
609                 _S_vtable[__rhs._M_index]
610                   (this->_M_storage(), __rhs._M_storage());
611               }
612           }
613         else
614           {
615             _Move_assign_base __tmp(std::move(__rhs));
616             this->~_Move_assign_base();
617             __try
618               {
619                 ::new (this) _Move_assign_base(std::move(__tmp));
620               }
621             __catch (...)
622               {
623                 this->_M_index = variant_npos;
624                 __throw_exception_again;
625               }
626           }
627         __glibcxx_assert(this->_M_index == __rhs._M_index);
628         return *this;
629       }
630
631       _Move_assign_base(const _Move_assign_base&) = default;
632       _Move_assign_base(_Move_assign_base&&) = default;
633       _Move_assign_base& operator=(const _Move_assign_base&) = default;
634     };
635
636   template<typename... _Types>
637     struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
638     {
639       using _Base = _Copy_assign_alias<_Types...>;
640       using _Base::_Base;
641     };
642
643   template<typename... _Types>
644     using _Move_assign_alias =
645         _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign,
646                           _Types...>;
647
648   template<typename... _Types>
649     struct _Variant_base : _Move_assign_alias<_Types...>
650     {
651       using _Base = _Move_assign_alias<_Types...>;
652
653       constexpr
654       _Variant_base()
655           noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
656       : _Variant_base(in_place_index<0>) { }
657
658       template<size_t _Np, typename... _Args>
659         constexpr explicit
660         _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
661         : _Base(__i, std::forward<_Args>(__args)...)
662         { }
663
664       _Variant_base(const _Variant_base&) = default;
665       _Variant_base(_Variant_base&&) = default;
666       _Variant_base& operator=(const _Variant_base&) = default;
667       _Variant_base& operator=(_Variant_base&&) = default;
668     };
669
670   // For how many times does _Tp appear in _Tuple?
671   template<typename _Tp, typename _Tuple>
672     struct __tuple_count;
673
674   template<typename _Tp, typename _Tuple>
675     inline constexpr size_t __tuple_count_v =
676       __tuple_count<_Tp, _Tuple>::value;
677
678   template<typename _Tp, typename... _Types>
679     struct __tuple_count<_Tp, tuple<_Types...>>
680     : integral_constant<size_t, 0> { };
681
682   template<typename _Tp, typename _First, typename... _Rest>
683     struct __tuple_count<_Tp, tuple<_First, _Rest...>>
684     : integral_constant<
685         size_t,
686         __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
687
688   // TODO: Reuse this in <tuple> ?
689   template<typename _Tp, typename... _Types>
690     inline constexpr bool __exactly_once =
691       __tuple_count_v<_Tp, tuple<_Types...>> == 1;
692
693   // Takes _Types and create an overloaded _S_fun for each type.
694   // If a type appears more than once in _Types, create only one overload.
695   template<typename... _Types>
696     struct __overload_set
697     { static void _S_fun(); };
698
699   template<typename _First, typename... _Rest>
700     struct __overload_set<_First, _Rest...> : __overload_set<_Rest...>
701     {
702       using __overload_set<_Rest...>::_S_fun;
703       static integral_constant<size_t, sizeof...(_Rest)> _S_fun(_First);
704     };
705
706   template<typename... _Rest>
707     struct __overload_set<void, _Rest...> : __overload_set<_Rest...>
708     {
709       using __overload_set<_Rest...>::_S_fun;
710     };
711
712   // Helper for variant(_Tp&&) and variant::operator=(_Tp&&).
713   // __accepted_index maps the arbitrary _Tp to an alternative type in _Variant.
714   template<typename _Tp, typename _Variant, typename = void>
715     struct __accepted_index
716     { static constexpr size_t value = variant_npos; };
717
718   template<typename _Tp, typename... _Types>
719     struct __accepted_index<
720       _Tp, variant<_Types...>,
721       decltype(__overload_set<_Types...>::_S_fun(std::declval<_Tp>()),
722                std::declval<void>())>
723     {
724       static constexpr size_t value = sizeof...(_Types) - 1
725         - decltype(__overload_set<_Types...>::
726                    _S_fun(std::declval<_Tp>()))::value;
727     };
728
729   // Returns the raw storage for __v.
730   template<typename _Variant>
731     void* __get_storage(_Variant&& __v)
732     { return __v._M_storage(); }
733
734   // Used for storing multi-dimensional vtable.
735   template<typename _Tp, size_t... _Dimensions>
736     struct _Multi_array
737     {
738       constexpr const _Tp&
739       _M_access() const
740       { return _M_data; }
741
742       _Tp _M_data;
743     };
744
745   template<typename _Tp, size_t __first, size_t... __rest>
746     struct _Multi_array<_Tp, __first, __rest...>
747     {
748       template<typename... _Args>
749         constexpr const _Tp&
750         _M_access(size_t __first_index, _Args... __rest_indices) const
751         { return _M_arr[__first_index]._M_access(__rest_indices...); }
752
753       _Multi_array<_Tp, __rest...> _M_arr[__first];
754     };
755
756   // Creates a multi-dimensional vtable recursively.
757   //
758   // For example,
759   // visit([](auto, auto){},
760   //       variant<int, char>(),  // typedef'ed as V1
761   //       variant<float, double, long double>())  // typedef'ed as V2
762   // will trigger instantiations of:
763   // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>,
764   //                   tuple<V1&&, V2&&>, std::index_sequence<>>
765   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
766   //                     tuple<V1&&, V2&&>, std::index_sequence<0>>
767   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
768   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 0>>
769   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
770   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 1>>
771   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
772   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 2>>
773   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
774   //                     tuple<V1&&, V2&&>, std::index_sequence<1>>
775   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
776   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 0>>
777   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
778   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 1>>
779   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
780   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 2>>
781   // The returned multi-dimensional vtable can be fast accessed by the visitor
782   // using index calculation.
783   template<typename _Array_type, typename _Variant_tuple, typename _Index_seq>
784     struct __gen_vtable_impl;
785
786   template<typename _Result_type, typename _Visitor, size_t... __dimensions,
787            typename... _Variants, size_t... __indices>
788     struct __gen_vtable_impl<
789         _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
790         tuple<_Variants...>, std::index_sequence<__indices...>>
791     {
792       using _Next =
793           remove_reference_t<typename _Nth_type<sizeof...(__indices),
794                              _Variants...>::type>;
795       using _Array_type =
796           _Multi_array<_Result_type (*)(_Visitor, _Variants...),
797                        __dimensions...>;
798
799       static constexpr _Array_type
800       _S_apply()
801       {
802         _Array_type __vtable{};
803         _S_apply_all_alts(
804           __vtable, make_index_sequence<variant_size_v<_Next>>());
805         return __vtable;
806       }
807
808       template<size_t... __var_indices>
809         static constexpr void
810         _S_apply_all_alts(_Array_type& __vtable,
811                           std::index_sequence<__var_indices...>)
812         {
813           (_S_apply_single_alt<__var_indices>(
814              __vtable._M_arr[__var_indices]), ...);
815         }
816
817       template<size_t __index, typename _Tp>
818         static constexpr void
819         _S_apply_single_alt(_Tp& __element)
820         {
821           using _Alternative = variant_alternative_t<__index, _Next>;
822           __element = __gen_vtable_impl<
823             remove_reference_t<
824               decltype(__element)>, tuple<_Variants...>,
825               std::index_sequence<__indices..., __index>>::_S_apply();
826         }
827     };
828
829   template<typename _Result_type, typename _Visitor, typename... _Variants,
830            size_t... __indices>
831     struct __gen_vtable_impl<
832       _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
833                    tuple<_Variants...>, std::index_sequence<__indices...>>
834     {
835       using _Array_type =
836           _Multi_array<_Result_type (*)(_Visitor&&, _Variants...)>;
837
838       decltype(auto)
839       static constexpr __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
840       {
841         return __invoke(std::forward<_Visitor>(__visitor),
842                         std::get<__indices>(
843                             std::forward<_Variants>(__vars))...);
844       }
845
846       static constexpr auto
847       _S_apply()
848       { return _Array_type{&__visit_invoke}; }
849     };
850
851   template<typename _Result_type, typename _Visitor, typename... _Variants>
852     struct __gen_vtable
853     {
854       using _Func_ptr = _Result_type (*)(_Visitor&&, _Variants...);
855       using _Array_type =
856           _Multi_array<_Func_ptr,
857                        variant_size_v<remove_reference_t<_Variants>>...>;
858
859       static constexpr _Array_type
860       _S_apply()
861       {
862         return __gen_vtable_impl<_Array_type, tuple<_Variants...>,
863                                  std::index_sequence<>>::_S_apply();
864       }
865
866       static constexpr auto _S_vtable = _S_apply();
867     };
868
869   template<size_t _Np, typename _Tp>
870     struct _Base_dedup : public _Tp { };
871
872   template<typename _Variant, typename __indices>
873     struct _Variant_hash_base;
874
875   template<typename... _Types, size_t... __indices>
876     struct _Variant_hash_base<variant<_Types...>,
877                               std::index_sequence<__indices...>>
878     : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
879
880 } // namespace __variant
881 } // namespace __detail
882
883   template<typename _Tp, typename... _Types>
884     inline constexpr bool holds_alternative(const variant<_Types...>& __v)
885     noexcept
886     {
887       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
888                     "T should occur for exactly once in alternatives");
889       return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>;
890     }
891
892   template<typename _Tp, typename... _Types>
893     constexpr inline _Tp& get(variant<_Types...>& __v)
894     {
895       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
896                     "T should occur for exactly once in alternatives");
897       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
898       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
899     }
900
901   template<typename _Tp, typename... _Types>
902     constexpr inline _Tp&& get(variant<_Types...>&& __v)
903     {
904       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
905                     "T should occur for exactly once in alternatives");
906       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
907       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
908         std::move(__v));
909     }
910
911   template<typename _Tp, typename... _Types>
912     constexpr inline const _Tp& get(const variant<_Types...>& __v)
913     {
914       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
915                     "T should occur for exactly once in alternatives");
916       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
917       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
918     }
919
920   template<typename _Tp, typename... _Types>
921     constexpr inline const _Tp&& get(const variant<_Types...>&& __v)
922     {
923       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
924                     "T should occur for exactly once in alternatives");
925       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
926       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
927         std::move(__v));
928     }
929
930   template<size_t _Np, typename... _Types>
931     constexpr inline
932     add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
933     get_if(variant<_Types...>* __ptr) noexcept
934     {
935       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
936       static_assert(_Np < sizeof...(_Types),
937                     "The index should be in [0, number of alternatives)");
938       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
939       if (__ptr && __ptr->index() == _Np)
940         return &__detail::__variant::__get<_Np>(*__ptr);
941       return nullptr;
942     }
943
944   template<size_t _Np, typename... _Types>
945     constexpr inline
946     add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
947     get_if(const variant<_Types...>* __ptr) noexcept
948     {
949       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
950       static_assert(_Np < sizeof...(_Types),
951                     "The index should be in [0, number of alternatives)");
952       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
953       if (__ptr && __ptr->index() == _Np)
954         return &__detail::__variant::__get<_Np>(*__ptr);
955       return nullptr;
956     }
957
958   template<typename _Tp, typename... _Types>
959     constexpr inline add_pointer_t<_Tp>
960     get_if(variant<_Types...>* __ptr) 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     }
968
969   template<typename _Tp, typename... _Types>
970     constexpr inline add_pointer_t<const _Tp>
971     get_if(const variant<_Types...>* __ptr)
972     noexcept
973     {
974       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
975                     "T should occur for exactly once in alternatives");
976       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
977       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
978           __ptr);
979     }
980
981   struct monostate { };
982
983 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
984   template<typename... _Types> \
985     constexpr bool operator __OP(const variant<_Types...>& __lhs, \
986                                  const variant<_Types...>& __rhs) \
987     { \
988       return __lhs._M_##__NAME(__rhs, std::index_sequence_for<_Types...>{}); \
989     } \
990 \
991   constexpr bool operator __OP(monostate, monostate) noexcept \
992   { return 0 __OP 0; }
993
994   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
995   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
996   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
997   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
998   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
999   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1000
1001 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1002
1003   template<typename _Visitor, typename... _Variants>
1004     constexpr decltype(auto) visit(_Visitor&&, _Variants&&...);
1005
1006   template<typename... _Types>
1007     inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1008                         && (is_swappable_v<_Types> && ...)>
1009     swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1010     noexcept(noexcept(__lhs.swap(__rhs)))
1011     { __lhs.swap(__rhs); }
1012
1013   template<typename... _Types>
1014     enable_if_t<!((is_move_constructible_v<_Types> && ...)
1015                    && (is_swappable_v<_Types> && ...))>
1016     swap(variant<_Types...>&, variant<_Types...>&) = delete;
1017
1018   class bad_variant_access : public exception
1019   {
1020   public:
1021     bad_variant_access() noexcept : _M_reason("Unknown reason") { }
1022     const char* what() const noexcept override
1023     { return _M_reason; }
1024
1025   private:
1026     bad_variant_access(const char* __reason) : _M_reason(__reason) { }
1027
1028     const char* _M_reason;
1029
1030     friend void __throw_bad_variant_access(const char* __what);
1031   };
1032
1033   inline void
1034   __throw_bad_variant_access(const char* __what)
1035   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1036
1037   template<typename... _Types>
1038     class variant
1039     : private __detail::__variant::_Variant_base<_Types...>,
1040       private _Enable_default_constructor<
1041         __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1042           variant<_Types...>>,
1043       private _Enable_copy_move<
1044         __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1045         __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1046         __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1047         __detail::__variant::_Traits<_Types...>::_S_move_assign,
1048         variant<_Types...>>
1049     {
1050     private:
1051       static_assert(sizeof...(_Types) > 0,
1052                     "variant must have at least one alternative");
1053       static_assert(!(std::is_reference_v<_Types> || ...),
1054                     "variant must have no reference alternative");
1055       static_assert(!(std::is_void_v<_Types> || ...),
1056                     "variant must have no void alternative");
1057
1058       using _Base = __detail::__variant::_Variant_base<_Types...>;
1059       using _Default_ctor_enabler =
1060         _Enable_default_constructor<
1061           __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1062             variant<_Types...>>;
1063
1064       template<typename _Tp>
1065         static constexpr bool
1066         __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1067
1068       template<typename _Tp>
1069         static constexpr size_t __accepted_index =
1070           __detail::__variant::__accepted_index<_Tp&&, variant>::value;
1071
1072       template<size_t _Np, bool = _Np < sizeof...(_Types)>
1073         struct __to_type_impl;
1074
1075       template<size_t _Np>
1076         struct __to_type_impl<_Np, true>
1077         { using type = variant_alternative_t<_Np, variant>; };
1078
1079       template<size_t _Np>
1080         using __to_type = typename __to_type_impl<_Np>::type;
1081
1082       template<typename _Tp>
1083         using __accepted_type = __to_type<__accepted_index<_Tp>>;
1084
1085       template<typename _Tp>
1086         static constexpr size_t __index_of =
1087           __detail::__variant::__index_of_v<_Tp, _Types...>;
1088
1089       using _Traits = __detail::__variant::_Traits<_Types...>;
1090
1091     public:
1092       variant() = default;
1093       variant(const variant& __rhs) = default;
1094       variant(variant&&) = default;
1095       variant& operator=(const variant&) = default;
1096       variant& operator=(variant&&) = default;
1097       ~variant() = default;
1098
1099       template<typename _Tp,
1100                typename = enable_if_t<!is_same_v<decay_t<_Tp>, variant>>,
1101                typename = enable_if_t<(sizeof...(_Types)>0)>,
1102                typename = enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1103                           && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>>>
1104         constexpr
1105         variant(_Tp&& __t)
1106         noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1107         : variant(in_place_index<__accepted_index<_Tp&&>>,
1108                   std::forward<_Tp>(__t))
1109         { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
1110
1111       template<typename _Tp, typename... _Args,
1112                typename = enable_if_t<__exactly_once<_Tp>
1113                           && is_constructible_v<_Tp, _Args&&...>>>
1114         constexpr explicit
1115         variant(in_place_type_t<_Tp>, _Args&&... __args)
1116         : variant(in_place_index<__index_of<_Tp>>,
1117                   std::forward<_Args>(__args)...)
1118         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1119
1120       template<typename _Tp, typename _Up, typename... _Args,
1121                typename = enable_if_t<__exactly_once<_Tp>
1122                           && is_constructible_v<
1123                             _Tp, initializer_list<_Up>&, _Args&&...>>>
1124         constexpr explicit
1125         variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1126                 _Args&&... __args)
1127         : variant(in_place_index<__index_of<_Tp>>, __il,
1128                   std::forward<_Args>(__args)...)
1129         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1130
1131       template<size_t _Np, typename... _Args,
1132                typename = enable_if_t<
1133                  is_constructible_v<__to_type<_Np>, _Args&&...>>>
1134         constexpr explicit
1135         variant(in_place_index_t<_Np>, _Args&&... __args)
1136         : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
1137         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1138         { __glibcxx_assert(index() == _Np); }
1139
1140       template<size_t _Np, typename _Up, typename... _Args,
1141                typename = enable_if_t<is_constructible_v<__to_type<_Np>,
1142                                       initializer_list<_Up>&, _Args&&...>>>
1143         constexpr explicit
1144         variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1145                 _Args&&... __args)
1146         : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1147         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1148         { __glibcxx_assert(index() == _Np); }
1149
1150       template<typename _Tp>
1151         enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1152                     && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>
1153                     && is_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1154                     && !is_same_v<decay_t<_Tp>, variant>, variant&>
1155         operator=(_Tp&& __rhs)
1156         noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1157                  && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1158         {
1159           constexpr auto __index = __accepted_index<_Tp&&>;
1160           if (index() == __index)
1161             std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1162           else
1163             this->emplace<__index>(std::forward<_Tp>(__rhs));
1164           __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this));
1165           return *this;
1166         }
1167
1168       template<typename _Tp, typename... _Args>
1169         enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1170                     _Tp&>
1171         emplace(_Args&&... __args)
1172         {
1173           auto& ret =
1174             this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...);
1175           __glibcxx_assert(holds_alternative<_Tp>(*this));
1176           return ret;
1177         }
1178
1179       template<typename _Tp, typename _Up, typename... _Args>
1180         enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1181                     && __exactly_once<_Tp>,
1182                     _Tp&>
1183         emplace(initializer_list<_Up> __il, _Args&&... __args)
1184         {
1185           auto& ret =
1186             this->emplace<__index_of<_Tp>>(__il,
1187                                            std::forward<_Args>(__args)...);
1188           __glibcxx_assert(holds_alternative<_Tp>(*this));
1189           return ret;
1190         }
1191
1192       template<size_t _Np, typename... _Args>
1193         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1194                                        _Args...>,
1195                     variant_alternative_t<_Np, variant>&>
1196         emplace(_Args&&... __args)
1197         {
1198           static_assert(_Np < sizeof...(_Types),
1199                         "The index should be in [0, number of alternatives)");
1200           this->~variant();
1201           __try
1202             {
1203               ::new (this) variant(in_place_index<_Np>,
1204                                    std::forward<_Args>(__args)...);
1205             }
1206           __catch (...)
1207             {
1208               this->_M_index = variant_npos;
1209               __throw_exception_again;
1210             }
1211           __glibcxx_assert(index() == _Np);
1212           return std::get<_Np>(*this);
1213         }
1214
1215       template<size_t _Np, typename _Up, typename... _Args>
1216         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1217                                        initializer_list<_Up>&, _Args...>,
1218                     variant_alternative_t<_Np, variant>&>
1219         emplace(initializer_list<_Up> __il, _Args&&... __args)
1220         {
1221           static_assert(_Np < sizeof...(_Types),
1222                         "The index should be in [0, number of alternatives)");
1223           this->~variant();
1224           __try
1225             {
1226               ::new (this) variant(in_place_index<_Np>, __il,
1227                                    std::forward<_Args>(__args)...);
1228             }
1229           __catch (...)
1230             {
1231               this->_M_index = variant_npos;
1232               __throw_exception_again;
1233             }
1234           __glibcxx_assert(index() == _Np);
1235           return std::get<_Np>(*this);
1236         }
1237
1238       constexpr bool valueless_by_exception() const noexcept
1239       { return !this->_M_valid(); }
1240
1241       constexpr size_t index() const noexcept
1242       {
1243         if (this->_M_index ==
1244             typename _Base::__index_type(variant_npos))
1245           return variant_npos;
1246         return this->_M_index;
1247       }
1248
1249       void
1250       swap(variant& __rhs)
1251       noexcept((__is_nothrow_swappable<_Types>::value && ...)
1252                && is_nothrow_move_constructible_v<variant>)
1253       {
1254         if (this->index() == __rhs.index())
1255           {
1256             if (this->_M_valid())
1257               {
1258                 static constexpr void (*_S_vtable[])(void*, void*) =
1259                   { &__detail::__variant::__erased_swap<_Types&, _Types&>... };
1260                 _S_vtable[__rhs._M_index](this->_M_storage(),
1261                                           __rhs._M_storage());
1262               }
1263           }
1264         else if (!this->_M_valid())
1265           {
1266             this->_M_destructive_move(std::move(__rhs));
1267             __rhs._M_reset();
1268           }
1269         else if (!__rhs._M_valid())
1270           {
1271             __rhs._M_destructive_move(std::move(*this));
1272             this->_M_reset();
1273           }
1274         else
1275           {
1276             auto __tmp = std::move(__rhs);
1277             __rhs._M_destructive_move(std::move(*this));
1278             this->_M_destructive_move(std::move(__tmp));
1279           }
1280       }
1281
1282     private:
1283 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1284       template<size_t... __indices> \
1285         static constexpr bool \
1286         (*_S_erased_##__NAME[])(const variant&, const variant&) = \
1287           { &__detail::__variant::__erased_##__NAME< \
1288                 const variant&, __indices>... }; \
1289       template<size_t... __indices> \
1290         constexpr inline bool \
1291         _M_##__NAME(const variant& __rhs, \
1292                     std::index_sequence<__indices...>) const \
1293         { \
1294           auto __lhs_index = this->index(); \
1295           auto __rhs_index = __rhs.index(); \
1296           if (__lhs_index != __rhs_index || valueless_by_exception()) \
1297             /* Modulo addition. */ \
1298             return __lhs_index + 1 __OP __rhs_index + 1; \
1299           return _S_erased_##__NAME<__indices...>[__lhs_index](*this, __rhs); \
1300         }
1301
1302       _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1303       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1304       _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1305       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1306       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1307       _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1308
1309 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1310
1311 #ifdef __clang__
1312     public:
1313       using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852
1314     private:
1315 #endif
1316
1317       template<size_t _Np, typename _Vp>
1318         friend constexpr decltype(auto) __detail::__variant::__get(_Vp&& __v);
1319
1320       template<typename _Vp>
1321         friend void* __detail::__variant::__get_storage(_Vp&& __v);
1322
1323 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1324       template<typename... _Tp> \
1325         friend constexpr bool \
1326         operator __OP(const variant<_Tp...>& __lhs, \
1327                       const variant<_Tp...>& __rhs);
1328
1329       _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1330       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1331       _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1332       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1333       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1334       _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1335
1336 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1337     };
1338
1339   template<size_t _Np, typename... _Types>
1340     constexpr variant_alternative_t<_Np, variant<_Types...>>&
1341     get(variant<_Types...>& __v)
1342     {
1343       static_assert(_Np < sizeof...(_Types),
1344                     "The index should be in [0, number of alternatives)");
1345       if (__v.index() != _Np)
1346         __throw_bad_variant_access("Unexpected index");
1347       return __detail::__variant::__get<_Np>(__v);
1348     }
1349
1350   template<size_t _Np, typename... _Types>
1351     constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1352     get(variant<_Types...>&& __v)
1353     {
1354       static_assert(_Np < sizeof...(_Types),
1355                     "The index should be in [0, number of alternatives)");
1356       if (__v.index() != _Np)
1357         __throw_bad_variant_access("Unexpected index");
1358       return __detail::__variant::__get<_Np>(std::move(__v));
1359     }
1360
1361   template<size_t _Np, typename... _Types>
1362     constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1363     get(const variant<_Types...>& __v)
1364     {
1365       static_assert(_Np < sizeof...(_Types),
1366                     "The index should be in [0, number of alternatives)");
1367       if (__v.index() != _Np)
1368         __throw_bad_variant_access("Unexpected index");
1369       return __detail::__variant::__get<_Np>(__v);
1370     }
1371
1372   template<size_t _Np, typename... _Types>
1373     constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1374     get(const variant<_Types...>&& __v)
1375     {
1376       static_assert(_Np < sizeof...(_Types),
1377                     "The index should be in [0, number of alternatives)");
1378       if (__v.index() != _Np)
1379         __throw_bad_variant_access("Unexpected index");
1380       return __detail::__variant::__get<_Np>(std::move(__v));
1381     }
1382
1383   template<typename _Visitor, typename... _Variants>
1384     constexpr decltype(auto)
1385     visit(_Visitor&& __visitor, _Variants&&... __variants)
1386     {
1387       if ((__variants.valueless_by_exception() || ...))
1388         __throw_bad_variant_access("Unexpected index");
1389
1390       using _Result_type =
1391         decltype(std::forward<_Visitor>(__visitor)(
1392             get<0>(std::forward<_Variants>(__variants))...));
1393
1394       constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1395         _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1396
1397       auto __func_ptr = __vtable._M_access(__variants.index()...);
1398       return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1399                            std::forward<_Variants>(__variants)...);
1400     }
1401
1402   template<bool, typename... _Types>
1403     struct __variant_hash_call_base_impl
1404     {
1405       size_t
1406       operator()(const variant<_Types...>& __t) const
1407       noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1408       {
1409         if (!__t.valueless_by_exception())
1410           {
1411             namespace __edv = __detail::__variant;
1412             static constexpr size_t (*_S_vtable[])(void*) =
1413               { &__edv::__erased_hash<const _Types&>... };
1414             return hash<size_t>{}(__t.index())
1415               + _S_vtable[__t.index()](__edv::__get_storage(__t));
1416           }
1417         return hash<size_t>{}(__t.index());
1418       }
1419     };
1420
1421   template<typename... _Types>
1422     struct __variant_hash_call_base_impl<false, _Types...> {};
1423
1424   template<typename... _Types>
1425     using __variant_hash_call_base =
1426     __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
1427                                    __enable_hash_call &&...), _Types...>;
1428
1429   template<typename... _Types>
1430     struct hash<variant<_Types...>>
1431     : private __detail::__variant::_Variant_hash_base<
1432         variant<_Types...>, std::index_sequence_for<_Types...>>,
1433       public __variant_hash_call_base<_Types...>
1434     {
1435       using result_type [[__deprecated__]] = size_t;
1436       using argument_type [[__deprecated__]] = variant<_Types...>;
1437     };
1438
1439   template<>
1440     struct hash<monostate>
1441     {
1442       using result_type [[__deprecated__]] = size_t;
1443       using argument_type [[__deprecated__]] = monostate;
1444
1445       size_t
1446       operator()(const monostate& __t) const noexcept
1447       {
1448         constexpr size_t __magic_monostate_hash = -7777;
1449         return __magic_monostate_hash;
1450       }
1451     };
1452
1453   template<typename... _Types>
1454     struct __is_fast_hash<hash<variant<_Types...>>>
1455     : bool_constant<(__is_fast_hash<_Types>::value && ...)>
1456     { };
1457
1458 _GLIBCXX_END_NAMESPACE_VERSION
1459 } // namespace std
1460
1461 #endif // C++17
1462
1463 #endif // _GLIBCXX_VARIANT