Implement LWG 2766,
[platform/upstream/gcc.git] / libstdc++-v3 / include / std / variant
1 // <variant> -*- C++ -*-
2
3 // Copyright (C) 2016 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 <= 201402L
35 # include <bits/c++17_warning.h>
36 #else
37
38 #include <type_traits>
39 #include <utility>
40 #include <bits/enable_special_members.h>
41 #include <bits/functexcept.h>
42 #include <bits/move.h>
43 #include <bits/uses_allocator.h>
44 #include <bits/functional_hash.h>
45
46 namespace std _GLIBCXX_VISIBILITY(default)
47 {
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
49
50   template<typename... _Types> class tuple;
51   template<typename... _Types> class variant;
52   template <typename> struct hash;
53
54   template<typename _Variant>
55     struct variant_size;
56
57   template<typename _Variant>
58     struct variant_size<const _Variant> : variant_size<_Variant> {};
59
60   template<typename _Variant>
61     struct variant_size<volatile _Variant> : variant_size<_Variant> {};
62
63   template<typename _Variant>
64     struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
65
66   template<typename... _Types>
67     struct variant_size<variant<_Types...>>
68     : std::integral_constant<size_t, sizeof...(_Types)> {};
69
70   template<typename _Variant>
71     constexpr size_t variant_size_v = variant_size<_Variant>::value;
72
73   template<size_t _Np, typename _Variant>
74     struct variant_alternative;
75
76   template<size_t _Np, typename _First, typename... _Rest>
77     struct variant_alternative<_Np, variant<_First, _Rest...>>
78     : variant_alternative<_Np-1, variant<_Rest...>> {};
79
80   template<typename _First, typename... _Rest>
81     struct variant_alternative<0, variant<_First, _Rest...>>
82     { using type = _First; };
83
84   template<size_t _Np, typename _Variant>
85     using variant_alternative_t =
86       typename variant_alternative<_Np, _Variant>::type;
87
88   template<size_t _Np, typename _Variant>
89     struct variant_alternative<_Np, const _Variant>
90     { using type = add_const_t<variant_alternative_t<_Np, _Variant>>; };
91
92   template<size_t _Np, typename _Variant>
93     struct variant_alternative<_Np, volatile _Variant>
94     { using type = add_volatile_t<variant_alternative_t<_Np, _Variant>>; };
95
96   template<size_t _Np, typename _Variant>
97     struct variant_alternative<_Np, const volatile _Variant>
98     { using type = add_cv_t<variant_alternative_t<_Np, _Variant>>; };
99
100   constexpr size_t variant_npos = -1;
101
102 _GLIBCXX_END_NAMESPACE_VERSION
103
104 namespace __detail
105 {
106 namespace __variant
107 {
108 _GLIBCXX_BEGIN_NAMESPACE_VERSION
109   // Returns the first apparence of _Tp in _Types.
110   // Returns sizeof...(_Types) if _Tp is not in _Types.
111   template<typename _Tp, typename... _Types>
112     struct __index_of : std::integral_constant<size_t, 0> {};
113
114   template<typename _Tp, typename... _Types>
115     constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value;
116
117   template<typename _Tp, typename _First, typename... _Rest>
118     struct __index_of<_Tp, _First, _Rest...> :
119       std::integral_constant<size_t, is_same_v<_Tp, _First>
120         ? 0 : __index_of_v<_Tp, _Rest...> + 1> {};
121
122   // Extract _From's qualifiers and references and apply it to _To.
123   // __reserved_type_map<const int&, char> is const char&.
124   template<typename _From, typename _To>
125     struct __reserved_type_map_impl
126     { using type = _To; };
127
128   template<typename _From, typename _To>
129     using __reserved_type_map =
130       typename __reserved_type_map_impl<_From, _To>::type;
131
132   template<typename _From, typename _To>
133     struct __reserved_type_map_impl<_From&, _To>
134     { using type = add_lvalue_reference_t<__reserved_type_map<_From, _To>>; };
135
136   template<typename _From, typename _To>
137     struct __reserved_type_map_impl<_From&&, _To>
138     { using type = add_rvalue_reference_t<__reserved_type_map<_From, _To>>; };
139
140   template<typename _From, typename _To>
141     struct __reserved_type_map_impl<const _From, _To>
142     { using type = add_const_t<__reserved_type_map<_From, _To>>; };
143
144   template<typename _From, typename _To>
145     struct __reserved_type_map_impl<volatile _From, _To>
146     { using type = add_volatile_t<__reserved_type_map<_From, _To>>; };
147
148   template<typename _From, typename _To>
149     struct __reserved_type_map_impl<const volatile _From, _To>
150     { using type = add_cv_t<__reserved_type_map<_From, _To>>; };
151
152   // This abstraction might be useful for future features,
153   // e.g. boost::recursive_wrapper.
154   template<typename _Alternative>
155     using __storage = _Alternative;
156
157   template<typename _Type, bool __is_literal = std::is_literal_type_v<_Type>>
158     struct _Uninitialized;
159
160   template<typename _Type>
161     struct _Uninitialized<_Type, true>
162     {
163       constexpr _Uninitialized() = default;
164
165       template<typename... _Args>
166       constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args)
167       : _M_storage(std::forward<_Args>(__args)...)
168       { }
169
170       _Type _M_storage;
171     };
172
173   template<typename _Type>
174     struct _Uninitialized<_Type, false>
175     {
176       constexpr _Uninitialized() = default;
177
178       template<typename... _Args>
179       constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args)
180       { ::new (&_M_storage) _Type(std::forward<_Args>(__args)...); }
181
182       typename std::aligned_storage<sizeof(_Type), alignof(_Type)>::type
183           _M_storage;
184     };
185
186   // Given a qualified storage type, return the desired reference.
187   // For example, variant<int>&& stores the int as __storage<int>, and
188   // _Qualified_storage will be __storage<int>&&.
189   template<typename _Qualified_storage>
190     decltype(auto)
191     __get_alternative(void* __ptr)
192     {
193       using _Storage = decay_t<_Qualified_storage>;
194       return __reserved_type_map<_Qualified_storage, _Storage>(
195         *static_cast<_Storage*>(__ptr));
196     }
197
198   // Various functions as "vtable" entries, where those vtables are used by
199   // polymorphic operations.
200   template<typename _Lhs, typename _Rhs>
201     constexpr void
202     __erased_ctor(void* __lhs, void* __rhs)
203     { ::new (__lhs) decay_t<_Lhs>(__get_alternative<_Rhs>(__rhs)); }
204
205   template<typename _Alloc, typename _Lhs, typename _Rhs>
206     constexpr void
207     __erased_use_alloc_ctor(const _Alloc& __a, void* __lhs, void* __rhs)
208     {
209       __uses_allocator_construct(__a, static_cast<decay_t<_Lhs>*>(__lhs),
210                                  __get_alternative<_Rhs>(__rhs));
211     }
212
213   // TODO: Find a potential chance to reuse this accross the project.
214   template<typename _Tp>
215     constexpr void
216     __erased_dtor(void* __ptr)
217     {
218       using _Storage = decay_t<_Tp>;
219       static_cast<_Storage*>(__ptr)->~_Storage();
220     }
221
222   template<typename _Lhs, typename _Rhs>
223     constexpr void
224     __erased_assign(void* __lhs, void* __rhs)
225     { __get_alternative<_Lhs>(__lhs) = __get_alternative<_Rhs>(__rhs); }
226
227   template<typename _Lhs, typename _Rhs>
228     constexpr void
229     __erased_swap(void* __lhs, void* __rhs)
230     {
231       using std::swap;
232       swap(__get_alternative<_Lhs>(__lhs), __get_alternative<_Rhs>(__rhs));
233     }
234
235   template<typename _Lhs, typename _Rhs>
236     constexpr bool
237     __erased_equal_to(void* __lhs, void* __rhs)
238     { return __get_alternative<_Lhs>(__lhs) == __get_alternative<_Rhs>(__rhs); }
239
240   template<typename _Lhs, typename _Rhs>
241     constexpr bool
242     __erased_less_than(void* __lhs, void* __rhs)
243     { return __get_alternative<_Lhs>(__lhs) < __get_alternative<_Rhs>(__rhs); }
244
245   template<typename _Tp>
246     constexpr size_t
247     __erased_hash(void* __t)
248     { return std::hash<decay_t<_Tp>>{}(__get_alternative<_Tp>(__t)); }
249
250   template<typename... _Types>
251     struct _Variant_base;
252
253   template<typename... _Types>
254     struct _Variant_storage
255     { constexpr _Variant_storage() = default; };
256
257   // Use recursive unions to implement a trivially destructible variant.
258   template<typename _First, typename... _Rest>
259     struct _Variant_storage<_First, _Rest...>
260     {
261       constexpr _Variant_storage() = default;
262
263       template<size_t _Np, typename... _Args>
264         constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
265         : _M_union(in_place_index<_Np>, std::forward<_Args>(__args)...)
266         { }
267
268       ~_Variant_storage() = default;
269
270       constexpr void*
271       _M_storage() const
272       {
273         return const_cast<void*>(
274           static_cast<const void*>(std::addressof(_M_union._M_first._M_storage)));
275       }
276
277       union _Union
278       {
279         constexpr _Union() {};
280
281         template<typename... _Args>
282           constexpr _Union(in_place_index_t<0>, _Args&&... __args)
283           : _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
284           { }
285
286         template<size_t _Np, typename... _Args,
287                  typename = enable_if_t<0 < _Np && _Np < sizeof...(_Rest) + 1>>
288           constexpr _Union(in_place_index_t<_Np>, _Args&&... __args)
289           : _M_rest(in_place_index<_Np - 1>, std::forward<_Args>(__args)...)
290           { }
291
292         _Uninitialized<__storage<_First>> _M_first;
293         _Variant_storage<_Rest...> _M_rest;
294       } _M_union;
295     };
296
297   template<typename _Derived, bool __is_trivially_destructible>
298     struct _Dtor_mixin
299     {
300       ~_Dtor_mixin()
301       { static_cast<_Derived*>(this)->_M_destroy(); }
302     };
303
304   template<typename _Derived>
305     struct _Dtor_mixin<_Derived, true>
306     {
307       ~_Dtor_mixin() = default;
308     };
309
310   // Helps SFINAE on special member functions. Otherwise it can live in variant
311   // class.
312   template<typename... _Types>
313     struct _Variant_base :
314       _Variant_storage<_Types...>,
315       _Dtor_mixin<_Variant_base<_Types...>,
316                   __and_<std::is_trivially_destructible<_Types>...>::value>
317     {
318       using _Storage = _Variant_storage<_Types...>;
319
320       constexpr
321       _Variant_base()
322       noexcept(is_nothrow_default_constructible_v<
323                  variant_alternative_t<0, variant<_Types...>>>)
324       : _Variant_base(in_place_index<0>) { }
325
326       _Variant_base(const _Variant_base& __rhs)
327       : _Storage(), _M_index(__rhs._M_index)
328       {
329         if (__rhs._M_valid())
330           {
331             static constexpr void (*_S_vtable[])(void*, void*) =
332               { &__erased_ctor<__storage<_Types>&,
333                                const __storage<_Types>&>... };
334             _S_vtable[__rhs._M_index](_M_storage(), __rhs._M_storage());
335           }
336       }
337
338       _Variant_base(_Variant_base&& __rhs)
339       noexcept(__and_<is_nothrow_move_constructible<_Types>...>::value)
340       : _Storage(), _M_index(__rhs._M_index)
341       {
342         if (__rhs._M_valid())
343           {
344             static constexpr void (*_S_vtable[])(void*, void*) =
345               { &__erased_ctor<__storage<_Types>&, __storage<_Types>&&>... };
346             _S_vtable[__rhs._M_index](_M_storage(), __rhs._M_storage());
347           }
348       }
349
350       template<size_t _Np, typename... _Args>
351         constexpr explicit
352         _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
353         : _Storage(__i, std::forward<_Args>(__args)...), _M_index(_Np)
354         { }
355
356       template<typename _Alloc>
357         _Variant_base(const _Alloc& __a, const _Variant_base& __rhs)
358         : _Storage(), _M_index(__rhs._M_index)
359         {
360           if (__rhs._M_valid())
361             {
362               static constexpr void
363               (*_S_vtable[])(const _Alloc&, void*, void*) =
364                 { &__erased_use_alloc_ctor<_Alloc, __storage<_Types>&,
365                                            const __storage<_Types>&>... };
366               _S_vtable[__rhs._M_index](__a, _M_storage(), __rhs._M_storage());
367             }
368         }
369
370       template<typename _Alloc>
371         _Variant_base(const _Alloc& __a, _Variant_base&& __rhs)
372         : _Storage(), _M_index(__rhs._M_index)
373         {
374           if (__rhs._M_valid())
375             {
376               static constexpr void
377               (*_S_vtable[])(const _Alloc&, void*, void*) =
378                 { &__erased_use_alloc_ctor<_Alloc, __storage<_Types>&,
379                                            __storage<_Types>&&>... };
380               _S_vtable[__rhs._M_index](__a, _M_storage(), __rhs._M_storage());
381             }
382         }
383
384       template<typename _Alloc, size_t _Np, typename... _Args>
385         constexpr explicit
386         _Variant_base(const _Alloc& __a, in_place_index_t<_Np>,
387                       _Args&&... __args)
388         : _Storage(), _M_index(_Np)
389         {
390           using _Storage =
391             __storage<variant_alternative_t<_Np, variant<_Types...>>>;
392           __uses_allocator_construct(__a, static_cast<_Storage*>(_M_storage()),
393                                      std::forward<_Args>(__args)...);
394           __glibcxx_assert(_M_index == _Np);
395         }
396
397       _Variant_base&
398       operator=(const _Variant_base& __rhs)
399       {
400         if (_M_index == __rhs._M_index)
401           {
402             if (__rhs._M_valid())
403               {
404                 static constexpr void (*_S_vtable[])(void*, void*) =
405                   { &__erased_assign<__storage<_Types>&,
406                                      const __storage<_Types>&>... };
407                 _S_vtable[__rhs._M_index](_M_storage(), __rhs._M_storage());
408               }
409           }
410         else
411           {
412             _Variant_base __tmp(__rhs);
413             this->~_Variant_base();
414             __try
415               {
416                 ::new (this) _Variant_base(std::move(__tmp));
417               }
418             __catch (...)
419               {
420                 _M_index = variant_npos;
421                 __throw_exception_again;
422               }
423           }
424         __glibcxx_assert(_M_index == __rhs._M_index);
425         return *this;
426       }
427
428       _Variant_base&
429       operator=(_Variant_base&& __rhs)
430       noexcept(__and_<is_nothrow_move_constructible<_Types>...,
431                       is_nothrow_move_assignable<_Types>...>::value)
432       {
433         if (_M_index == __rhs._M_index)
434           {
435             if (__rhs._M_valid())
436               {
437                 static constexpr void (*_S_vtable[])(void*, void*) =
438                   { &__erased_assign<__storage<_Types>&,
439                                      __storage<_Types>&&>... };
440                 _S_vtable[__rhs._M_index](_M_storage(), __rhs._M_storage());
441               }
442           }
443         else
444           {
445             this->~_Variant_base();
446             __try
447               {
448                 ::new (this) _Variant_base(std::move(__rhs));
449               }
450             __catch (...)
451               {
452                 _M_index = variant_npos;
453                 __throw_exception_again;
454               }
455           }
456         return *this;
457       }
458
459       void _M_destroy()
460       {
461         if (_M_valid())
462           {
463             static constexpr void (*_S_vtable[])(void*) =
464               { &__erased_dtor<__storage<_Types>&>... };
465             _S_vtable[this->_M_index](_M_storage());
466           }
467       }
468
469       constexpr void*
470       _M_storage() const
471       { return _Storage::_M_storage(); }
472
473       constexpr bool
474       _M_valid() const noexcept
475       { return _M_index != variant_npos; }
476
477       size_t _M_index;
478     };
479
480   // For how many times does _Tp appear in _Tuple?
481   template<typename _Tp, typename _Tuple>
482     struct __tuple_count;
483
484   template<typename _Tp, typename _Tuple>
485     constexpr size_t __tuple_count_v = __tuple_count<_Tp, _Tuple>::value;
486
487   template<typename _Tp, typename... _Types>
488     struct __tuple_count<_Tp, tuple<_Types...>>
489     : integral_constant<size_t, 0> { };
490
491   template<typename _Tp, typename _First, typename... _Rest>
492     struct __tuple_count<_Tp, tuple<_First, _Rest...>>
493     : integral_constant<
494         size_t,
495         __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
496
497   // TODO: Reuse this in <tuple> ?
498   template<typename _Tp, typename... _Types>
499     constexpr bool __exactly_once = __tuple_count_v<_Tp, tuple<_Types...>> == 1;
500
501   // Takes _Types and create an overloaded _S_fun for each type.
502   // If a type appears more than once in _Types, create only one overload.
503   template<typename... _Types>
504     struct __overload_set
505     { static void _S_fun(); };
506
507   template<typename _First, typename... _Rest>
508     struct __overload_set<_First, _Rest...> : __overload_set<_Rest...>
509     {
510       using __overload_set<_Rest...>::_S_fun;
511       static integral_constant<size_t, sizeof...(_Rest)> _S_fun(_First);
512     };
513
514   template<typename... _Rest>
515     struct __overload_set<void, _Rest...> : __overload_set<_Rest...>
516     {
517       using __overload_set<_Rest...>::_S_fun;
518     };
519
520   // Helper for variant(_Tp&&) and variant::operator=(_Tp&&).
521   // __accepted_index maps the arbitrary _Tp to an alternative type in _Variant.
522   template<typename _Tp, typename _Variant, typename = void>
523     struct __accepted_index
524     { static constexpr size_t value = variant_npos; };
525
526   template<typename _Tp, typename... _Types>
527     struct __accepted_index<
528       _Tp, variant<_Types...>,
529       decltype(__overload_set<_Types...>::_S_fun(std::declval<_Tp>()),
530                std::declval<void>())>
531     {
532       static constexpr size_t value = sizeof...(_Types) - 1
533         - decltype(__overload_set<_Types...>::
534                    _S_fun(std::declval<_Tp>()))::value;
535     };
536
537   // Returns the raw storage for __v.
538   template<typename _Variant>
539     void* __get_storage(_Variant&& __v)
540     { return __v._M_storage(); }
541
542   // Returns the reference to the desired alternative.
543   // It is as unsafe as a reinterpret_cast.
544   template<typename _Tp, typename _Variant>
545     decltype(auto) __access(_Variant&& __v)
546     {
547       return __get_alternative<__reserved_type_map<_Variant&&, __storage<_Tp>>>(
548         __get_storage(std::forward<_Variant>(__v)));
549     }
550
551   // A helper used to create variadic number of _To types.
552   template<typename _From, typename _To>
553     using _To_type = _To;
554
555   // Call the actual visitor.
556   // _Args are qualified storage types.
557   template<typename _Visitor, typename... _Args>
558     decltype(auto)
559     __visit_invoke(_Visitor&& __visitor, _To_type<_Args, void*>... __ptrs)
560     {
561       return std::forward<_Visitor>(__visitor)(
562           __get_alternative<_Args>(__ptrs)...);
563     }
564
565   // Used for storing multi-dimensional vtable.
566   template<typename _Tp, size_t... _Dimensions>
567     struct _Multi_array
568     {
569       constexpr const _Tp&
570       _M_access() const
571       { return _M_data; }
572
573       _Tp _M_data;
574     };
575
576   template<typename _Tp, size_t __first, size_t... __rest>
577     struct _Multi_array<_Tp, __first, __rest...>
578     {
579       template<typename... _Args>
580         constexpr const _Tp&
581         _M_access(size_t __first_index, _Args... __rest_indices) const
582         { return _M_arr[__first_index]._M_access(__rest_indices...); }
583
584       _Multi_array<_Tp, __rest...> _M_arr[__first];
585     };
586
587   // Creates a multi-dimensional vtable recursively.
588   // _Variant_tuple is initially the input from visit(), and gets gradually
589   // consumed.
590   // _Arg_tuple is enumerated alternative sequence, represented by a
591   // qualified storage.
592   //
593   // For example,
594   // visit([](auto, auto){},
595   //       variant<int, char>(),
596   //       variant<float, double, long double>())
597   // will trigger instantiations of:
598   // __gen_vtable_impl<_Multi_array<void(*)(void*, void*), 2, 3>,
599   //                   tuple<variant<int, char>,
600   //                         variant<float, double, long double>>,
601   //                   tuple<>>
602   //   __gen_vtable_impl<_Multi_array<void(*)(void*, void*), 3>,
603   //                     tuple<variant<float, double, long double>>,
604   //                     tuple<int>>
605   //     __gen_vtable_impl<_Multi_array<void(*)(void*, void*)>,
606   //                       tuple<>,
607   //                       tuple<int, float>>
608   //     __gen_vtable_impl<_Multi_array<void(*)(void*, void*)>,
609   //                       tuple<>,
610   //                       tuple<int, double>>
611   //     __gen_vtable_impl<_Multi_array<void(*)(void*, void*)>,
612   //                       tuple<>,
613   //                       tuple<int, long double>>
614   //   __gen_vtable_impl<_Multi_array<void(*)(void*, void*), 3>,
615   //                     tuple<variant<float, double, long double>>,
616   //                     tuple<char>>
617   //     __gen_vtable_impl<_Multi_array<void(*)(void*, void*)>,
618   //                       tuple<>,
619   //                       tuple<char, float>>
620   //     __gen_vtable_impl<_Multi_array<void(*)(void*, void*)>,
621   //                       tuple<>,
622   //                       tuple<char, double>>
623   //     __gen_vtable_impl<_Multi_array<void(*)(void*, void*)>,
624   //                       tuple<>,
625   //                       tuple<char, long double>>
626   // The returned multi-dimensional vtable can be fast accessed by the visitor
627   // using index calculation.
628   template<typename _Array_type, typename _Variant_tuple, typename _Arg_tuple>
629     struct __gen_vtable_impl;
630
631   template<typename _Array_type, typename _First, typename... _Rest,
632            typename... _Args>
633     struct __gen_vtable_impl<_Array_type, tuple<_First, _Rest...>,
634                              tuple<_Args...>>
635     {
636       static constexpr _Array_type
637       _S_apply()
638       {
639         _Array_type __vtable{};
640         _S_apply_all_alts(
641           __vtable, make_index_sequence<variant_size_v<decay_t<_First>>>());
642         return __vtable;
643       }
644
645       template<size_t... __indices>
646         static constexpr void
647         _S_apply_all_alts(_Array_type& __vtable, index_sequence<__indices...>)
648         { (_S_apply_single_alt<__indices>(__vtable._M_arr[__indices]), ...); }
649
650       template<size_t __index>
651         static constexpr void
652         _S_apply_single_alt(auto& __element)
653         {
654           using _Alternative = variant_alternative_t<__index, decay_t<_First>>;
655           using _Qualified_storage = __reserved_type_map<
656             _First, __storage<_Alternative>>;
657           __element = __gen_vtable_impl<
658             decay_t<decltype(__element)>, tuple<_Rest...>,
659             tuple<_Args..., _Qualified_storage>>::_S_apply();
660         }
661     };
662
663   template<typename _Result_type, typename _Visitor, typename... _Args>
664     struct __gen_vtable_impl<
665       _Multi_array<_Result_type (*)(_Visitor, _To_type<_Args, void*>...)>,
666                    tuple<>, tuple<_Args...>>
667     {
668       using _Array_type =
669         _Multi_array<_Result_type (*)(_Visitor&&, _To_type<_Args, void*>...)>;
670
671       static constexpr auto
672       _S_apply()
673       { return _Array_type{&__visit_invoke<_Visitor, _Args...>}; }
674     };
675
676   template<typename _Result_type, typename _Visitor, typename... _Variants>
677     struct __gen_vtable
678     {
679       using _Func_ptr =
680         _Result_type (*)(_Visitor&&, _To_type<_Variants, void*>...);
681       using _Array_type =
682         _Multi_array<_Func_ptr, variant_size_v<decay_t<_Variants>>...>;
683
684       static constexpr _Array_type
685       _S_apply()
686       {
687         return __gen_vtable_impl<
688           _Array_type, tuple<_Variants...>, tuple<>>::_S_apply();
689       }
690     };
691
692 _GLIBCXX_END_NAMESPACE_VERSION
693 } // namespace __variant
694 } // namespace __detail
695
696 _GLIBCXX_BEGIN_NAMESPACE_VERSION
697
698   template<typename _Tp, typename... _Types>
699     inline constexpr bool holds_alternative(const variant<_Types...>& __v)
700     noexcept
701     {
702       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
703                     "T should occur for exactly once in alternatives");
704       return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>;
705     }
706
707   template<size_t _Np, typename... _Types>
708     variant_alternative_t<_Np, variant<_Types...>>&
709     get(variant<_Types...>&);
710
711   template<size_t _Np, typename... _Types>
712     variant_alternative_t<_Np, variant<_Types...>>&&
713     get(variant<_Types...>&&);
714
715   template<size_t _Np, typename... _Types>
716     variant_alternative_t<_Np, variant<_Types...>> const&
717     get(const variant<_Types...>&);
718
719   template<size_t _Np, typename... _Types>
720     variant_alternative_t<_Np, variant<_Types...>> const&&
721     get(const variant<_Types...>&&);
722
723   template<typename _Tp, typename... _Types>
724     inline _Tp& get(variant<_Types...>& __v)
725     {
726       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
727                     "T should occur for exactly once in alternatives");
728       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
729       return get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
730     }
731
732   template<typename _Tp, typename... _Types>
733     inline _Tp&& get(variant<_Types...>&& __v)
734     {
735       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
736                     "T should occur for exactly once in alternatives");
737       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
738       return get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
739         std::move(__v));
740     }
741
742   template<typename _Tp, typename... _Types>
743     inline const _Tp& get(const variant<_Types...>& __v)
744     {
745       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
746                     "T should occur for exactly once in alternatives");
747       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
748       return get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
749     }
750
751   template<typename _Tp, typename... _Types>
752     inline const _Tp&& get(const variant<_Types...>&& __v)
753     {
754       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
755                     "T should occur for exactly once in alternatives");
756       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
757       return get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
758         std::move(__v));
759     }
760
761   template<size_t _Np, typename... _Types>
762     inline add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
763     get_if(variant<_Types...>* __ptr) noexcept
764     {
765       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
766       static_assert(_Np < sizeof...(_Types),
767                     "The index should be in [0, number of alternatives)");
768       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
769       if (__ptr && __ptr->index() == _Np)
770         return &__detail::__variant::__access<_Alternative_type>(*__ptr);
771       return nullptr;
772     }
773
774   template<size_t _Np, typename... _Types>
775     inline add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
776     get_if(const variant<_Types...>* __ptr) noexcept
777     {
778       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
779       static_assert(_Np < sizeof...(_Types),
780                     "The index should be in [0, number of alternatives)");
781       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
782       if (__ptr && __ptr->index() == _Np)
783         return &__detail::__variant::__access<_Alternative_type>(*__ptr);
784       return nullptr;
785     }
786
787   template<typename _Tp, typename... _Types>
788     inline add_pointer_t<_Tp> get_if(variant<_Types...>* __ptr) noexcept
789     {
790       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
791                     "T should occur for exactly once in alternatives");
792       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
793       return get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(__ptr);
794     }
795
796   template<typename _Tp, typename... _Types>
797     inline add_pointer_t<const _Tp> get_if(const variant<_Types...>* __ptr)
798     noexcept
799     {
800       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
801                     "T should occur for exactly once in alternatives");
802       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
803       return get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(__ptr);
804     }
805
806   template<typename... _Types>
807     bool operator==(const variant<_Types...>& __lhs,
808                     const variant<_Types...>& __rhs)
809     {
810       if (__lhs.index() != __rhs.index())
811         return false;
812
813       if (__lhs.valueless_by_exception())
814         return true;
815
816       using __detail::__variant::__storage;
817       static constexpr bool (*_S_vtable[])(void*, void*) =
818         { &__detail::__variant::__erased_equal_to<
819           const __storage<_Types>&, const __storage<_Types>&>... };
820       return _S_vtable[__lhs.index()](
821           __detail::__variant::__get_storage(__lhs),
822           __detail::__variant::__get_storage(__rhs));
823     }
824
825   template<typename... _Types>
826     inline bool
827     operator!=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs)
828     { return !(__lhs == __rhs); }
829
830   template<typename... _Types>
831     inline bool
832     operator<(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs)
833     {
834       if (__lhs.index() < __rhs.index())
835         return true;
836
837       if (__lhs.index() > __rhs.index())
838         return false;
839
840       if (__lhs.valueless_by_exception())
841         return false;
842
843       using __detail::__variant::__storage;
844       static constexpr bool (*_S_vtable[])(void*, void*) =
845         { &__detail::__variant::__erased_less_than<
846             const __storage<_Types>&,
847             const __storage<_Types>&>... };
848       return _S_vtable[__lhs.index()](
849           __detail::__variant::__get_storage(__lhs),
850           __detail::__variant::__get_storage(__rhs));
851     }
852
853   template<typename... _Types>
854     inline bool
855     operator>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs)
856     { return __rhs < __lhs; }
857
858   template<typename... _Types>
859     inline bool
860     operator<=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs)
861     { return !(__lhs > __rhs); }
862
863   template<typename... _Types>
864     inline bool
865     operator>=(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs)
866     { return !(__lhs < __rhs); }
867
868   template<typename _Visitor, typename... _Variants>
869     decltype(auto) visit(_Visitor&&, _Variants&&...);
870
871   struct monostate { };
872
873   constexpr bool operator<(monostate, monostate) noexcept
874   { return false; }
875
876   constexpr bool operator>(monostate, monostate) noexcept
877   { return false; }
878
879   constexpr bool operator<=(monostate, monostate) noexcept
880   { return true; }
881
882   constexpr bool operator>=(monostate, monostate) noexcept
883   { return true; }
884
885   constexpr bool operator==(monostate, monostate) noexcept
886   { return true; }
887
888   constexpr bool operator!=(monostate, monostate) noexcept
889   { return false; }
890
891   template<typename... _Types>
892     inline enable_if_t<__and_<is_move_constructible<_Types>...,
893                               is_swappable<_Types>...>::value>
894     swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
895     noexcept(noexcept(__lhs.swap(__rhs)))
896     { __lhs.swap(__rhs); }
897
898   template<typename... _Types>
899     inline enable_if_t<!__and_<is_move_constructible<_Types>...,
900                                is_swappable<_Types>...>::value>
901     swap(variant<_Types...>&, variant<_Types...>&) = delete;
902
903   class bad_variant_access : public exception
904   {
905   public:
906     bad_variant_access() noexcept : _M_reason("Unknown reason") { }
907     const char* what() const noexcept override
908     { return _M_reason; }
909
910   private:
911     bad_variant_access(const char* __reason) : _M_reason(__reason) { }
912
913     const char* _M_reason;
914
915     friend void __throw_bad_variant_access(const char* __what);
916   };
917
918   inline void
919   __throw_bad_variant_access(const char* __what)
920   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
921
922   template<typename... _Types>
923     class variant
924     : private __detail::__variant::_Variant_base<_Types...>,
925       private _Enable_default_constructor<
926         is_default_constructible_v<
927           variant_alternative_t<0, variant<_Types...>>>, variant<_Types...>>,
928       private _Enable_copy_move<
929         __and_<is_copy_constructible<_Types>...>::value,
930         __and_<is_copy_constructible<_Types>...,
931                is_move_constructible<_Types>...,
932                is_copy_assignable<_Types>...>::value,
933         __and_<is_move_constructible<_Types>...>::value,
934         __and_<is_move_constructible<_Types>...,
935                is_move_assignable<_Types>...>::value,
936         variant<_Types...>>
937     {
938     private:
939       static_assert(sizeof...(_Types) > 0,
940                     "variant must have at least one alternative");
941       static_assert(!(std::is_reference_v<_Types> || ...),
942                     "variant must have no reference alternative");
943       static_assert(!(std::is_void_v<_Types> || ...),
944                     "variant must have no void alternative");
945
946       using _Base = __detail::__variant::_Variant_base<_Types...>;
947       using _Default_ctor_enabler =
948         _Enable_default_constructor<
949           is_default_constructible_v<
950             variant_alternative_t<0, variant<_Types...>>>, variant<_Types...>>;
951
952       template<typename _Tp>
953         static constexpr bool
954         __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
955
956       template<typename _Tp>
957         static constexpr size_t __accepted_index =
958           __detail::__variant::__accepted_index<_Tp&&, variant>::value;
959
960       template<size_t _Np, bool = _Np < sizeof...(_Types)>
961         struct __to_type_impl;
962
963       template<size_t _Np>
964         struct __to_type_impl<_Np, true>
965         { using type = variant_alternative_t<_Np, variant>; };
966
967       template<size_t _Np>
968         using __to_type = typename __to_type_impl<_Np>::type;
969
970       template<typename _Tp>
971         using __accepted_type = __to_type<__accepted_index<_Tp>>;
972
973       template<typename _Tp>
974         using __storage = __detail::__variant::__storage<_Tp>;
975
976       template<typename _Tp>
977         static constexpr size_t __index_of =
978           __detail::__variant::__index_of_v<_Tp, _Types...>;
979
980     public:
981       constexpr variant()
982       noexcept(is_nothrow_default_constructible_v<__to_type<0>>) = default;
983       variant(const variant&) = default;
984       variant(variant&&)
985       noexcept(__and_<
986         is_nothrow_move_constructible<_Types>...>::value) = default;
987
988       template<typename _Tp,
989                typename = enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
990                           && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>
991                           && !is_same_v<decay_t<_Tp>, variant>>>
992         constexpr
993         variant(_Tp&& __t)
994         noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
995         : variant(in_place_index<__accepted_index<_Tp&&>>, std::forward<_Tp>(__t))
996         { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
997
998       template<typename _Tp, typename... _Args,
999                typename = enable_if_t<__exactly_once<_Tp>
1000                           && is_constructible_v<_Tp, _Args&&...>>>
1001         constexpr explicit
1002         variant(in_place_type_t<_Tp>, _Args&&... __args)
1003         : variant(in_place_index<__index_of<_Tp>>, std::forward<_Args>(__args)...)
1004         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1005
1006       template<typename _Tp, typename _Up, typename... _Args,
1007                typename = enable_if_t<__exactly_once<_Tp>
1008                           && is_constructible_v<
1009                             _Tp, initializer_list<_Up>&, _Args&&...>>>
1010         constexpr explicit
1011         variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1012                 _Args&&... __args)
1013         : variant(in_place_index<__index_of<_Tp>>, __il,
1014                   std::forward<_Args>(__args)...)
1015         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1016
1017       template<size_t _Np, typename... _Args,
1018                typename = enable_if_t<
1019                  is_constructible_v<__to_type<_Np>, _Args&&...>>>
1020         constexpr explicit
1021         variant(in_place_index_t<_Np>, _Args&&... __args)
1022         : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
1023         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1024         { __glibcxx_assert(index() == _Np); }
1025
1026       template<size_t _Np, typename _Up, typename... _Args,
1027                typename = enable_if_t<is_constructible_v<__to_type<_Np>,
1028                                       initializer_list<_Up>&, _Args&&...>>>
1029         constexpr explicit
1030         variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1031                 _Args&&... __args)
1032         : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1033         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1034         { __glibcxx_assert(index() == _Np); }
1035
1036       template<typename _Alloc,
1037                typename = enable_if_t<
1038                  __is_uses_allocator_constructible_v<__to_type<0>, _Alloc>>>
1039         variant(allocator_arg_t, const _Alloc& __a)
1040         : variant(allocator_arg, __a, in_place_index<0>)
1041         { }
1042
1043       template<typename _Alloc,
1044                typename = enable_if_t<__and_<__is_uses_allocator_constructible<
1045                  _Types, _Alloc,
1046                  add_lvalue_reference_t<add_const_t<_Types>>>...>::value>>
1047         variant(allocator_arg_t, const _Alloc& __a, const variant& __rhs)
1048         : _Base(__a, __rhs),
1049         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1050         { }
1051
1052       template<typename _Alloc,
1053                typename = enable_if_t<__and_<
1054                  __is_uses_allocator_constructible<
1055                    _Types, _Alloc, add_rvalue_reference_t<_Types>>...>::value>>
1056         variant(allocator_arg_t, const _Alloc& __a, variant&& __rhs)
1057         : _Base(__a, std::move(__rhs)),
1058         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1059         { }
1060
1061       template<typename _Alloc, typename _Tp,
1062                typename = enable_if_t<
1063                  __exactly_once<__accepted_type<_Tp&&>>
1064                  && __is_uses_allocator_constructible_v<
1065                    __accepted_type<_Tp&&>, _Alloc, _Tp&&>
1066                  && !is_same_v<decay_t<_Tp>, variant>, variant&>>
1067         variant(allocator_arg_t, const _Alloc& __a, _Tp&& __t)
1068         : variant(allocator_arg, __a, in_place_index<__accepted_index<_Tp&&>>,
1069                   std::forward<_Tp>(__t))
1070         { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
1071
1072       template<typename _Alloc, typename _Tp, typename... _Args,
1073                typename = enable_if_t<
1074                  __exactly_once<_Tp>
1075                  && __is_uses_allocator_constructible_v<
1076                    _Tp, _Alloc, _Args&&...>>>
1077         variant(allocator_arg_t, const _Alloc& __a, in_place_type_t<_Tp>,
1078                 _Args&&... __args)
1079         : variant(allocator_arg, __a, in_place_index<__index_of<_Tp>>,
1080                   std::forward<_Args>(__args)...)
1081         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1082
1083       template<typename _Alloc, typename _Tp, typename _Up, typename... _Args,
1084                typename = enable_if_t<
1085                  __exactly_once<_Tp>
1086                  && __is_uses_allocator_constructible_v<
1087                    _Tp, _Alloc, initializer_list<_Up>&, _Args&&...>>>
1088         variant(allocator_arg_t, const _Alloc& __a, in_place_type_t<_Tp>,
1089                 initializer_list<_Up> __il, _Args&&... __args)
1090         : variant(allocator_arg, __a, in_place_index<__index_of<_Tp>>, __il,
1091                   std::forward<_Args>(__args)...)
1092         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1093
1094       template<typename _Alloc, size_t _Np, typename... _Args,
1095                typename = enable_if_t<
1096                  __is_uses_allocator_constructible_v<
1097                    __to_type<_Np>, _Alloc, _Args&&...>>>
1098         variant(allocator_arg_t, const _Alloc& __a, in_place_index_t<_Np>,
1099                 _Args&&... __args)
1100         : _Base(__a, in_place_index<_Np>, std::forward<_Args>(__args)...),
1101         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1102         { __glibcxx_assert(index() == _Np); }
1103
1104       template<typename _Alloc, size_t _Np, typename _Up, typename... _Args,
1105                typename = enable_if_t<
1106                  __is_uses_allocator_constructible_v<
1107                    __to_type<_Np>, _Alloc, initializer_list<_Up>&, _Args&&...>>>
1108         variant(allocator_arg_t, const _Alloc& __a, in_place_index_t<_Np>,
1109                 initializer_list<_Up> __il, _Args&&... __args)
1110         : _Base(__a, in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1111         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1112         { __glibcxx_assert(index() == _Np); }
1113
1114       ~variant() = default;
1115
1116       variant& operator=(const variant&) = default;
1117       variant& operator=(variant&&)
1118       noexcept(__and_<is_nothrow_move_constructible<_Types>...,
1119                       is_nothrow_move_assignable<_Types>...>::value) = default;
1120
1121       template<typename _Tp>
1122         enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1123                     && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>
1124                     && is_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1125                     && !is_same_v<decay_t<_Tp>, variant>, variant&>
1126         operator=(_Tp&& __rhs)
1127         noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1128                  && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1129         {
1130           constexpr auto __index = __accepted_index<_Tp&&>;
1131           if (index() == __index)
1132             std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1133           else
1134             this->emplace<__index>(std::forward<_Tp>(__rhs));
1135           __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this));
1136           return *this;
1137         }
1138
1139       template<typename _Tp, typename... _Args>
1140         void emplace(_Args&&... __args)
1141         {
1142           static_assert(__exactly_once<_Tp>,
1143                         "T should occur for exactly once in alternatives");
1144           this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...);
1145           __glibcxx_assert(holds_alternative<_Tp>(*this));
1146         }
1147
1148       template<typename _Tp, typename _Up, typename... _Args>
1149         void emplace(initializer_list<_Up> __il, _Args&&... __args)
1150         {
1151           static_assert(__exactly_once<_Tp>,
1152                         "T should occur for exactly once in alternatives");
1153           this->emplace<__index_of<_Tp>>(__il, std::forward<_Args>(__args)...);
1154           __glibcxx_assert(holds_alternative<_Tp>(*this));
1155         }
1156
1157       template<size_t _Np, typename... _Args>
1158         void emplace(_Args&&... __args)
1159         {
1160           static_assert(_Np < sizeof...(_Types),
1161                         "The index should be in [0, number of alternatives)");
1162           this->~variant();
1163           __try
1164             {
1165               ::new (this) variant(in_place_index<_Np>,
1166                                    std::forward<_Args>(__args)...);
1167             }
1168           __catch (...)
1169             {
1170               this->_M_index = variant_npos;
1171               __throw_exception_again;
1172             }
1173           __glibcxx_assert(index() == _Np);
1174         }
1175
1176       template<size_t _Np, typename _Up, typename... _Args>
1177         void emplace(initializer_list<_Up> __il, _Args&&... __args)
1178         {
1179           static_assert(_Np < sizeof...(_Types),
1180                         "The index should be in [0, number of alternatives)");
1181           this->~variant();
1182           __try
1183             {
1184               ::new (this) variant(in_place_index<_Np>, __il,
1185                                    std::forward<_Args>(__args)...);
1186             }
1187           __catch (...)
1188             {
1189               this->_M_index = variant_npos;
1190               __throw_exception_again;
1191             }
1192           __glibcxx_assert(index() == _Np);
1193         }
1194
1195       constexpr bool valueless_by_exception() const noexcept
1196       { return !this->_M_valid(); }
1197
1198       constexpr size_t index() const noexcept
1199       { return this->_M_index; }
1200
1201       void
1202       swap(variant& __rhs)
1203       noexcept(__and_<__is_nothrow_swappable<_Types>...>::value
1204                && is_nothrow_move_assignable_v<variant>)
1205       {
1206         if (this->index() == __rhs.index())
1207           {
1208             if (this->_M_valid())
1209               {
1210                 static constexpr void (*_S_vtable[])(void*, void*) =
1211                   { &__detail::__variant::__erased_swap<
1212                       __storage<_Types>&, __storage<_Types>&>... };
1213                 _S_vtable[__rhs._M_index](this->_M_storage(),
1214                                           __rhs._M_storage());
1215               }
1216           }
1217         else if (!this->_M_valid())
1218           {
1219             *this = std::move(__rhs);
1220           }
1221         else if (!__rhs._M_valid())
1222           {
1223             __rhs = std::move(*this);
1224           }
1225         else
1226           {
1227             auto __tmp = std::move(__rhs);
1228             __rhs = std::move(*this);
1229             *this = std::move(__tmp);
1230           }
1231       }
1232
1233       template<typename _Vp>
1234         friend void* __detail::__variant::
1235 #if _GLIBCXX_INLINE_VERSION
1236         __7:: // Required due to PR c++/59256
1237 #endif
1238         __get_storage(_Vp&& __v);
1239     };
1240
1241   template<size_t _Np, typename... _Types>
1242     variant_alternative_t<_Np, variant<_Types...>>&
1243     get(variant<_Types...>& __v)
1244     {
1245       static_assert(_Np < sizeof...(_Types),
1246                     "The index should be in [0, number of alternatives)");
1247       if (__v.index() != _Np)
1248         __throw_bad_variant_access("Unexpected index");
1249       return __detail::__variant::__access<
1250         variant_alternative_t<_Np, variant<_Types...>>>(__v);
1251     }
1252
1253   template<size_t _Np, typename... _Types>
1254     variant_alternative_t<_Np, variant<_Types...>>&&
1255     get(variant<_Types...>&& __v)
1256     {
1257       static_assert(_Np < sizeof...(_Types),
1258                     "The index should be in [0, number of alternatives)");
1259       if (__v.index() != _Np)
1260         __throw_bad_variant_access("Unexpected index");
1261       return __detail::__variant::__access<
1262         variant_alternative_t<_Np, variant<_Types...>>>(std::move(__v));
1263     }
1264
1265   template<size_t _Np, typename... _Types>
1266     const variant_alternative_t<_Np, variant<_Types...>>&
1267     get(const variant<_Types...>& __v)
1268     {
1269       static_assert(_Np < sizeof...(_Types),
1270                     "The index should be in [0, number of alternatives)");
1271       if (__v.index() != _Np)
1272         __throw_bad_variant_access("Unexpected index");
1273       return __detail::__variant::__access<
1274         variant_alternative_t<_Np, variant<_Types...>>>(__v);
1275     }
1276
1277   template<size_t _Np, typename... _Types>
1278     const variant_alternative_t<_Np, variant<_Types...>>&&
1279     get(const variant<_Types...>&& __v)
1280     {
1281       static_assert(_Np < sizeof...(_Types),
1282                     "The index should be in [0, number of alternatives)");
1283       if (__v.index() != _Np)
1284         __throw_bad_variant_access("Unexpected index");
1285       return __detail::__variant::__access<
1286         variant_alternative_t<_Np, variant<_Types...>>>(std::move(__v));
1287     }
1288
1289   template<typename _Visitor, typename... _Variants>
1290     decltype(auto)
1291     visit(_Visitor&& __visitor, _Variants&&... __variants)
1292     {
1293       using _Result_type =
1294         decltype(std::forward<_Visitor>(__visitor)(get<0>(__variants)...));
1295       static constexpr auto _S_vtable =
1296         __detail::__variant::__gen_vtable<
1297           _Result_type, _Visitor&&, _Variants&&...>::_S_apply();
1298       auto __func_ptr = _S_vtable._M_access(__variants.index()...);
1299       return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1300                            __detail::__variant::__get_storage(__variants)...);
1301     }
1302
1303   template<typename... _Types, typename _Alloc>
1304     struct uses_allocator<variant<_Types...>, _Alloc>
1305     : true_type { };
1306
1307   template<typename... _Types>
1308     struct hash<variant<_Types...>>
1309     : private __poison_hash<remove_const_t<_Types>>...
1310     {
1311       using result_type = size_t;
1312       using argument_type = variant<_Types...>;
1313
1314       size_t
1315       operator()(const variant<_Types...>& __t) const
1316       noexcept((... && noexcept(hash<decay_t<_Types>>{}(std::declval<_Types>()))))
1317       {
1318         if (!__t.valueless_by_exception())
1319           {
1320             namespace __edv = __detail::__variant;
1321             static constexpr size_t (*_S_vtable[])(void*) =
1322               { &__edv::__erased_hash<const __edv::__storage<_Types>&>... };
1323             return hash<size_t>{}(__t.index())
1324               + _S_vtable[__t.index()](__edv::__get_storage(__t));
1325           }
1326         return hash<size_t>{}(__t.index());
1327       }
1328     };
1329
1330   template<>
1331     struct hash<monostate>
1332     {
1333       using result_type = size_t;
1334       using argument_type = monostate;
1335
1336       size_t
1337       operator()(const monostate& __t) const noexcept
1338       {
1339         constexpr size_t __magic_monostate_hash = -7777;
1340         return __magic_monostate_hash;
1341       }
1342     };
1343
1344 _GLIBCXX_END_NAMESPACE_VERSION
1345 } // namespace std
1346
1347 #endif // C++17
1348
1349 #endif // _GLIBCXX_VARIANT