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