Fix missing or incorrect feature test macros
[official-gcc.git] / libstdc++-v3 / include / std / variant
blob89deb143097dfa66a33559b8025051f9846e33a6
1 // <variant> -*- C++ -*-
3 // Copyright (C) 2016-2019 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file variant
26  *  This is the <variant> C++ Library header.
27  */
29 #ifndef _GLIBCXX_VARIANT
30 #define _GLIBCXX_VARIANT 1
32 #pragma GCC system_header
34 #if __cplusplus >= 201703L
36 #include <type_traits>
37 #include <utility>
38 #include <bits/enable_special_members.h>
39 #include <bits/functexcept.h>
40 #include <bits/move.h>
41 #include <bits/functional_hash.h>
42 #include <bits/invoke.h>
43 #include <ext/aligned_buffer.h>
44 #include <bits/parse_numbers.h>
45 #include <bits/stl_iterator_base_types.h>
46 #include <bits/stl_iterator_base_funcs.h>
47 #include <bits/stl_construct.h>
49 namespace std _GLIBCXX_VISIBILITY(default)
51 _GLIBCXX_BEGIN_NAMESPACE_VERSION
53 namespace __detail
55 namespace __variant
57   template<size_t _Np, typename... _Types>
58     struct _Nth_type;
60   template<size_t _Np, typename _First, typename... _Rest>
61     struct _Nth_type<_Np, _First, _Rest...>
62     : _Nth_type<_Np-1, _Rest...> { };
64   template<typename _First, typename... _Rest>
65     struct _Nth_type<0, _First, _Rest...>
66     { using type = _First; };
68 } // namespace __variant
69 } // namespace __detail
71 #define __cpp_lib_variant 201606L
73   template<typename... _Types> class tuple;
74   template<typename... _Types> class variant;
75   template <typename> struct hash;
77   template<typename _Variant>
78     struct variant_size;
80   template<typename _Variant>
81     struct variant_size<const _Variant> : variant_size<_Variant> {};
83   template<typename _Variant>
84     struct variant_size<volatile _Variant> : variant_size<_Variant> {};
86   template<typename _Variant>
87     struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
89   template<typename... _Types>
90     struct variant_size<variant<_Types...>>
91     : std::integral_constant<size_t, sizeof...(_Types)> {};
93   template<typename _Variant>
94     inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
96   template<size_t _Np, typename _Variant>
97     struct variant_alternative;
99   template<size_t _Np, typename _First, typename... _Rest>
100     struct variant_alternative<_Np, variant<_First, _Rest...>>
101     : variant_alternative<_Np-1, variant<_Rest...>> {};
103   template<typename _First, typename... _Rest>
104     struct variant_alternative<0, variant<_First, _Rest...>>
105     { using type = _First; };
107   template<size_t _Np, typename _Variant>
108     using variant_alternative_t =
109       typename variant_alternative<_Np, _Variant>::type;
111   template<size_t _Np, typename _Variant>
112     struct variant_alternative<_Np, const _Variant>
113     { using type = add_const_t<variant_alternative_t<_Np, _Variant>>; };
115   template<size_t _Np, typename _Variant>
116     struct variant_alternative<_Np, volatile _Variant>
117     { using type = add_volatile_t<variant_alternative_t<_Np, _Variant>>; };
119   template<size_t _Np, typename _Variant>
120     struct variant_alternative<_Np, const volatile _Variant>
121     { using type = add_cv_t<variant_alternative_t<_Np, _Variant>>; };
123   inline constexpr size_t variant_npos = -1;
125   template<size_t _Np, typename... _Types>
126     constexpr variant_alternative_t<_Np, variant<_Types...>>&
127     get(variant<_Types...>&);
129   template<size_t _Np, typename... _Types>
130     constexpr variant_alternative_t<_Np, variant<_Types...>>&&
131     get(variant<_Types...>&&);
133   template<size_t _Np, typename... _Types>
134     constexpr variant_alternative_t<_Np, variant<_Types...>> const&
135     get(const variant<_Types...>&);
137   template<size_t _Np, typename... _Types>
138     constexpr variant_alternative_t<_Np, variant<_Types...>> const&&
139     get(const variant<_Types...>&&);
141 namespace __detail
143 namespace __variant
145   // Returns the first apparence of _Tp in _Types.
146   // Returns sizeof...(_Types) if _Tp is not in _Types.
147   template<typename _Tp, typename... _Types>
148     struct __index_of : std::integral_constant<size_t, 0> {};
150   template<typename _Tp, typename... _Types>
151     inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value;
153   template<typename _Tp, typename _First, typename... _Rest>
154     struct __index_of<_Tp, _First, _Rest...> :
155       std::integral_constant<size_t, is_same_v<_Tp, _First>
156         ? 0 : __index_of_v<_Tp, _Rest...> + 1> {};
158   // _Uninitialized<T> is guaranteed to be a literal type, even if T is not.
159   // We have to do this, because [basic.types]p10.5.3 (n4606) is not implemented
160   // yet. When it's implemented, _Uninitialized<T> can be changed to the alias
161   // to T, therefore equivalent to being removed entirely.
162   //
163   // Another reason we may not want to remove _Uninitialzied<T> may be that, we
164   // want _Uninitialized<T> to be trivially destructible, no matter whether T
165   // is; but we will see.
166   template<typename _Type, bool = std::is_literal_type_v<_Type>>
167     struct _Uninitialized;
169   template<typename _Type>
170     struct _Uninitialized<_Type, true>
171     {
172       template<typename... _Args>
173       constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args)
174       : _M_storage(std::forward<_Args>(__args)...)
175       { }
177       constexpr const _Type& _M_get() const &
178       { return _M_storage; }
180       constexpr _Type& _M_get() &
181       { return _M_storage; }
183       constexpr const _Type&& _M_get() const &&
184       { return std::move(_M_storage); }
186       constexpr _Type&& _M_get() &&
187       { return std::move(_M_storage); }
189       _Type _M_storage;
190     };
192   template<typename _Type>
193     struct _Uninitialized<_Type, false>
194     {
195       template<typename... _Args>
196       constexpr _Uninitialized(in_place_index_t<0>, _Args&&... __args)
197       { ::new (&_M_storage) _Type(std::forward<_Args>(__args)...); }
199       const _Type& _M_get() const &
200       { return *_M_storage._M_ptr(); }
202       _Type& _M_get() &
203       { return *_M_storage._M_ptr(); }
205       const _Type&& _M_get() const &&
206       { return std::move(*_M_storage._M_ptr()); }
208       _Type&& _M_get() &&
209       { return std::move(*_M_storage._M_ptr()); }
211       __gnu_cxx::__aligned_membuf<_Type> _M_storage;
212     };
214   template<typename _Ref>
215     _Ref __ref_cast(void* __ptr)
216     {
217       return static_cast<_Ref>(*static_cast<remove_reference_t<_Ref>*>(__ptr));
218     }
220   template<typename _Union>
221     constexpr decltype(auto) __get(in_place_index_t<0>, _Union&& __u)
222     { return std::forward<_Union>(__u)._M_first._M_get(); }
224   template<size_t _Np, typename _Union>
225     constexpr decltype(auto) __get(in_place_index_t<_Np>, _Union&& __u)
226     {
227       return __variant::__get(in_place_index<_Np-1>,
228                               std::forward<_Union>(__u)._M_rest);
229     }
231   // Returns the typed storage for __v.
232   template<size_t _Np, typename _Variant>
233     constexpr decltype(auto) __get(_Variant&& __v)
234     {
235       return __variant::__get(std::in_place_index<_Np>,
236                               std::forward<_Variant>(__v)._M_u);
237     }
239   // Various functions as "vtable" entries, where those vtables are used by
240   // polymorphic operations.
241   template<typename _Lhs, typename _Rhs>
242     void
243     __erased_ctor(void* __lhs, void* __rhs)
244     {
245       using _Type = remove_reference_t<_Lhs>;
246       ::new (__lhs) _Type(__variant::__ref_cast<_Rhs>(__rhs));
247     }
249   template<typename _Variant, size_t _Np>
250     void
251     __erased_dtor(_Variant&& __v)
252     { std::_Destroy(std::__addressof(__variant::__get<_Np>(__v))); }
254   template<typename _Lhs, typename _Rhs>
255     void
256     __erased_assign(void* __lhs, void* __rhs)
257     {
258       __variant::__ref_cast<_Lhs>(__lhs) = __variant::__ref_cast<_Rhs>(__rhs);
259     }
261   template<typename _Lhs, typename _Rhs>
262     void
263     __erased_swap(void* __lhs, void* __rhs)
264     {
265       using std::swap;
266       swap(__variant::__ref_cast<_Lhs>(__lhs),
267            __variant::__ref_cast<_Rhs>(__rhs));
268     }
270 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
271   template<typename _Variant, size_t _Np> \
272     constexpr bool \
273     __erased_##__NAME(const _Variant& __lhs, const _Variant& __rhs) \
274     { \
275       return __variant::__get<_Np>(std::forward<_Variant>(__lhs)) \
276           __OP __variant::__get<_Np>(std::forward<_Variant>(__rhs)); \
277     }
279   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
280   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
281   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
282   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
283   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
284   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
286 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
288   template<typename _Tp>
289     size_t
290     __erased_hash(void* __t)
291     {
292       return std::hash<__remove_cvref_t<_Tp>>{}(
293           __variant::__ref_cast<_Tp>(__t));
294     }
296   template<typename... _Types>
297     struct _Traits
298     {
299       static constexpr bool _S_default_ctor =
300           is_default_constructible_v<typename _Nth_type<0, _Types...>::type>;
301       static constexpr bool _S_copy_ctor =
302           (is_copy_constructible_v<_Types> && ...);
303       static constexpr bool _S_move_ctor =
304           (is_move_constructible_v<_Types> && ...);
305       static constexpr bool _S_copy_assign =
306           _S_copy_ctor && _S_move_ctor
307           && (is_copy_assignable_v<_Types> && ...);
308       static constexpr bool _S_move_assign =
309           _S_move_ctor
310           && (is_move_assignable_v<_Types> && ...);
312       static constexpr bool _S_trivial_dtor =
313           (is_trivially_destructible_v<_Types> && ...);
314       static constexpr bool _S_trivial_copy_ctor =
315           (is_trivially_copy_constructible_v<_Types> && ...);
316       static constexpr bool _S_trivial_move_ctor =
317           (is_trivially_move_constructible_v<_Types> && ...);
318       static constexpr bool _S_trivial_copy_assign =
319           _S_trivial_dtor && (is_trivially_copy_assignable_v<_Types> && ...);
320       static constexpr bool _S_trivial_move_assign =
321           _S_trivial_dtor && (is_trivially_move_assignable_v<_Types> && ...);
323       // The following nothrow traits are for non-trivial SMFs. Trivial SMFs
324       // are always nothrow.
325       static constexpr bool _S_nothrow_default_ctor =
326           is_nothrow_default_constructible_v<
327               typename _Nth_type<0, _Types...>::type>;
328       static constexpr bool _S_nothrow_copy_ctor = false;
329       static constexpr bool _S_nothrow_move_ctor =
330           (is_nothrow_move_constructible_v<_Types> && ...);
331       static constexpr bool _S_nothrow_copy_assign = false;
332       static constexpr bool _S_nothrow_move_assign =
333           _S_nothrow_move_ctor && (is_nothrow_move_assignable_v<_Types> && ...);
334     };
336   // Defines members and ctors.
337   template<typename... _Types>
338     union _Variadic_union { };
340   template<typename _First, typename... _Rest>
341     union _Variadic_union<_First, _Rest...>
342     {
343       constexpr _Variadic_union() : _M_rest() { }
345       template<typename... _Args>
346         constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args)
347         : _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
348         { }
350       template<size_t _Np, typename... _Args>
351         constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
352         : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
353         { }
355       _Uninitialized<_First> _M_first;
356       _Variadic_union<_Rest...> _M_rest;
357     };
359   // Defines index and the dtor, possibly trivial.
360   template<bool __trivially_destructible, typename... _Types>
361     struct _Variant_storage;
363   template <typename... _Types>
364   using __select_index =
365     typename __select_int::_Select_int_base<sizeof...(_Types),
366                                             unsigned char,
367                                             unsigned short>::type::value_type;
369   template<typename... _Types>
370     struct _Variant_storage<false, _Types...>
371     {
372       template<size_t... __indices>
373         static constexpr void (*_S_vtable[])(const _Variant_storage&) =
374             { &__erased_dtor<const _Variant_storage&, __indices>... };
376       constexpr _Variant_storage() : _M_index(variant_npos) { }
378       template<size_t _Np, typename... _Args>
379         constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
380         : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
381         _M_index(_Np)
382         { }
384       template<size_t... __indices>
385         constexpr void _M_reset_impl(std::index_sequence<__indices...>)
386         {
387           if (_M_index != __index_type(variant_npos))
388             _S_vtable<__indices...>[_M_index](*this);
389         }
391       void _M_reset()
392       {
393         _M_reset_impl(std::index_sequence_for<_Types...>{});
394         _M_index = variant_npos;
395       }
397       ~_Variant_storage()
398       { _M_reset(); }
400       void*
401       _M_storage() const
402       {
403         return const_cast<void*>(static_cast<const void*>(
404             std::addressof(_M_u)));
405       }
407       constexpr bool
408       _M_valid() const noexcept
409       {
410         return this->_M_index != __index_type(variant_npos);
411       }
413       _Variadic_union<_Types...> _M_u;
414       using __index_type = __select_index<_Types...>;
415       __index_type _M_index;
416     };
418   template<typename... _Types>
419     struct _Variant_storage<true, _Types...>
420     {
421       constexpr _Variant_storage() : _M_index(variant_npos) { }
423       template<size_t _Np, typename... _Args>
424         constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
425         : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
426         _M_index(_Np)
427         { }
429       void _M_reset()
430       { _M_index = variant_npos; }
432       void*
433       _M_storage() const
434       {
435         return const_cast<void*>(static_cast<const void*>(
436             std::addressof(_M_u)));
437       }
439       constexpr bool
440       _M_valid() const noexcept
441       {
442         if constexpr ((is_trivially_copyable_v<_Types> && ...))
443           return true;
444         return this->_M_index != __index_type(variant_npos);
445       }
447       _Variadic_union<_Types...> _M_u;
448       using __index_type = __select_index<_Types...>;
449       __index_type _M_index;
450     };
452   template<typename... _Types>
453     using _Variant_storage_alias =
454         _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
456   // The following are (Copy|Move) (ctor|assign) layers for forwarding
457   // triviality and handling non-trivial SMF behaviors.
459   template<bool, typename... _Types>
460     struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
461     {
462       using _Base = _Variant_storage_alias<_Types...>;
463       using _Base::_Base;
465       _Copy_ctor_base(const _Copy_ctor_base& __rhs)
466           noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
467       {
468         if (__rhs._M_valid())
469           {
470             static constexpr void (*_S_vtable[])(void*, void*) =
471               { &__erased_ctor<_Types&, const _Types&>... };
472             _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
473             this->_M_index = __rhs._M_index;
474           }
475       }
477       _Copy_ctor_base(_Copy_ctor_base&&) = default;
478       _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default;
479       _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default;
480     };
482   template<typename... _Types>
483     struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
484     {
485       using _Base = _Variant_storage_alias<_Types...>;
486       using _Base::_Base;
487     };
489   template<typename... _Types>
490     using _Copy_ctor_alias =
491         _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
493   template<bool, typename... _Types>
494     struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
495     {
496       using _Base = _Copy_ctor_alias<_Types...>;
497       using _Base::_Base;
499       _Move_ctor_base(_Move_ctor_base&& __rhs)
500           noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
501       {
502         if (__rhs._M_valid())
503           {
504             static constexpr void (*_S_vtable[])(void*, void*) =
505               { &__erased_ctor<_Types&, _Types&&>... };
506             _S_vtable[__rhs._M_index](this->_M_storage(), __rhs._M_storage());
507             this->_M_index = __rhs._M_index;
508           }
509       }
511       void _M_destructive_move(_Move_ctor_base&& __rhs)
512       {
513         this->~_Move_ctor_base();
514         __try
515           {
516             ::new (this) _Move_ctor_base(std::move(__rhs));
517           }
518         __catch (...)
519           {
520             this->_M_index = variant_npos;
521             __throw_exception_again;
522           }
523       }
525       _Move_ctor_base(const _Move_ctor_base&) = default;
526       _Move_ctor_base& operator=(const _Move_ctor_base&) = default;
527       _Move_ctor_base& operator=(_Move_ctor_base&&) = default;
528     };
530   template<typename... _Types>
531     struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
532     {
533       using _Base = _Copy_ctor_alias<_Types...>;
534       using _Base::_Base;
536       void _M_destructive_move(_Move_ctor_base&& __rhs)
537       {
538         this->~_Move_ctor_base();
539         ::new (this) _Move_ctor_base(std::move(__rhs));
540       }
541     };
543   template<typename... _Types>
544     using _Move_ctor_alias =
545         _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
547   template<bool, typename... _Types>
548     struct _Copy_assign_base : _Move_ctor_alias<_Types...>
549     {
550       using _Base = _Move_ctor_alias<_Types...>;
551       using _Base::_Base;
553       _Copy_assign_base&
554       operator=(const _Copy_assign_base& __rhs)
555           noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
556       {
557         if (this->_M_index == __rhs._M_index)
558           {
559             if (__rhs._M_valid())
560               {
561                 static constexpr void (*_S_vtable[])(void*, void*) =
562                   { &__erased_assign<_Types&, const _Types&>... };
563                 _S_vtable[__rhs._M_index](this->_M_storage(),
564                                           __rhs._M_storage());
565               }
566           }
567         else
568           {
569             _Copy_assign_base __tmp(__rhs);
570             this->_M_destructive_move(std::move(__tmp));
571           }
572         __glibcxx_assert(this->_M_index == __rhs._M_index);
573         return *this;
574       }
576       _Copy_assign_base(const _Copy_assign_base&) = default;
577       _Copy_assign_base(_Copy_assign_base&&) = default;
578       _Copy_assign_base& operator=(_Copy_assign_base&&) = default;
579     };
581   template<typename... _Types>
582     struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
583     {
584       using _Base = _Move_ctor_alias<_Types...>;
585       using _Base::_Base;
586     };
588   template<typename... _Types>
589     using _Copy_assign_alias =
590         _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign,
591                           _Types...>;
593   template<bool, typename... _Types>
594     struct _Move_assign_base : _Copy_assign_alias<_Types...>
595     {
596       using _Base = _Copy_assign_alias<_Types...>;
597       using _Base::_Base;
599       _Move_assign_base&
600       operator=(_Move_assign_base&& __rhs)
601           noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
602       {
603         if (this->_M_index == __rhs._M_index)
604           {
605             if (__rhs._M_valid())
606               {
607                 static constexpr void (*_S_vtable[])(void*, void*) =
608                   { &__erased_assign<_Types&, _Types&&>... };
609                 _S_vtable[__rhs._M_index]
610                   (this->_M_storage(), __rhs._M_storage());
611               }
612           }
613         else
614           {
615             _Move_assign_base __tmp(std::move(__rhs));
616             this->_M_destructive_move(std::move(__tmp));
617           }
618         __glibcxx_assert(this->_M_index == __rhs._M_index);
619         return *this;
620       }
622       _Move_assign_base(const _Move_assign_base&) = default;
623       _Move_assign_base(_Move_assign_base&&) = default;
624       _Move_assign_base& operator=(const _Move_assign_base&) = default;
625     };
627   template<typename... _Types>
628     struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
629     {
630       using _Base = _Copy_assign_alias<_Types...>;
631       using _Base::_Base;
632     };
634   template<typename... _Types>
635     using _Move_assign_alias =
636         _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign,
637                           _Types...>;
639   template<typename... _Types>
640     struct _Variant_base : _Move_assign_alias<_Types...>
641     {
642       using _Base = _Move_assign_alias<_Types...>;
644       constexpr
645       _Variant_base()
646           noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
647       : _Variant_base(in_place_index<0>) { }
649       template<size_t _Np, typename... _Args>
650         constexpr explicit
651         _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
652         : _Base(__i, std::forward<_Args>(__args)...)
653         { }
655       _Variant_base(const _Variant_base&) = default;
656       _Variant_base(_Variant_base&&) = default;
657       _Variant_base& operator=(const _Variant_base&) = default;
658       _Variant_base& operator=(_Variant_base&&) = default;
659     };
661   // For how many times does _Tp appear in _Tuple?
662   template<typename _Tp, typename _Tuple>
663     struct __tuple_count;
665   template<typename _Tp, typename _Tuple>
666     inline constexpr size_t __tuple_count_v =
667       __tuple_count<_Tp, _Tuple>::value;
669   template<typename _Tp, typename... _Types>
670     struct __tuple_count<_Tp, tuple<_Types...>>
671     : integral_constant<size_t, 0> { };
673   template<typename _Tp, typename _First, typename... _Rest>
674     struct __tuple_count<_Tp, tuple<_First, _Rest...>>
675     : integral_constant<
676         size_t,
677         __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
679   // TODO: Reuse this in <tuple> ?
680   template<typename _Tp, typename... _Types>
681     inline constexpr bool __exactly_once =
682       __tuple_count_v<_Tp, tuple<_Types...>> == 1;
684   // Takes _Types and create an overloaded _S_fun for each type.
685   // If a type appears more than once in _Types, create only one overload.
686   template<typename... _Types>
687     struct __overload_set
688     { static void _S_fun(); };
690   template<typename _First, typename... _Rest>
691     struct __overload_set<_First, _Rest...> : __overload_set<_Rest...>
692     {
693       using __overload_set<_Rest...>::_S_fun;
694       static integral_constant<size_t, sizeof...(_Rest)> _S_fun(_First);
695     };
697   template<typename... _Rest>
698     struct __overload_set<void, _Rest...> : __overload_set<_Rest...>
699     {
700       using __overload_set<_Rest...>::_S_fun;
701     };
703   // Helper for variant(_Tp&&) and variant::operator=(_Tp&&).
704   // __accepted_index maps an arbitrary _Tp to an alternative type in _Variant
705   // (or to variant_npos).
706   template<typename _Tp, typename _Variant, typename = void>
707     struct __accepted_index
708     { static constexpr size_t value = variant_npos; };
710   template<typename _Tp, typename... _Types>
711     struct __accepted_index<
712       _Tp, variant<_Types...>,
713       void_t<decltype(__overload_set<_Types...>::_S_fun(std::declval<_Tp>()))>>
714     {
715       static constexpr size_t value = sizeof...(_Types) - 1
716         - decltype(__overload_set<_Types...>::
717                    _S_fun(std::declval<_Tp>()))::value;
718     };
720   // Returns the raw storage for __v.
721   template<typename _Variant>
722     void* __get_storage(_Variant&& __v)
723     { return __v._M_storage(); }
725   // Used for storing multi-dimensional vtable.
726   template<typename _Tp, size_t... _Dimensions>
727     struct _Multi_array
728     {
729       constexpr const _Tp&
730       _M_access() const
731       { return _M_data; }
733       _Tp _M_data;
734     };
736   template<typename _Tp, size_t __first, size_t... __rest>
737     struct _Multi_array<_Tp, __first, __rest...>
738     {
739       template<typename... _Args>
740         constexpr const _Tp&
741         _M_access(size_t __first_index, _Args... __rest_indices) const
742         { return _M_arr[__first_index]._M_access(__rest_indices...); }
744       _Multi_array<_Tp, __rest...> _M_arr[__first];
745     };
747   // Creates a multi-dimensional vtable recursively.
748   //
749   // For example,
750   // visit([](auto, auto){},
751   //       variant<int, char>(),  // typedef'ed as V1
752   //       variant<float, double, long double>())  // typedef'ed as V2
753   // will trigger instantiations of:
754   // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>,
755   //                   tuple<V1&&, V2&&>, std::index_sequence<>>
756   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
757   //                     tuple<V1&&, V2&&>, std::index_sequence<0>>
758   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
759   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 0>>
760   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
761   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 1>>
762   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
763   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 2>>
764   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
765   //                     tuple<V1&&, V2&&>, std::index_sequence<1>>
766   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
767   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 0>>
768   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
769   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 1>>
770   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
771   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 2>>
772   // The returned multi-dimensional vtable can be fast accessed by the visitor
773   // using index calculation.
774   template<typename _Array_type, typename _Variant_tuple, typename _Index_seq>
775     struct __gen_vtable_impl;
777   template<typename _Result_type, typename _Visitor, size_t... __dimensions,
778            typename... _Variants, size_t... __indices>
779     struct __gen_vtable_impl<
780         _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
781         tuple<_Variants...>, std::index_sequence<__indices...>>
782     {
783       using _Next =
784           remove_reference_t<typename _Nth_type<sizeof...(__indices),
785                              _Variants...>::type>;
786       using _Array_type =
787           _Multi_array<_Result_type (*)(_Visitor, _Variants...),
788                        __dimensions...>;
790       static constexpr _Array_type
791       _S_apply()
792       {
793         _Array_type __vtable{};
794         _S_apply_all_alts(
795           __vtable, make_index_sequence<variant_size_v<_Next>>());
796         return __vtable;
797       }
799       template<size_t... __var_indices>
800         static constexpr void
801         _S_apply_all_alts(_Array_type& __vtable,
802                           std::index_sequence<__var_indices...>)
803         {
804           (_S_apply_single_alt<__var_indices>(
805              __vtable._M_arr[__var_indices]), ...);
806         }
808       template<size_t __index, typename _Tp>
809         static constexpr void
810         _S_apply_single_alt(_Tp& __element)
811         {
812           using _Alternative = variant_alternative_t<__index, _Next>;
813           __element = __gen_vtable_impl<
814             remove_reference_t<decltype(__element)>, tuple<_Variants...>,
815             std::index_sequence<__indices..., __index>>::_S_apply();
816         }
817     };
819   template<typename _Result_type, typename _Visitor, typename... _Variants,
820            size_t... __indices>
821     struct __gen_vtable_impl<
822       _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
823                    tuple<_Variants...>, std::index_sequence<__indices...>>
824     {
825       using _Array_type =
826           _Multi_array<_Result_type (*)(_Visitor&&, _Variants...)>;
828       static constexpr decltype(auto)
829       __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
830       {
831         return std::__invoke(std::forward<_Visitor>(__visitor),
832             __variant::__get<__indices>(std::forward<_Variants>(__vars))...);
833       }
835       static constexpr auto
836       _S_apply()
837       { return _Array_type{&__visit_invoke}; }
838     };
840   template<typename _Result_type, typename _Visitor, typename... _Variants>
841     struct __gen_vtable
842     {
843       using _Func_ptr = _Result_type (*)(_Visitor&&, _Variants...);
844       using _Array_type =
845           _Multi_array<_Func_ptr,
846                        variant_size_v<remove_reference_t<_Variants>>...>;
848       static constexpr _Array_type
849       _S_apply()
850       {
851         return __gen_vtable_impl<_Array_type, tuple<_Variants...>,
852                                  std::index_sequence<>>::_S_apply();
853       }
855       static constexpr auto _S_vtable = _S_apply();
856     };
858   template<size_t _Np, typename _Tp>
859     struct _Base_dedup : public _Tp { };
861   template<typename _Variant, typename __indices>
862     struct _Variant_hash_base;
864   template<typename... _Types, size_t... __indices>
865     struct _Variant_hash_base<variant<_Types...>,
866                               std::index_sequence<__indices...>>
867     : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
869 } // namespace __variant
870 } // namespace __detail
872   template<typename _Tp, typename... _Types>
873     constexpr bool
874     holds_alternative(const variant<_Types...>& __v) noexcept
875     {
876       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
877                     "T should occur for exactly once in alternatives");
878       return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>;
879     }
881   template<typename _Tp, typename... _Types>
882     constexpr _Tp& get(variant<_Types...>& __v)
883     {
884       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
885                     "T should occur for exactly once in alternatives");
886       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
887       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
888     }
890   template<typename _Tp, typename... _Types>
891     constexpr _Tp&& get(variant<_Types...>&& __v)
892     {
893       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
894                     "T should occur for exactly once in alternatives");
895       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
896       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
897         std::move(__v));
898     }
900   template<typename _Tp, typename... _Types>
901     constexpr const _Tp& get(const variant<_Types...>& __v)
902     {
903       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
904                     "T should occur for exactly once in alternatives");
905       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
906       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
907     }
909   template<typename _Tp, typename... _Types>
910     constexpr const _Tp&& get(const variant<_Types...>&& __v)
911     {
912       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
913                     "T should occur for exactly once in alternatives");
914       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
915       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
916         std::move(__v));
917     }
919   template<size_t _Np, typename... _Types>
920     constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
921     get_if(variant<_Types...>* __ptr) noexcept
922     {
923       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
924       static_assert(_Np < sizeof...(_Types),
925                     "The index should be in [0, number of alternatives)");
926       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
927       if (__ptr && __ptr->index() == _Np)
928         return &__detail::__variant::__get<_Np>(*__ptr);
929       return nullptr;
930     }
932   template<size_t _Np, typename... _Types>
933     constexpr
934     add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
935     get_if(const variant<_Types...>* __ptr) noexcept
936     {
937       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
938       static_assert(_Np < sizeof...(_Types),
939                     "The index should be in [0, number of alternatives)");
940       static_assert(!is_void_v<_Alternative_type>, "_Tp should not be void");
941       if (__ptr && __ptr->index() == _Np)
942         return &__detail::__variant::__get<_Np>(*__ptr);
943       return nullptr;
944     }
946   template<typename _Tp, typename... _Types>
947     constexpr add_pointer_t<_Tp>
948     get_if(variant<_Types...>* __ptr) noexcept
949     {
950       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
951                     "T should occur for exactly once in alternatives");
952       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
953       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
954           __ptr);
955     }
957   template<typename _Tp, typename... _Types>
958     constexpr add_pointer_t<const _Tp>
959     get_if(const variant<_Types...>* __ptr)
960     noexcept
961     {
962       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
963                     "T should occur for exactly once in alternatives");
964       static_assert(!is_void_v<_Tp>, "_Tp should not be void");
965       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
966           __ptr);
967     }
969   struct monostate { };
971 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
972   template<typename... _Types> \
973     constexpr bool operator __OP(const variant<_Types...>& __lhs, \
974                                  const variant<_Types...>& __rhs) \
975     { \
976       return __lhs._M_##__NAME(__rhs, std::index_sequence_for<_Types...>{}); \
977     } \
979   constexpr bool operator __OP(monostate, monostate) noexcept \
980   { return 0 __OP 0; }
982   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
983   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
984   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
985   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
986   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
987   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
989 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
991   template<typename _Visitor, typename... _Variants>
992     constexpr decltype(auto) visit(_Visitor&&, _Variants&&...);
994   template<typename... _Types>
995     inline enable_if_t<(is_move_constructible_v<_Types> && ...)
996                         && (is_swappable_v<_Types> && ...)>
997     swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
998     noexcept(noexcept(__lhs.swap(__rhs)))
999     { __lhs.swap(__rhs); }
1001   template<typename... _Types>
1002     enable_if_t<!((is_move_constructible_v<_Types> && ...)
1003                    && (is_swappable_v<_Types> && ...))>
1004     swap(variant<_Types...>&, variant<_Types...>&) = delete;
1006   class bad_variant_access : public exception
1007   {
1008   public:
1009     bad_variant_access() noexcept : _M_reason("Unknown reason") { }
1010     const char* what() const noexcept override
1011     { return _M_reason; }
1013   private:
1014     bad_variant_access(const char* __reason) : _M_reason(__reason) { }
1016     const char* _M_reason;
1018     friend void __throw_bad_variant_access(const char* __what);
1019   };
1021   inline void
1022   __throw_bad_variant_access(const char* __what)
1023   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1025   template<typename... _Types>
1026     class variant
1027     : private __detail::__variant::_Variant_base<_Types...>,
1028       private _Enable_default_constructor<
1029         __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1030           variant<_Types...>>,
1031       private _Enable_copy_move<
1032         __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1033         __detail::__variant::_Traits<_Types...>::_S_copy_assign,
1034         __detail::__variant::_Traits<_Types...>::_S_move_ctor,
1035         __detail::__variant::_Traits<_Types...>::_S_move_assign,
1036         variant<_Types...>>
1037     {
1038     private:
1039       static_assert(sizeof...(_Types) > 0,
1040                     "variant must have at least one alternative");
1041       static_assert(!(std::is_reference_v<_Types> || ...),
1042                     "variant must have no reference alternative");
1043       static_assert(!(std::is_void_v<_Types> || ...),
1044                     "variant must have no void alternative");
1046       using _Base = __detail::__variant::_Variant_base<_Types...>;
1047       using _Default_ctor_enabler =
1048         _Enable_default_constructor<
1049           __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1050             variant<_Types...>>;
1052       template<typename _Tp>
1053         static constexpr bool
1054         __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1056       template<typename _Tp>
1057         static constexpr size_t __accepted_index =
1058           __detail::__variant::__accepted_index<_Tp&&, variant>::value;
1060       template<size_t _Np, bool = _Np < sizeof...(_Types)>
1061         struct __to_type_impl;
1063       template<size_t _Np>
1064         struct __to_type_impl<_Np, true>
1065         { using type = variant_alternative_t<_Np, variant>; };
1067       template<size_t _Np>
1068         using __to_type = typename __to_type_impl<_Np>::type;
1070       template<typename _Tp>
1071         using __accepted_type = __to_type<__accepted_index<_Tp>>;
1073       template<typename _Tp>
1074         static constexpr size_t __index_of =
1075           __detail::__variant::__index_of_v<_Tp, _Types...>;
1077       using _Traits = __detail::__variant::_Traits<_Types...>;
1079     public:
1080       variant() = default;
1081       variant(const variant& __rhs) = default;
1082       variant(variant&&) = default;
1083       variant& operator=(const variant&) = default;
1084       variant& operator=(variant&&) = default;
1085       ~variant() = default;
1087       template<typename _Tp,
1088                typename = enable_if_t<!is_same_v<decay_t<_Tp>, variant>>,
1089                typename = enable_if_t<(sizeof...(_Types)>0)>,
1090                typename = enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1091                           && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>>>
1092         constexpr
1093         variant(_Tp&& __t)
1094         noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1095         : variant(in_place_index<__accepted_index<_Tp&&>>,
1096                   std::forward<_Tp>(__t))
1097         { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); }
1099       template<typename _Tp, typename... _Args,
1100                typename = enable_if_t<__exactly_once<_Tp>
1101                           && is_constructible_v<_Tp, _Args&&...>>>
1102         constexpr explicit
1103         variant(in_place_type_t<_Tp>, _Args&&... __args)
1104         : variant(in_place_index<__index_of<_Tp>>,
1105                   std::forward<_Args>(__args)...)
1106         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1108       template<typename _Tp, typename _Up, typename... _Args,
1109                typename = enable_if_t<__exactly_once<_Tp>
1110                           && is_constructible_v<
1111                             _Tp, initializer_list<_Up>&, _Args&&...>>>
1112         constexpr explicit
1113         variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1114                 _Args&&... __args)
1115         : variant(in_place_index<__index_of<_Tp>>, __il,
1116                   std::forward<_Args>(__args)...)
1117         { __glibcxx_assert(holds_alternative<_Tp>(*this)); }
1119       template<size_t _Np, typename... _Args,
1120                typename = enable_if_t<
1121                  is_constructible_v<__to_type<_Np>, _Args&&...>>>
1122         constexpr explicit
1123         variant(in_place_index_t<_Np>, _Args&&... __args)
1124         : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
1125         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1126         { __glibcxx_assert(index() == _Np); }
1128       template<size_t _Np, typename _Up, typename... _Args,
1129                typename = enable_if_t<is_constructible_v<__to_type<_Np>,
1130                                       initializer_list<_Up>&, _Args&&...>>>
1131         constexpr explicit
1132         variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1133                 _Args&&... __args)
1134         : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1135         _Default_ctor_enabler(_Enable_default_constructor_tag{})
1136         { __glibcxx_assert(index() == _Np); }
1138       template<typename _Tp>
1139         enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1140                     && is_constructible_v<__accepted_type<_Tp&&>, _Tp&&>
1141                     && is_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1142                     && !is_same_v<decay_t<_Tp>, variant>, variant&>
1143         operator=(_Tp&& __rhs)
1144         noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp&&>
1145                  && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>)
1146         {
1147           constexpr auto __index = __accepted_index<_Tp&&>;
1148           if (index() == __index)
1149             std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1150           else
1151             this->emplace<__index>(std::forward<_Tp>(__rhs));
1152           __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this));
1153           return *this;
1154         }
1156       template<typename _Tp, typename... _Args>
1157         enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1158                     _Tp&>
1159         emplace(_Args&&... __args)
1160         {
1161           auto& ret =
1162             this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...);
1163           __glibcxx_assert(holds_alternative<_Tp>(*this));
1164           return ret;
1165         }
1167       template<typename _Tp, typename _Up, typename... _Args>
1168         enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1169                     && __exactly_once<_Tp>,
1170                     _Tp&>
1171         emplace(initializer_list<_Up> __il, _Args&&... __args)
1172         {
1173           auto& ret =
1174             this->emplace<__index_of<_Tp>>(__il,
1175                                            std::forward<_Args>(__args)...);
1176           __glibcxx_assert(holds_alternative<_Tp>(*this));
1177           return ret;
1178         }
1180       template<size_t _Np, typename... _Args>
1181         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1182                                        _Args...>,
1183                     variant_alternative_t<_Np, variant>&>
1184         emplace(_Args&&... __args)
1185         {
1186           static_assert(_Np < sizeof...(_Types),
1187                         "The index should be in [0, number of alternatives)");
1189           using type = variant_alternative_t<_Np, variant>;
1190           // If constructing the value can throw but move assigning it can't,
1191           // construct in a temporary and then move assign from it. This gives
1192           // the strong exception safety guarantee, ensuring we never become
1193           // valueless.
1194           if constexpr (is_trivially_copyable_v<type>
1195               && !is_nothrow_constructible_v<type, _Args...>)
1196             {
1197               // If move assignment cannot throw then we can provide the
1198               // strong exception safety guarantee, and never become valueless.
1199               variant __tmp(in_place_index<_Np>,
1200                             std::forward<_Args>(__args)...);
1201               *this = std::move(__tmp);
1202               return std::get<_Np>(*this);
1203             }
1205           this->~variant();
1206           __try
1207             {
1208               ::new (this) variant(in_place_index<_Np>,
1209                                    std::forward<_Args>(__args)...);
1210             }
1211           __catch (...)
1212             {
1213               this->_M_index = variant_npos;
1214               __throw_exception_again;
1215             }
1216           __glibcxx_assert(index() == _Np);
1217           return std::get<_Np>(*this);
1218         }
1220       template<size_t _Np, typename _Up, typename... _Args>
1221         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
1222                                        initializer_list<_Up>&, _Args...>,
1223                     variant_alternative_t<_Np, variant>&>
1224         emplace(initializer_list<_Up> __il, _Args&&... __args)
1225         {
1226           static_assert(_Np < sizeof...(_Types),
1227                         "The index should be in [0, number of alternatives)");
1229           using type = variant_alternative_t<_Np, variant>;
1230           if constexpr (is_trivially_copyable_v<type>
1231               && !is_nothrow_constructible_v<type, initializer_list<_Up>,
1232                                              _Args...>)
1233             {
1234               // If move assignment cannot throw then we can provide the
1235               // strong exception safety guarantee, and never become valueless.
1236               variant __tmp(in_place_index<_Np>, __il,
1237                             std::forward<_Args>(__args)...);
1238               *this = std::move(__tmp);
1239               return std::get<_Np>(*this);
1240             }
1242           this->~variant();
1243           __try
1244             {
1245               ::new (this) variant(in_place_index<_Np>, __il,
1246                                    std::forward<_Args>(__args)...);
1247             }
1248           __catch (...)
1249             {
1250               this->_M_index = variant_npos;
1251               __throw_exception_again;
1252             }
1253           __glibcxx_assert(index() == _Np);
1254           return std::get<_Np>(*this);
1255         }
1257       constexpr bool valueless_by_exception() const noexcept
1258       { return !this->_M_valid(); }
1260       constexpr size_t index() const noexcept
1261       {
1262         if (this->_M_index ==
1263             typename _Base::__index_type(variant_npos))
1264           return variant_npos;
1265         return this->_M_index;
1266       }
1268       void
1269       swap(variant& __rhs)
1270       noexcept((__is_nothrow_swappable<_Types>::value && ...)
1271                && is_nothrow_move_constructible_v<variant>)
1272       {
1273         if (this->index() == __rhs.index())
1274           {
1275             if (this->_M_valid())
1276               {
1277                 static constexpr void (*_S_vtable[])(void*, void*) =
1278                   { &__detail::__variant::__erased_swap<_Types&, _Types&>... };
1279                 _S_vtable[__rhs._M_index](this->_M_storage(),
1280                                           __rhs._M_storage());
1281               }
1282           }
1283         else if (!this->_M_valid())
1284           {
1285             this->_M_destructive_move(std::move(__rhs));
1286             __rhs._M_reset();
1287           }
1288         else if (!__rhs._M_valid())
1289           {
1290             __rhs._M_destructive_move(std::move(*this));
1291             this->_M_reset();
1292           }
1293         else
1294           {
1295             auto __tmp = std::move(__rhs);
1296             __rhs._M_destructive_move(std::move(*this));
1297             this->_M_destructive_move(std::move(__tmp));
1298           }
1299       }
1301     private:
1302 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1303       template<size_t... __indices> \
1304         static constexpr bool \
1305         (*_S_erased_##__NAME[])(const variant&, const variant&) = \
1306           { &__detail::__variant::__erased_##__NAME< \
1307                 const variant&, __indices>... }; \
1308       template<size_t... __indices> \
1309         constexpr bool \
1310         _M_##__NAME(const variant& __rhs, \
1311                     std::index_sequence<__indices...>) const \
1312         { \
1313           auto __lhs_index = this->index(); \
1314           auto __rhs_index = __rhs.index(); \
1315           if (__lhs_index != __rhs_index || valueless_by_exception()) \
1316             /* Modulo addition. */ \
1317             return __lhs_index + 1 __OP __rhs_index + 1; \
1318           return _S_erased_##__NAME<__indices...>[__lhs_index](*this, __rhs); \
1319         }
1321       _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1322       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1323       _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1324       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1325       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1326       _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1328 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1330 #if defined(__clang__) && __clang_major__ <= 7
1331     public:
1332       using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852
1333     private:
1334 #endif
1336       template<size_t _Np, typename _Vp>
1337         friend constexpr decltype(auto) __detail::__variant::__get(_Vp&& __v);
1339       template<typename _Vp>
1340         friend void* __detail::__variant::__get_storage(_Vp&& __v);
1342 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1343       template<typename... _Tp> \
1344         friend constexpr bool \
1345         operator __OP(const variant<_Tp...>& __lhs, \
1346                       const variant<_Tp...>& __rhs);
1348       _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1349       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1350       _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1351       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1352       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1353       _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1355 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1356     };
1358   template<size_t _Np, typename... _Types>
1359     constexpr variant_alternative_t<_Np, variant<_Types...>>&
1360     get(variant<_Types...>& __v)
1361     {
1362       static_assert(_Np < sizeof...(_Types),
1363                     "The index should be in [0, number of alternatives)");
1364       if (__v.index() != _Np)
1365         __throw_bad_variant_access("Unexpected index");
1366       return __detail::__variant::__get<_Np>(__v);
1367     }
1369   template<size_t _Np, typename... _Types>
1370     constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1371     get(variant<_Types...>&& __v)
1372     {
1373       static_assert(_Np < sizeof...(_Types),
1374                     "The index should be in [0, number of alternatives)");
1375       if (__v.index() != _Np)
1376         __throw_bad_variant_access("Unexpected index");
1377       return __detail::__variant::__get<_Np>(std::move(__v));
1378     }
1380   template<size_t _Np, typename... _Types>
1381     constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1382     get(const variant<_Types...>& __v)
1383     {
1384       static_assert(_Np < sizeof...(_Types),
1385                     "The index should be in [0, number of alternatives)");
1386       if (__v.index() != _Np)
1387         __throw_bad_variant_access("Unexpected index");
1388       return __detail::__variant::__get<_Np>(__v);
1389     }
1391   template<size_t _Np, typename... _Types>
1392     constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1393     get(const variant<_Types...>&& __v)
1394     {
1395       static_assert(_Np < sizeof...(_Types),
1396                     "The index should be in [0, number of alternatives)");
1397       if (__v.index() != _Np)
1398         __throw_bad_variant_access("Unexpected index");
1399       return __detail::__variant::__get<_Np>(std::move(__v));
1400     }
1402   template<typename _Visitor, typename... _Variants>
1403     constexpr decltype(auto)
1404     visit(_Visitor&& __visitor, _Variants&&... __variants)
1405     {
1406       if ((__variants.valueless_by_exception() || ...))
1407         __throw_bad_variant_access("Unexpected index");
1409       using _Result_type =
1410         decltype(std::forward<_Visitor>(__visitor)(
1411             std::get<0>(std::forward<_Variants>(__variants))...));
1413       constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1414         _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1416       auto __func_ptr = __vtable._M_access(__variants.index()...);
1417       return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1418                            std::forward<_Variants>(__variants)...);
1419     }
1421   template<bool, typename... _Types>
1422     struct __variant_hash_call_base_impl
1423     {
1424       size_t
1425       operator()(const variant<_Types...>& __t) const
1426       noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1427       {
1428         if (!__t.valueless_by_exception())
1429           {
1430             namespace __edv = __detail::__variant;
1431             static constexpr size_t (*_S_vtable[])(void*) =
1432               { &__edv::__erased_hash<const _Types&>... };
1433             return hash<size_t>{}(__t.index())
1434               + _S_vtable[__t.index()](__edv::__get_storage(__t));
1435           }
1436         return hash<size_t>{}(__t.index());
1437       }
1438     };
1440   template<typename... _Types>
1441     struct __variant_hash_call_base_impl<false, _Types...> {};
1443   template<typename... _Types>
1444     using __variant_hash_call_base =
1445     __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
1446                                    __enable_hash_call &&...), _Types...>;
1448   template<typename... _Types>
1449     struct hash<variant<_Types...>>
1450     : private __detail::__variant::_Variant_hash_base<
1451         variant<_Types...>, std::index_sequence_for<_Types...>>,
1452       public __variant_hash_call_base<_Types...>
1453     {
1454       using result_type [[__deprecated__]] = size_t;
1455       using argument_type [[__deprecated__]] = variant<_Types...>;
1456     };
1458   template<>
1459     struct hash<monostate>
1460     {
1461       using result_type [[__deprecated__]] = size_t;
1462       using argument_type [[__deprecated__]] = monostate;
1464       size_t
1465       operator()(const monostate& __t) const noexcept
1466       {
1467         constexpr size_t __magic_monostate_hash = -7777;
1468         return __magic_monostate_hash;
1469       }
1470     };
1472   template<typename... _Types>
1473     struct __is_fast_hash<hash<variant<_Types...>>>
1474     : bool_constant<(__is_fast_hash<_Types>::value && ...)>
1475     { };
1477 _GLIBCXX_END_NAMESPACE_VERSION
1478 } // namespace std
1480 #endif // C++17
1482 #endif // _GLIBCXX_VARIANT