LCOV - code coverage report
Current view: top level - 11 - variant (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 118 140 84.3 %
Date: 2025-08-24 09:11:10 Functions: 70 116 60.3 %

          Line data    Source code
       1             : // <variant> -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2016-2021 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             : #if __cplusplus > 201703L
      49             : # include <compare>
      50             : #endif
      51             : 
      52             : namespace std _GLIBCXX_VISIBILITY(default)
      53             : {
      54             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      55             : 
      56             : namespace __detail
      57             : {
      58             : namespace __variant
      59             : {
      60             :   template<size_t _Np, typename... _Types>
      61             :     struct _Nth_type;
      62             : 
      63             :   template<size_t _Np, typename _First, typename... _Rest>
      64             :     struct _Nth_type<_Np, _First, _Rest...>
      65             :     : _Nth_type<_Np-1, _Rest...> { };
      66             : 
      67             :   template<typename _First, typename... _Rest>
      68             :     struct _Nth_type<0, _First, _Rest...>
      69             :     { using type = _First; };
      70             : 
      71             : } // namespace __variant
      72             : } // namespace __detail
      73             : 
      74             : #define __cpp_lib_variant 202102L
      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             :   template<typename _Result_type, typename _Visitor, typename... _Variants>
     145             :     constexpr decltype(auto)
     146             :     __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
     147             : 
     148             :   template <typename... _Types, typename _Tp>
     149             :     decltype(auto)
     150           4 :     __variant_cast(_Tp&& __rhs)
     151             :     {
     152             :       if constexpr (is_lvalue_reference_v<_Tp>)
     153             :         {
     154             :           if constexpr (is_const_v<remove_reference_t<_Tp>>)
     155           1 :             return static_cast<const variant<_Types...>&>(__rhs);
     156             :           else
     157           3 :             return static_cast<variant<_Types...>&>(__rhs);
     158             :         }
     159             :       else
     160             :         return static_cast<variant<_Types...>&&>(__rhs);
     161             :     }
     162             : 
     163             : namespace __detail
     164             : {
     165             : namespace __variant
     166             : {
     167             :   // Returns the first appearance of _Tp in _Types.
     168             :   // Returns sizeof...(_Types) if _Tp is not in _Types.
     169             :   template<typename _Tp, typename... _Types>
     170             :     struct __index_of : std::integral_constant<size_t, 0> {};
     171             : 
     172             :   template<typename _Tp, typename... _Types>
     173             :     inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value;
     174             : 
     175             :   template<typename _Tp, typename _First, typename... _Rest>
     176             :     struct __index_of<_Tp, _First, _Rest...> :
     177             :       std::integral_constant<size_t, is_same_v<_Tp, _First>
     178             :         ? 0 : __index_of_v<_Tp, _Rest...> + 1> {};
     179             : 
     180             :   // used for raw visitation
     181             :   struct __variant_cookie {};
     182             :   // used for raw visitation with indices passed in
     183             :   struct __variant_idx_cookie { using type = __variant_idx_cookie; };
     184             :   // Used to enable deduction (and same-type checking) for std::visit:
     185             :   template<typename _Tp> struct __deduce_visit_result { using type = _Tp; };
     186             : 
     187             :   // Visit variants that might be valueless.
     188             :   template<typename _Visitor, typename... _Variants>
     189             :     constexpr void
     190           1 :     __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
     191             :     {
     192           1 :       std::__do_visit<__variant_cookie>(std::forward<_Visitor>(__visitor),
     193             :                                         std::forward<_Variants>(__variants)...);
     194           1 :     }
     195             : 
     196             :   // Visit variants that might be valueless, passing indices to the visitor.
     197             :   template<typename _Visitor, typename... _Variants>
     198             :     constexpr void
     199             :     __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
     200             :     {
     201             :       std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor),
     202             :           std::forward<_Variants>(__variants)...);
     203             :     }
     204             : 
     205             :   // The __as function templates implement the exposition-only "as-variant"
     206             : 
     207             :   template<typename... _Types>
     208             :     constexpr std::variant<_Types...>&
     209             :     __as(std::variant<_Types...>& __v) noexcept
     210             :     { return __v; }
     211             : 
     212             :   template<typename... _Types>
     213             :     constexpr const std::variant<_Types...>&
     214             :     __as(const std::variant<_Types...>& __v) noexcept
     215             :     { return __v; }
     216             : 
     217             :   template<typename... _Types>
     218             :     constexpr std::variant<_Types...>&&
     219             :     __as(std::variant<_Types...>&& __v) noexcept
     220             :     { return std::move(__v); }
     221             : 
     222             :   template<typename... _Types>
     223             :     constexpr const std::variant<_Types...>&&
     224             :     __as(const std::variant<_Types...>&& __v) noexcept
     225             :     { return std::move(__v); }
     226             : 
     227             :   // _Uninitialized<T> is guaranteed to be a trivially destructible type,
     228             :   // even if T is not.
     229             :   template<typename _Type, bool = std::is_trivially_destructible_v<_Type>>
     230             :     struct _Uninitialized;
     231             : 
     232             :   template<typename _Type>
     233             :     struct _Uninitialized<_Type, true>
     234             :     {
     235             :       template<typename... _Args>
     236             :         constexpr
     237           1 :         _Uninitialized(in_place_index_t<0>, _Args&&... __args)
     238             :         : _M_storage(std::forward<_Args>(__args)...)
     239           1 :         { }
     240             : 
     241           0 :       constexpr const _Type& _M_get() const & noexcept
     242           0 :       { return _M_storage; }
     243             : 
     244          40 :       constexpr _Type& _M_get() & noexcept
     245          40 :       { return _M_storage; }
     246             : 
     247             :       constexpr const _Type&& _M_get() const && noexcept
     248             :       { return std::move(_M_storage); }
     249             : 
     250             :       constexpr _Type&& _M_get() && noexcept
     251             :       { return std::move(_M_storage); }
     252             : 
     253             :       _Type _M_storage;
     254             :     };
     255             : 
     256             :   template<typename _Type>
     257             :     struct _Uninitialized<_Type, false>
     258             :     {
     259             :       template<typename... _Args>
     260             :         constexpr
     261             :         _Uninitialized(in_place_index_t<0>, _Args&&... __args)
     262             :         {
     263             :           ::new ((void*)std::addressof(_M_storage))
     264             :             _Type(std::forward<_Args>(__args)...);
     265             :         }
     266             : 
     267           2 :       const _Type& _M_get() const & noexcept
     268           2 :       { return *_M_storage._M_ptr(); }
     269             : 
     270           4 :       _Type& _M_get() & noexcept
     271           4 :       { return *_M_storage._M_ptr(); }
     272             : 
     273             :       const _Type&& _M_get() const && noexcept
     274             :       { return std::move(*_M_storage._M_ptr()); }
     275             : 
     276             :       _Type&& _M_get() && noexcept
     277             :       { return std::move(*_M_storage._M_ptr()); }
     278             : 
     279             :       __gnu_cxx::__aligned_membuf<_Type> _M_storage;
     280             :     };
     281             : 
     282             :   template<typename _Union>
     283             :     constexpr decltype(auto)
     284          46 :     __get(in_place_index_t<0>, _Union&& __u) noexcept
     285          46 :     { return std::forward<_Union>(__u)._M_first._M_get(); }
     286             : 
     287             :   template<size_t _Np, typename _Union>
     288             :     constexpr decltype(auto)
     289          45 :     __get(in_place_index_t<_Np>, _Union&& __u) noexcept
     290             :     {
     291          45 :       return __variant::__get(in_place_index<_Np-1>,
     292          45 :                               std::forward<_Union>(__u)._M_rest);
     293             :     }
     294             : 
     295             :   // Returns the typed storage for __v.
     296             :   template<size_t _Np, typename _Variant>
     297             :     constexpr decltype(auto)
     298          46 :     __get(_Variant&& __v) noexcept
     299             :     {
     300          46 :       return __variant::__get(std::in_place_index<_Np>,
     301          46 :                               std::forward<_Variant>(__v)._M_u);
     302             :     }
     303             : 
     304             :   template<typename... _Types>
     305             :     struct _Traits
     306             :     {
     307             :       static constexpr bool _S_default_ctor =
     308             :           is_default_constructible_v<typename _Nth_type<0, _Types...>::type>;
     309             :       static constexpr bool _S_copy_ctor =
     310             :           (is_copy_constructible_v<_Types> && ...);
     311             :       static constexpr bool _S_move_ctor =
     312             :           (is_move_constructible_v<_Types> && ...);
     313             :       static constexpr bool _S_copy_assign =
     314             :           _S_copy_ctor
     315             :           && (is_copy_assignable_v<_Types> && ...);
     316             :       static constexpr bool _S_move_assign =
     317             :           _S_move_ctor
     318             :           && (is_move_assignable_v<_Types> && ...);
     319             : 
     320             :       static constexpr bool _S_trivial_dtor =
     321             :           (is_trivially_destructible_v<_Types> && ...);
     322             :       static constexpr bool _S_trivial_copy_ctor =
     323             :           (is_trivially_copy_constructible_v<_Types> && ...);
     324             :       static constexpr bool _S_trivial_move_ctor =
     325             :           (is_trivially_move_constructible_v<_Types> && ...);
     326             :       static constexpr bool _S_trivial_copy_assign =
     327             :           _S_trivial_dtor && _S_trivial_copy_ctor
     328             :           && (is_trivially_copy_assignable_v<_Types> && ...);
     329             :       static constexpr bool _S_trivial_move_assign =
     330             :           _S_trivial_dtor && _S_trivial_move_ctor
     331             :           && (is_trivially_move_assignable_v<_Types> && ...);
     332             : 
     333             :       // The following nothrow traits are for non-trivial SMFs. Trivial SMFs
     334             :       // are always nothrow.
     335             :       static constexpr bool _S_nothrow_default_ctor =
     336             :           is_nothrow_default_constructible_v<
     337             :               typename _Nth_type<0, _Types...>::type>;
     338             :       static constexpr bool _S_nothrow_copy_ctor = false;
     339             :       static constexpr bool _S_nothrow_move_ctor =
     340             :           (is_nothrow_move_constructible_v<_Types> && ...);
     341             :       static constexpr bool _S_nothrow_copy_assign = false;
     342             :       static constexpr bool _S_nothrow_move_assign =
     343             :           _S_nothrow_move_ctor
     344             :           && (is_nothrow_move_assignable_v<_Types> && ...);
     345             :     };
     346             : 
     347             :   // Defines members and ctors.
     348             :   template<typename... _Types>
     349             :     union _Variadic_union { };
     350             : 
     351             :   template<typename _First, typename... _Rest>
     352             :     union _Variadic_union<_First, _Rest...>
     353             :     {
     354           3 :       constexpr _Variadic_union() : _M_rest() { }
     355             : 
     356             :       template<typename... _Args>
     357           1 :         constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args)
     358           1 :         : _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
     359           1 :         { }
     360             : 
     361             :       template<size_t _Np, typename... _Args>
     362             :         constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
     363             :         : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
     364             :         { }
     365             : 
     366             :       _Uninitialized<_First> _M_first;
     367             :       _Variadic_union<_Rest...> _M_rest;
     368             :     };
     369             : 
     370             :   // _Never_valueless_alt is true for variant alternatives that can
     371             :   // always be placed in a variant without it becoming valueless.
     372             : 
     373             :   // For suitably-small, trivially copyable types we can create temporaries
     374             :   // on the stack and then memcpy them into place.
     375             :   template<typename _Tp>
     376             :     struct _Never_valueless_alt
     377             :     : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
     378             :     { };
     379             : 
     380             :   // Specialize _Never_valueless_alt for other types which have a
     381             :   // non-throwing and cheap move construction and move assignment operator,
     382             :   // so that emplacing the type will provide the strong exception-safety
     383             :   // guarantee, by creating and moving a temporary.
     384             :   // Whether _Never_valueless_alt<T> is true or not affects the ABI of a
     385             :   // variant using that alternative, so we can't change the value later!
     386             : 
     387             :   // True if every alternative in _Types... can be emplaced in a variant
     388             :   // without it becoming valueless. If this is true, variant<_Types...>
     389             :   // can never be valueless, which enables some minor optimizations.
     390             :   template <typename... _Types>
     391             :     constexpr bool __never_valueless()
     392             :     {
     393             :       return _Traits<_Types...>::_S_move_assign
     394             :         && (_Never_valueless_alt<_Types>::value && ...);
     395             :     }
     396             : 
     397             :   // Defines index and the dtor, possibly trivial.
     398             :   template<bool __trivially_destructible, typename... _Types>
     399             :     struct _Variant_storage;
     400             : 
     401             :   template <typename... _Types>
     402             :     using __select_index =
     403             :       typename __select_int::_Select_int_base<sizeof...(_Types),
     404             :                                               unsigned char,
     405             :                                               unsigned short>::type::value_type;
     406             : 
     407             :   template<typename... _Types>
     408             :     struct _Variant_storage<false, _Types...>
     409             :     {
     410             :       constexpr
     411           1 :       _Variant_storage()
     412           1 :       : _M_index(static_cast<__index_type>(variant_npos))
     413           1 :       { }
     414             : 
     415             :       template<size_t _Np, typename... _Args>
     416             :         constexpr
     417           1 :         _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
     418           1 :         : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
     419           1 :         _M_index{_Np}
     420           1 :         { }
     421             : 
     422           3 :       void _M_reset()
     423             :       {
     424           3 :         if (!_M_valid()) [[unlikely]]
     425           0 :           return;
     426             : 
     427           9 :         std::__do_visit<void>([](auto&& __this_mem) mutable
     428             :           {
     429           3 :             std::_Destroy(std::__addressof(__this_mem));
     430             :           }, __variant_cast<_Types...>(*this));
     431             : 
     432           3 :         _M_index = static_cast<__index_type>(variant_npos);
     433             :       }
     434             : 
     435           2 :       ~_Variant_storage()
     436           2 :       { _M_reset(); }
     437             : 
     438             :       constexpr bool
     439           3 :       _M_valid() const noexcept
     440             :       {
     441             :         if constexpr (__variant::__never_valueless<_Types...>())
     442             :           return true;
     443           3 :         return this->_M_index != __index_type(variant_npos);
     444             :       }
     445             : 
     446             :       _Variadic_union<_Types...> _M_u;
     447             :       using __index_type = __select_index<_Types...>;
     448             :       __index_type _M_index;
     449             :     };
     450             : 
     451             :   template<typename... _Types>
     452             :     struct _Variant_storage<true, _Types...>
     453             :     {
     454             :       constexpr
     455             :       _Variant_storage()
     456             :       : _M_index(static_cast<__index_type>(variant_npos))
     457             :       { }
     458             : 
     459             :       template<size_t _Np, typename... _Args>
     460             :         constexpr
     461             :         _Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
     462             :         : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
     463             :         _M_index{_Np}
     464             :         { }
     465             : 
     466          13 :       void _M_reset() noexcept
     467          13 :       { _M_index = static_cast<__index_type>(variant_npos); }
     468             : 
     469             :       constexpr bool
     470           0 :       _M_valid() const noexcept
     471             :       {
     472             :         if constexpr (__variant::__never_valueless<_Types...>())
     473           0 :           return true;
     474             :         return this->_M_index != static_cast<__index_type>(variant_npos);
     475             :       }
     476             : 
     477             :       _Variadic_union<_Types...> _M_u;
     478             :       using __index_type = __select_index<_Types...>;
     479             :       __index_type _M_index;
     480             :     };
     481             : 
     482             :   template<typename... _Types>
     483             :     using _Variant_storage_alias =
     484             :         _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
     485             : 
     486             :   template<typename _Tp, typename _Up>
     487           1 :     void __variant_construct_single(_Tp&& __lhs, _Up&& __rhs_mem)
     488             :     {
     489           1 :       void* __storage = std::addressof(__lhs._M_u);
     490             :       using _Type = remove_reference_t<decltype(__rhs_mem)>;
     491             :       if constexpr (!is_same_v<_Type, __variant_cookie>)
     492           1 :         ::new (__storage)
     493           1 :           _Type(std::forward<decltype(__rhs_mem)>(__rhs_mem));
     494           1 :     }
     495             : 
     496             :   template<typename... _Types, typename _Tp, typename _Up>
     497           1 :     void __variant_construct(_Tp&& __lhs, _Up&& __rhs)
     498             :     {
     499           1 :       __lhs._M_index = __rhs._M_index;
     500           4 :       __variant::__raw_visit([&__lhs](auto&& __rhs_mem) mutable
     501             :         {
     502           1 :           __variant_construct_single(std::forward<_Tp>(__lhs),
     503             :               std::forward<decltype(__rhs_mem)>(__rhs_mem));
     504             :         }, __variant_cast<_Types...>(std::forward<_Up>(__rhs)));
     505           1 :     }
     506             : 
     507             :   // The following are (Copy|Move) (ctor|assign) layers for forwarding
     508             :   // triviality and handling non-trivial SMF behaviors.
     509             : 
     510             :   template<bool, typename... _Types>
     511             :     struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
     512             :     {
     513             :       using _Base = _Variant_storage_alias<_Types...>;
     514             :       using _Base::_Base;
     515             : 
     516           1 :       _Copy_ctor_base(const _Copy_ctor_base& __rhs)
     517             :           noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
     518           1 :       {
     519           1 :         __variant_construct<_Types...>(*this, __rhs);
     520           1 :       }
     521             : 
     522             :       _Copy_ctor_base(_Copy_ctor_base&&) = default;
     523             :       _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default;
     524             :       _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default;
     525             :     };
     526             : 
     527             :   template<typename... _Types>
     528             :     struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
     529             :     {
     530             :       using _Base = _Variant_storage_alias<_Types...>;
     531             :       using _Base::_Base;
     532             :     };
     533             : 
     534             :   template<typename... _Types>
     535             :     using _Copy_ctor_alias =
     536             :         _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
     537             : 
     538             :   template<bool, typename... _Types>
     539             :     struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
     540             :     {
     541             :       using _Base = _Copy_ctor_alias<_Types...>;
     542             :       using _Base::_Base;
     543             : 
     544             :       _Move_ctor_base(_Move_ctor_base&& __rhs)
     545             :           noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
     546             :       {
     547             :         __variant_construct<_Types...>(*this, std::move(__rhs));
     548             :       }
     549             : 
     550             :       template<typename _Up>
     551             :         void _M_destructive_move(unsigned short __rhs_index, _Up&& __rhs)
     552             :         {
     553             :           this->_M_reset();
     554             :           __variant_construct_single(*this, std::forward<_Up>(__rhs));
     555             :           this->_M_index = __rhs_index;
     556             :         }
     557             : 
     558             :       template<typename _Up>
     559             :         void _M_destructive_copy(unsigned short __rhs_index, const _Up& __rhs)
     560             :         {
     561             :           this->_M_reset();
     562             :           __variant_construct_single(*this, __rhs);
     563             :           this->_M_index = __rhs_index;
     564             :         }
     565             : 
     566           1 :       _Move_ctor_base(const _Move_ctor_base&) = default;
     567             :       _Move_ctor_base& operator=(const _Move_ctor_base&) = default;
     568             :       _Move_ctor_base& operator=(_Move_ctor_base&&) = default;
     569             :     };
     570             : 
     571             :   template<typename... _Types>
     572             :     struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
     573             :     {
     574             :       using _Base = _Copy_ctor_alias<_Types...>;
     575             :       using _Base::_Base;
     576             : 
     577             :       template<typename _Up>
     578             :         void _M_destructive_move(unsigned short __rhs_index, _Up&& __rhs)
     579             :         {
     580             :           this->_M_reset();
     581             :           __variant_construct_single(*this, std::forward<_Up>(__rhs));
     582             :           this->_M_index = __rhs_index;
     583             :         }
     584             : 
     585             :       template<typename _Up>
     586             :         void _M_destructive_copy(unsigned short __rhs_index, const _Up& __rhs)
     587             :         {
     588             :           this->_M_reset();
     589             :           __variant_construct_single(*this, __rhs);
     590             :           this->_M_index = __rhs_index;
     591             :         }
     592             :     };
     593             : 
     594             :   template<typename... _Types>
     595             :     using _Move_ctor_alias =
     596             :         _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
     597             : 
     598             :   template<bool, typename... _Types>
     599             :     struct _Copy_assign_base : _Move_ctor_alias<_Types...>
     600             :     {
     601             :       using _Base = _Move_ctor_alias<_Types...>;
     602             :       using _Base::_Base;
     603             : 
     604             :       _Copy_assign_base&
     605             :       operator=(const _Copy_assign_base& __rhs)
     606             :           noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
     607             :       {
     608             :         __variant::__raw_idx_visit(
     609             :           [this](auto&& __rhs_mem, auto __rhs_index) mutable
     610             :           {
     611             :             if constexpr (__rhs_index != variant_npos)
     612             :               {
     613             :                 if (this->_M_index == __rhs_index)
     614             :                   __variant::__get<__rhs_index>(*this) = __rhs_mem;
     615             :                 else
     616             :                   {
     617             :                     using __rhs_type = __remove_cvref_t<decltype(__rhs_mem)>;
     618             :                     if constexpr (is_nothrow_copy_constructible_v<__rhs_type>
     619             :                         || !is_nothrow_move_constructible_v<__rhs_type>)
     620             :                       // The standard says this->emplace<__rhs_type>(__rhs_mem)
     621             :                       // should be used here, but _M_destructive_copy is
     622             :                       // equivalent in this case. Either copy construction
     623             :                       // doesn't throw, so _M_destructive_copy gives strong
     624             :                       // exception safety guarantee, or both copy construction
     625             :                       // and move construction can throw, so emplace only gives
     626             :                       // basic exception safety anyway.
     627             :                       this->_M_destructive_copy(__rhs_index, __rhs_mem);
     628             :                     else
     629             :                       __variant_cast<_Types...>(*this)
     630             :                         = variant<_Types...>(std::in_place_index<__rhs_index>,
     631             :                                              __rhs_mem);
     632             :                   }
     633             :               }
     634             :             else
     635             :               this->_M_reset();
     636             :           }, __variant_cast<_Types...>(__rhs));
     637             :         return *this;
     638             :       }
     639             : 
     640           1 :       _Copy_assign_base(const _Copy_assign_base&) = default;
     641             :       _Copy_assign_base(_Copy_assign_base&&) = default;
     642             :       _Copy_assign_base& operator=(_Copy_assign_base&&) = default;
     643             :     };
     644             : 
     645             :   template<typename... _Types>
     646             :     struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
     647             :     {
     648             :       using _Base = _Move_ctor_alias<_Types...>;
     649             :       using _Base::_Base;
     650             :     };
     651             : 
     652             :   template<typename... _Types>
     653             :     using _Copy_assign_alias =
     654             :       _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
     655             : 
     656             :   template<bool, typename... _Types>
     657             :     struct _Move_assign_base : _Copy_assign_alias<_Types...>
     658             :     {
     659             :       using _Base = _Copy_assign_alias<_Types...>;
     660             :       using _Base::_Base;
     661             : 
     662             :       _Move_assign_base&
     663             :       operator=(_Move_assign_base&& __rhs)
     664             :           noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
     665             :       {
     666             :         __variant::__raw_idx_visit(
     667             :           [this](auto&& __rhs_mem, auto __rhs_index) mutable
     668             :           {
     669             :             if constexpr (__rhs_index != variant_npos)
     670             :               {
     671             :                 if (this->_M_index == __rhs_index)
     672             :                   __variant::__get<__rhs_index>(*this) = std::move(__rhs_mem);
     673             :                 else
     674             :                   __variant_cast<_Types...>(*this)
     675             :                     .template emplace<__rhs_index>(std::move(__rhs_mem));
     676             :               }
     677             :             else
     678             :               this->_M_reset();
     679             :           }, __variant_cast<_Types...>(__rhs));
     680             :         return *this;
     681             :       }
     682             : 
     683           1 :       _Move_assign_base(const _Move_assign_base&) = default;
     684             :       _Move_assign_base(_Move_assign_base&&) = default;
     685             :       _Move_assign_base& operator=(const _Move_assign_base&) = default;
     686             :     };
     687             : 
     688             :   template<typename... _Types>
     689             :     struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
     690             :     {
     691             :       using _Base = _Copy_assign_alias<_Types...>;
     692             :       using _Base::_Base;
     693             :     };
     694             : 
     695             :   template<typename... _Types>
     696             :     using _Move_assign_alias =
     697             :       _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
     698             : 
     699             :   template<typename... _Types>
     700             :     struct _Variant_base : _Move_assign_alias<_Types...>
     701             :     {
     702             :       using _Base = _Move_assign_alias<_Types...>;
     703             : 
     704             :       constexpr
     705           1 :       _Variant_base()
     706             :           noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
     707           1 :       : _Variant_base(in_place_index<0>) { }
     708             : 
     709             :       template<size_t _Np, typename... _Args>
     710             :         constexpr explicit
     711           1 :         _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
     712           1 :         : _Base(__i, std::forward<_Args>(__args)...)
     713           1 :         { }
     714             : 
     715           1 :       _Variant_base(const _Variant_base&) = default;
     716             :       _Variant_base(_Variant_base&&) = default;
     717             :       _Variant_base& operator=(const _Variant_base&) = default;
     718             :       _Variant_base& operator=(_Variant_base&&) = default;
     719             :     };
     720             : 
     721             :   // For how many times does _Tp appear in _Tuple?
     722             :   template<typename _Tp, typename _Tuple>
     723             :     struct __tuple_count;
     724             : 
     725             :   template<typename _Tp, typename _Tuple>
     726             :     inline constexpr size_t __tuple_count_v =
     727             :       __tuple_count<_Tp, _Tuple>::value;
     728             : 
     729             :   template<typename _Tp, typename... _Types>
     730             :     struct __tuple_count<_Tp, tuple<_Types...>>
     731             :     : integral_constant<size_t, 0> { };
     732             : 
     733             :   template<typename _Tp, typename _First, typename... _Rest>
     734             :     struct __tuple_count<_Tp, tuple<_First, _Rest...>>
     735             :     : integral_constant<
     736             :         size_t,
     737             :         __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { };
     738             : 
     739             :   // TODO: Reuse this in <tuple> ?
     740             :   template<typename _Tp, typename... _Types>
     741             :     inline constexpr bool __exactly_once =
     742             :       __tuple_count_v<_Tp, tuple<_Types...>> == 1;
     743             : 
     744             :   // Helper used to check for valid conversions that don't involve narrowing.
     745             :   template<typename _Ti> struct _Arr { _Ti _M_x[1]; };
     746             : 
     747             :   // "Build an imaginary function FUN(Ti) for each alternative type Ti"
     748             :   template<size_t _Ind, typename _Tp, typename _Ti, typename = void>
     749             :     struct _Build_FUN
     750             :     {
     751             :       // This function means 'using _Build_FUN<I, T, Ti>::_S_fun;' is valid,
     752             :       // but only static functions will be considered in the call below.
     753             :       void _S_fun();
     754             :     };
     755             : 
     756             :   // "... for which Ti x[] = {std::forward<T>(t)}; is well-formed."
     757             :   template<size_t _Ind, typename _Tp, typename _Ti>
     758             :     struct _Build_FUN<_Ind, _Tp, _Ti,
     759             :                       void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>>
     760             :     {
     761             :       // This is the FUN function for type _Ti, with index _Ind
     762             :       static integral_constant<size_t, _Ind> _S_fun(_Ti);
     763             :     };
     764             : 
     765             :   template<typename _Tp, typename _Variant,
     766             :            typename = make_index_sequence<variant_size_v<_Variant>>>
     767             :     struct _Build_FUNs;
     768             : 
     769             :   template<typename _Tp, typename... _Ti, size_t... _Ind>
     770             :     struct _Build_FUNs<_Tp, variant<_Ti...>, index_sequence<_Ind...>>
     771             :     : _Build_FUN<_Ind, _Tp, _Ti>...
     772             :     {
     773             :       using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
     774             :     };
     775             : 
     776             :   // The index j of the overload FUN(Tj) selected by overload resolution
     777             :   // for FUN(std::forward<_Tp>(t))
     778             :   template<typename _Tp, typename _Variant>
     779             :     using _FUN_type
     780             :       = decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>()));
     781             : 
     782             :   // The index selected for FUN(std::forward<T>(t)), or variant_npos if none.
     783             :   template<typename _Tp, typename _Variant, typename = void>
     784             :     struct __accepted_index
     785             :     : integral_constant<size_t, variant_npos>
     786             :     { };
     787             : 
     788             :   template<typename _Tp, typename _Variant>
     789             :     struct __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
     790             :     : _FUN_type<_Tp, _Variant>
     791             :     { };
     792             : 
     793             :   template <typename _Maybe_variant_cookie, typename _Variant>
     794             :     struct _Extra_visit_slot_needed
     795             :     {
     796             :       template <typename> struct _Variant_never_valueless;
     797             : 
     798             :       template <typename... _Types>
     799             :         struct _Variant_never_valueless<variant<_Types...>>
     800             :         : bool_constant<__variant::__never_valueless<_Types...>()> {};
     801             : 
     802             :       static constexpr bool value =
     803             :         (is_same_v<_Maybe_variant_cookie, __variant_cookie>
     804             :          || is_same_v<_Maybe_variant_cookie, __variant_idx_cookie>)
     805             :         && !_Variant_never_valueless<__remove_cvref_t<_Variant>>::value;
     806             :     };
     807             : 
     808             :   // Used for storing a multi-dimensional vtable.
     809             :   template<typename _Tp, size_t... _Dimensions>
     810             :     struct _Multi_array;
     811             : 
     812             :   // Partial specialization with rank zero, stores a single _Tp element.
     813             :   template<typename _Tp>
     814             :     struct _Multi_array<_Tp>
     815             :     {
     816             :       template<typename>
     817             :         struct __untag_result
     818             :         : false_type
     819             :         { using element_type = _Tp; };
     820             : 
     821             :       template <typename... _Args>
     822             :         struct __untag_result<const void(*)(_Args...)>
     823             :         : false_type
     824             :         { using element_type = void(*)(_Args...); };
     825             : 
     826             :       template <typename... _Args>
     827             :         struct __untag_result<__variant_cookie(*)(_Args...)>
     828             :         : false_type
     829             :         { using element_type = void(*)(_Args...); };
     830             : 
     831             :       template <typename... _Args>
     832             :         struct __untag_result<__variant_idx_cookie(*)(_Args...)>
     833             :         : false_type
     834             :         { using element_type = void(*)(_Args...); };
     835             : 
     836             :       template <typename _Res, typename... _Args>
     837             :         struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
     838             :         : true_type
     839             :         { using element_type = _Res(*)(_Args...); };
     840             : 
     841             :       using __result_is_deduced = __untag_result<_Tp>;
     842             : 
     843             :       constexpr const typename __untag_result<_Tp>::element_type&
     844           4 :       _M_access() const
     845           4 :       { return _M_data; }
     846             : 
     847             :       typename __untag_result<_Tp>::element_type _M_data;
     848             :     };
     849             : 
     850             :   // Partial specialization with rank >= 1.
     851             :   template<typename _Ret,
     852             :            typename _Visitor,
     853             :            typename... _Variants,
     854             :            size_t __first, size_t... __rest>
     855             :     struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
     856             :     {
     857             :       static constexpr size_t __index =
     858             :         sizeof...(_Variants) - sizeof...(__rest) - 1;
     859             : 
     860             :       using _Variant = typename _Nth_type<__index, _Variants...>::type;
     861             : 
     862             :       static constexpr int __do_cookie =
     863             :         _Extra_visit_slot_needed<_Ret, _Variant>::value ? 1 : 0;
     864             : 
     865             :       using _Tp = _Ret(*)(_Visitor, _Variants...);
     866             : 
     867             :       template<typename... _Args>
     868             :         constexpr decltype(auto)
     869           4 :         _M_access(size_t __first_index, _Args... __rest_indices) const
     870             :         {
     871           1 :           return _M_arr[__first_index + __do_cookie]
     872           4 :             ._M_access(__rest_indices...);
     873             :         }
     874             : 
     875             :       _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
     876             :     };
     877             : 
     878             :   // Creates a multi-dimensional vtable recursively.
     879             :   //
     880             :   // For example,
     881             :   // visit([](auto, auto){},
     882             :   //       variant<int, char>(),  // typedef'ed as V1
     883             :   //       variant<float, double, long double>())  // typedef'ed as V2
     884             :   // will trigger instantiations of:
     885             :   // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>,
     886             :   //                   tuple<V1&&, V2&&>, std::index_sequence<>>
     887             :   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
     888             :   //                     tuple<V1&&, V2&&>, std::index_sequence<0>>
     889             :   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
     890             :   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 0>>
     891             :   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
     892             :   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 1>>
     893             :   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
     894             :   //                       tuple<V1&&, V2&&>, std::index_sequence<0, 2>>
     895             :   //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
     896             :   //                     tuple<V1&&, V2&&>, std::index_sequence<1>>
     897             :   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
     898             :   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 0>>
     899             :   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
     900             :   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 1>>
     901             :   //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
     902             :   //                       tuple<V1&&, V2&&>, std::index_sequence<1, 2>>
     903             :   // The returned multi-dimensional vtable can be fast accessed by the visitor
     904             :   // using index calculation.
     905             :   template<typename _Array_type, typename _Index_seq>
     906             :     struct __gen_vtable_impl;
     907             : 
     908             :   // Defines the _S_apply() member that returns a _Multi_array populated
     909             :   // with function pointers that perform the visitation expressions e(m)
     910             :   // for each valid pack of indexes into the variant types _Variants.
     911             :   //
     912             :   // This partial specialization builds up the index sequences by recursively
     913             :   // calling _S_apply() on the next specialization of __gen_vtable_impl.
     914             :   // The base case of the recursion defines the actual function pointers.
     915             :   template<typename _Result_type, typename _Visitor, size_t... __dimensions,
     916             :            typename... _Variants, size_t... __indices>
     917             :     struct __gen_vtable_impl<
     918             :         _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
     919             :         std::index_sequence<__indices...>>
     920             :     {
     921             :       using _Next =
     922             :           remove_reference_t<typename _Nth_type<sizeof...(__indices),
     923             :                              _Variants...>::type>;
     924             :       using _Array_type =
     925             :           _Multi_array<_Result_type (*)(_Visitor, _Variants...),
     926             :                        __dimensions...>;
     927             : 
     928             :       static constexpr _Array_type
     929             :       _S_apply()
     930             :       {
     931             :         _Array_type __vtable{};
     932             :         _S_apply_all_alts(
     933             :           __vtable, make_index_sequence<variant_size_v<_Next>>());
     934             :         return __vtable;
     935             :       }
     936             : 
     937             :       template<size_t... __var_indices>
     938             :         static constexpr void
     939             :         _S_apply_all_alts(_Array_type& __vtable,
     940             :                           std::index_sequence<__var_indices...>)
     941             :         {
     942             :           if constexpr (_Extra_visit_slot_needed<_Result_type, _Next>::value)
     943             :             (_S_apply_single_alt<true, __var_indices>(
     944             :               __vtable._M_arr[__var_indices + 1],
     945             :               &(__vtable._M_arr[0])), ...);
     946             :           else
     947             :             (_S_apply_single_alt<false, __var_indices>(
     948             :               __vtable._M_arr[__var_indices]), ...);
     949             :         }
     950             : 
     951             :       template<bool __do_cookie, size_t __index, typename _Tp>
     952             :         static constexpr void
     953             :         _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element = nullptr)
     954             :         {
     955             :           if constexpr (__do_cookie)
     956             :             {
     957             :               __element = __gen_vtable_impl<
     958             :                 _Tp,
     959             :                 std::index_sequence<__indices..., __index>>::_S_apply();
     960             :               *__cookie_element = __gen_vtable_impl<
     961             :                 _Tp,
     962             :                 std::index_sequence<__indices..., variant_npos>>::_S_apply();
     963             :             }
     964             :           else
     965             :             {
     966             :               auto __tmp_element = __gen_vtable_impl<
     967             :                 remove_reference_t<decltype(__element)>,
     968             :                 std::index_sequence<__indices..., __index>>::_S_apply();
     969             :               static_assert(is_same_v<_Tp, decltype(__tmp_element)>,
     970             :                             "std::visit requires the visitor to have the same "
     971             :                             "return type for all alternatives of a variant");
     972             :               __element = __tmp_element;
     973             :             }
     974             :         }
     975             :     };
     976             : 
     977             :   // This partial specialization is the base case for the recursion.
     978             :   // It populates a _Multi_array element with the address of a function
     979             :   // that invokes the visitor with the alternatives specified by __indices.
     980             :   template<typename _Result_type, typename _Visitor, typename... _Variants,
     981             :            size_t... __indices>
     982             :     struct __gen_vtable_impl<
     983             :       _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
     984             :                    std::index_sequence<__indices...>>
     985             :     {
     986             :       using _Array_type =
     987             :           _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
     988             : 
     989             :       template<size_t __index, typename _Variant>
     990             :         static constexpr decltype(auto)
     991           1 :         __element_by_index_or_cookie(_Variant&& __var) noexcept
     992             :         {
     993             :           if constexpr (__index != variant_npos)
     994           1 :             return __variant::__get<__index>(std::forward<_Variant>(__var));
     995             :           else
     996           0 :             return __variant_cookie{};
     997             :         }
     998             : 
     999             :       static constexpr decltype(auto)
    1000           4 :       __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
    1001             :       {
    1002             :         if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
    1003             :           // For raw visitation using indices, pass the indices to the visitor
    1004             :           // and discard the return value:
    1005             :           std::__invoke(std::forward<_Visitor>(__visitor),
    1006             :               __element_by_index_or_cookie<__indices>(
    1007             :                 std::forward<_Variants>(__vars))...,
    1008             :               integral_constant<size_t, __indices>()...);
    1009             :         else if constexpr (is_same_v<_Result_type, __variant_cookie>)
    1010             :           // For raw visitation without indices, and discard the return value:
    1011           1 :           std::__invoke(std::forward<_Visitor>(__visitor),
    1012           0 :               __element_by_index_or_cookie<__indices>(
    1013             :                 std::forward<_Variants>(__vars))...);
    1014             :         else if constexpr (_Array_type::__result_is_deduced::value)
    1015             :           // For the usual std::visit case deduce the return value:
    1016             :           return std::__invoke(std::forward<_Visitor>(__visitor),
    1017             :               __element_by_index_or_cookie<__indices>(
    1018             :                 std::forward<_Variants>(__vars))...);
    1019             :         else // for std::visit<R> use INVOKE<R>
    1020           3 :           return std::__invoke_r<_Result_type>(
    1021             :               std::forward<_Visitor>(__visitor),
    1022           3 :               __variant::__get<__indices>(std::forward<_Variants>(__vars))...);
    1023           1 :       }
    1024             : 
    1025             :       static constexpr auto
    1026             :       _S_apply()
    1027             :       {
    1028             :         if constexpr (_Array_type::__result_is_deduced::value)
    1029             :           {
    1030             :             constexpr bool __visit_ret_type_mismatch =
    1031             :               !is_same_v<typename _Result_type::type,
    1032             :                          decltype(__visit_invoke(std::declval<_Visitor>(),
    1033             :                                     std::declval<_Variants>()...))>;
    1034             :             if constexpr (__visit_ret_type_mismatch)
    1035             :               {
    1036             :                 struct __cannot_match {};
    1037             :                 return __cannot_match{};
    1038             :               }
    1039             :             else
    1040             :               return _Array_type{&__visit_invoke};
    1041             :           }
    1042             :         else
    1043             :           return _Array_type{&__visit_invoke};
    1044             :       }
    1045             :     };
    1046             : 
    1047             :   template<typename _Result_type, typename _Visitor, typename... _Variants>
    1048             :     struct __gen_vtable
    1049             :     {
    1050             :       using _Array_type =
    1051             :           _Multi_array<_Result_type (*)(_Visitor, _Variants...),
    1052             :                        variant_size_v<remove_reference_t<_Variants>>...>;
    1053             : 
    1054             :       static constexpr _Array_type _S_vtable
    1055             :         = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
    1056             :     };
    1057             : 
    1058             :   template<size_t _Np, typename _Tp>
    1059             :     struct _Base_dedup : public _Tp { };
    1060             : 
    1061             :   template<typename _Variant, typename __indices>
    1062             :     struct _Variant_hash_base;
    1063             : 
    1064             :   template<typename... _Types, size_t... __indices>
    1065             :     struct _Variant_hash_base<variant<_Types...>,
    1066             :                               std::index_sequence<__indices...>>
    1067             :     : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
    1068             : 
    1069             :   // Equivalent to decltype(get<_Np>(as-variant(declval<_Variant>())))
    1070             :   template<size_t _Np, typename _Variant,
    1071             :       typename _AsV = decltype(__variant::__as(std::declval<_Variant>())),
    1072             :       typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>>
    1073             :     using __get_t
    1074             :       = conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
    1075             : 
    1076             :   // Return type of std::visit.
    1077             :   template<typename _Visitor, typename... _Variants>
    1078             :     using __visit_result_t
    1079             :       = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
    1080             : 
    1081             :   template<typename _Tp, typename... _Types>
    1082             :     constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
    1083             : 
    1084             :   template <typename _Visitor, typename _Variant, size_t... _Idxs>
    1085             :     constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>)
    1086             :     {
    1087             :       return __same_types<
    1088             :         invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
    1089             :         >;
    1090             :     }
    1091             : 
    1092             :   template<size_t _Np, typename _Variant, typename... _Args>
    1093             :     inline void
    1094          14 :     __construct_by_index(_Variant& __v, _Args&&... __args)
    1095             :     {
    1096          14 :       auto&& __storage = __detail::__variant::__get<_Np>(__v);
    1097          14 :       ::new ((void*)std::addressof(__storage))
    1098             :         remove_reference_t<decltype(__storage)>
    1099          14 :           (std::forward<_Args>(__args)...);
    1100             :       // Construction didn't throw, so can set the new index now:
    1101          14 :       __v._M_index = _Np;
    1102          14 :     }
    1103             : 
    1104             : } // namespace __variant
    1105             : } // namespace __detail
    1106             : 
    1107             :   template<typename _Tp, typename... _Types>
    1108             :     constexpr bool
    1109          52 :     holds_alternative(const variant<_Types...>& __v) noexcept
    1110             :     {
    1111             :       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
    1112             :                     "T must occur exactly once in alternatives");
    1113          52 :       return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>;
    1114             :     }
    1115             : 
    1116             :   template<typename _Tp, typename... _Types>
    1117          13 :     constexpr _Tp& get(variant<_Types...>& __v)
    1118             :     {
    1119             :       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
    1120             :                     "T must occur exactly once in alternatives");
    1121             :       static_assert(!is_void_v<_Tp>, "_Tp must not be void");
    1122          13 :       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
    1123             :     }
    1124             : 
    1125             :   template<typename _Tp, typename... _Types>
    1126             :     constexpr _Tp&& get(variant<_Types...>&& __v)
    1127             :     {
    1128             :       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
    1129             :                     "T must occur exactly once in alternatives");
    1130             :       static_assert(!is_void_v<_Tp>, "_Tp must not be void");
    1131             :       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
    1132             :         std::move(__v));
    1133             :     }
    1134             : 
    1135             :   template<typename _Tp, typename... _Types>
    1136             :     constexpr const _Tp& get(const variant<_Types...>& __v)
    1137             :     {
    1138             :       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
    1139             :                     "T must occur exactly once in alternatives");
    1140             :       static_assert(!is_void_v<_Tp>, "_Tp must not be void");
    1141             :       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v);
    1142             :     }
    1143             : 
    1144             :   template<typename _Tp, typename... _Types>
    1145             :     constexpr const _Tp&& get(const variant<_Types...>&& __v)
    1146             :     {
    1147             :       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
    1148             :                     "T must occur exactly once in alternatives");
    1149             :       static_assert(!is_void_v<_Tp>, "_Tp must not be void");
    1150             :       return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(
    1151             :         std::move(__v));
    1152             :     }
    1153             : 
    1154             :   template<size_t _Np, typename... _Types>
    1155             :     constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
    1156             :     get_if(variant<_Types...>* __ptr) noexcept
    1157             :     {
    1158             :       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
    1159             :       static_assert(_Np < sizeof...(_Types),
    1160             :                     "The index must be in [0, number of alternatives)");
    1161             :       static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void");
    1162             :       if (__ptr && __ptr->index() == _Np)
    1163             :         return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
    1164             :       return nullptr;
    1165             :     }
    1166             : 
    1167             :   template<size_t _Np, typename... _Types>
    1168             :     constexpr
    1169             :     add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
    1170           1 :     get_if(const variant<_Types...>* __ptr) noexcept
    1171             :     {
    1172             :       using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
    1173             :       static_assert(_Np < sizeof...(_Types),
    1174             :                     "The index must be in [0, number of alternatives)");
    1175             :       static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void");
    1176           1 :       if (__ptr && __ptr->index() == _Np)
    1177           1 :         return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
    1178           0 :       return nullptr;
    1179             :     }
    1180             : 
    1181             :   template<typename _Tp, typename... _Types>
    1182             :     constexpr add_pointer_t<_Tp>
    1183             :     get_if(variant<_Types...>* __ptr) noexcept
    1184             :     {
    1185             :       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
    1186             :                     "T must occur exactly once in alternatives");
    1187             :       static_assert(!is_void_v<_Tp>, "_Tp must not be void");
    1188             :       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
    1189             :           __ptr);
    1190             :     }
    1191             : 
    1192             :   template<typename _Tp, typename... _Types>
    1193             :     constexpr add_pointer_t<const _Tp>
    1194           1 :     get_if(const variant<_Types...>* __ptr) noexcept
    1195             :     {
    1196             :       static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
    1197             :                     "T must occur exactly once in alternatives");
    1198             :       static_assert(!is_void_v<_Tp>, "_Tp must not be void");
    1199           1 :       return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>(
    1200           1 :           __ptr);
    1201             :     }
    1202             : 
    1203             :   struct monostate { };
    1204             : 
    1205             : #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
    1206             :   template<typename... _Types> \
    1207             :     constexpr bool operator __OP(const variant<_Types...>& __lhs, \
    1208             :                                  const variant<_Types...>& __rhs) \
    1209             :     { \
    1210             :       bool __ret = true; \
    1211             :       __detail::__variant::__raw_idx_visit( \
    1212             :         [&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \
    1213             :         { \
    1214             :           if constexpr (__rhs_index != variant_npos) \
    1215             :             { \
    1216             :               if (__lhs.index() == __rhs_index) \
    1217             :                 { \
    1218             :                   auto& __this_mem = std::get<__rhs_index>(__lhs);    \
    1219             :                   __ret = __this_mem __OP __rhs_mem; \
    1220             :                 } \
    1221             :               else \
    1222             :                 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
    1223             :             } \
    1224             :           else \
    1225             :             __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
    1226             :         }, __rhs); \
    1227             :       return __ret; \
    1228             :     }
    1229             : 
    1230             :   _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
    1231             :   _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
    1232             :   _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
    1233             :   _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
    1234             :   _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
    1235             :   _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
    1236             : 
    1237             : #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
    1238             : 
    1239             :   constexpr bool operator==(monostate, monostate) noexcept { return true; }
    1240             : 
    1241             : #ifdef __cpp_lib_three_way_comparison
    1242             :   template<typename... _Types>
    1243             :     requires (three_way_comparable<_Types> && ...)
    1244             :     constexpr
    1245             :     common_comparison_category_t<compare_three_way_result_t<_Types>...>
    1246             :     operator<=>(const variant<_Types...>& __v, const variant<_Types...>& __w)
    1247             :     {
    1248             :       common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
    1249             :         = strong_ordering::equal;
    1250             : 
    1251             :       __detail::__variant::__raw_idx_visit(
    1252             :         [&__ret, &__v] (auto&& __w_mem, auto __w_index) mutable
    1253             :         {
    1254             :           if constexpr (__w_index != variant_npos)
    1255             :             {
    1256             :               if (__v.index() == __w_index)
    1257             :                 {
    1258             :                   auto& __this_mem = std::get<__w_index>(__v);
    1259             :                   __ret = __this_mem <=> __w_mem;
    1260             :                   return;
    1261             :                 }
    1262             :             }
    1263             :           __ret = (__v.index() + 1) <=> (__w_index + 1);
    1264             :         }, __w);
    1265             :       return __ret;
    1266             :     }
    1267             : 
    1268             :   constexpr strong_ordering
    1269             :   operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; }
    1270             : #else
    1271             :   constexpr bool operator!=(monostate, monostate) noexcept { return false; }
    1272             :   constexpr bool operator<(monostate, monostate) noexcept { return false; }
    1273             :   constexpr bool operator>(monostate, monostate) noexcept { return false; }
    1274             :   constexpr bool operator<=(monostate, monostate) noexcept { return true; }
    1275             :   constexpr bool operator>=(monostate, monostate) noexcept { return true; }
    1276             : #endif
    1277             : 
    1278             :   template<typename _Visitor, typename... _Variants>
    1279             :     constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
    1280             :     visit(_Visitor&&, _Variants&&...);
    1281             : 
    1282             :   template<typename... _Types>
    1283             :     inline enable_if_t<(is_move_constructible_v<_Types> && ...)
    1284             :                         && (is_swappable_v<_Types> && ...)>
    1285             :     swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
    1286             :     noexcept(noexcept(__lhs.swap(__rhs)))
    1287             :     { __lhs.swap(__rhs); }
    1288             : 
    1289             :   template<typename... _Types>
    1290             :     enable_if_t<!((is_move_constructible_v<_Types> && ...)
    1291             :                    && (is_swappable_v<_Types> && ...))>
    1292             :     swap(variant<_Types...>&, variant<_Types...>&) = delete;
    1293             : 
    1294             :   class bad_variant_access : public exception
    1295             :   {
    1296             :   public:
    1297             :     bad_variant_access() noexcept { }
    1298             : 
    1299           0 :     const char* what() const noexcept override
    1300           0 :     { return _M_reason; }
    1301             : 
    1302             :   private:
    1303           0 :     bad_variant_access(const char* __reason) noexcept : _M_reason(__reason) { }
    1304             : 
    1305             :     // Must point to a string with static storage duration:
    1306             :     const char* _M_reason = "bad variant access";
    1307             : 
    1308             :     friend void __throw_bad_variant_access(const char* __what);
    1309             :   };
    1310             : 
    1311             :   // Must only be called with a string literal
    1312             :   inline void
    1313           0 :   __throw_bad_variant_access(const char* __what)
    1314           0 :   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
    1315             : 
    1316             :   inline void
    1317           0 :   __throw_bad_variant_access(bool __valueless)
    1318             :   {
    1319           0 :     if (__valueless) [[__unlikely__]]
    1320           0 :       __throw_bad_variant_access("std::get: variant is valueless");
    1321             :     else
    1322           0 :       __throw_bad_variant_access("std::get: wrong index for variant");
    1323           0 :   }
    1324             : 
    1325             :   template<typename... _Types>
    1326             :     class variant
    1327             :     : private __detail::__variant::_Variant_base<_Types...>,
    1328             :       private _Enable_default_constructor<
    1329             :         __detail::__variant::_Traits<_Types...>::_S_default_ctor,
    1330             :           variant<_Types...>>,
    1331             :       private _Enable_copy_move<
    1332             :         __detail::__variant::_Traits<_Types...>::_S_copy_ctor,
    1333             :         __detail::__variant::_Traits<_Types...>::_S_copy_assign,
    1334             :         __detail::__variant::_Traits<_Types...>::_S_move_ctor,
    1335             :         __detail::__variant::_Traits<_Types...>::_S_move_assign,
    1336             :         variant<_Types...>>
    1337             :     {
    1338             :     private:
    1339             :       template <typename... _UTypes, typename _Tp>
    1340             :         friend decltype(auto) __variant_cast(_Tp&&);
    1341             :       template<size_t _Np, typename _Variant, typename... _Args>
    1342             :         friend void
    1343             :         __detail::__variant::__construct_by_index(_Variant& __v,
    1344             :                                                   _Args&&... __args);
    1345             : 
    1346             :       static_assert(sizeof...(_Types) > 0,
    1347             :                     "variant must have at least one alternative");
    1348             :       static_assert(!(std::is_reference_v<_Types> || ...),
    1349             :                     "variant must have no reference alternative");
    1350             :       static_assert(!(std::is_void_v<_Types> || ...),
    1351             :                     "variant must have no void alternative");
    1352             : 
    1353             :       using _Base = __detail::__variant::_Variant_base<_Types...>;
    1354             :       using _Default_ctor_enabler =
    1355             :         _Enable_default_constructor<
    1356             :           __detail::__variant::_Traits<_Types...>::_S_default_ctor,
    1357             :             variant<_Types...>>;
    1358             : 
    1359             :       template<typename _Tp>
    1360             :         static constexpr bool __not_self
    1361             :           = !is_same_v<__remove_cvref_t<_Tp>, variant>;
    1362             : 
    1363             :       template<typename _Tp>
    1364             :         static constexpr bool
    1365             :         __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
    1366             : 
    1367             :       template<typename _Tp>
    1368             :         static constexpr size_t __accepted_index
    1369             :           = __detail::__variant::__accepted_index<_Tp, variant>::value;
    1370             : 
    1371             :       template<size_t _Np, typename = enable_if_t<(_Np < sizeof...(_Types))>>
    1372             :         using __to_type = variant_alternative_t<_Np, variant>;
    1373             : 
    1374             :       template<typename _Tp, typename = enable_if_t<__not_self<_Tp>>>
    1375             :         using __accepted_type = __to_type<__accepted_index<_Tp>>;
    1376             : 
    1377             :       template<typename _Tp>
    1378             :         static constexpr size_t __index_of =
    1379             :           __detail::__variant::__index_of_v<_Tp, _Types...>;
    1380             : 
    1381             :       using _Traits = __detail::__variant::_Traits<_Types...>;
    1382             : 
    1383             :       template<typename _Tp>
    1384             :         struct __is_in_place_tag : false_type { };
    1385             :       template<typename _Tp>
    1386             :         struct __is_in_place_tag<in_place_type_t<_Tp>> : true_type { };
    1387             :       template<size_t _Np>
    1388             :         struct __is_in_place_tag<in_place_index_t<_Np>> : true_type { };
    1389             : 
    1390             :       template<typename _Tp>
    1391             :         static constexpr bool __not_in_place_tag
    1392             :           = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value;
    1393             : 
    1394             :     public:
    1395           1 :       variant() = default;
    1396           1 :       variant(const variant& __rhs) = default;
    1397             :       variant(variant&&) = default;
    1398             :       variant& operator=(const variant&) = default;
    1399             :       variant& operator=(variant&&) = default;
    1400           2 :       ~variant() = default;
    1401             : 
    1402             :       template<typename _Tp,
    1403             :                typename = enable_if_t<sizeof...(_Types) != 0>,
    1404             :                typename = enable_if_t<__not_in_place_tag<_Tp>>,
    1405             :                typename _Tj = __accepted_type<_Tp&&>,
    1406             :                typename = enable_if_t<__exactly_once<_Tj>
    1407             :                                       && is_constructible_v<_Tj, _Tp>>>
    1408             :         constexpr
    1409             :         variant(_Tp&& __t)
    1410             :         noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
    1411             :         : variant(in_place_index<__accepted_index<_Tp>>,
    1412             :                   std::forward<_Tp>(__t))
    1413             :         { }
    1414             : 
    1415             :       template<typename _Tp, typename... _Args,
    1416             :                typename = enable_if_t<__exactly_once<_Tp>
    1417             :                                       && is_constructible_v<_Tp, _Args...>>>
    1418             :         constexpr explicit
    1419             :         variant(in_place_type_t<_Tp>, _Args&&... __args)
    1420             :         : variant(in_place_index<__index_of<_Tp>>,
    1421             :                   std::forward<_Args>(__args)...)
    1422             :         { }
    1423             : 
    1424             :       template<typename _Tp, typename _Up, typename... _Args,
    1425             :                typename = enable_if_t<__exactly_once<_Tp>
    1426             :                                       && is_constructible_v<_Tp,
    1427             :                                            initializer_list<_Up>&, _Args...>>>
    1428             :         constexpr explicit
    1429             :         variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
    1430             :                 _Args&&... __args)
    1431             :         : variant(in_place_index<__index_of<_Tp>>, __il,
    1432             :                   std::forward<_Args>(__args)...)
    1433             :         { }
    1434             : 
    1435             :       template<size_t _Np, typename... _Args,
    1436             :                typename _Tp = __to_type<_Np>,
    1437             :                typename = enable_if_t<is_constructible_v<_Tp, _Args...>>>
    1438             :         constexpr explicit
    1439             :         variant(in_place_index_t<_Np>, _Args&&... __args)
    1440             :         : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
    1441             :         _Default_ctor_enabler(_Enable_default_constructor_tag{})
    1442             :         { }
    1443             : 
    1444             :       template<size_t _Np, typename _Up, typename... _Args,
    1445             :                typename _Tp = __to_type<_Np>,
    1446             :                typename = enable_if_t<is_constructible_v<_Tp,
    1447             :                                                          initializer_list<_Up>&,
    1448             :                                                          _Args...>>>
    1449             :         constexpr explicit
    1450             :         variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
    1451             :                 _Args&&... __args)
    1452             :         : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
    1453             :         _Default_ctor_enabler(_Enable_default_constructor_tag{})
    1454             :         { }
    1455             : 
    1456             :       template<typename _Tp>
    1457             :         enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
    1458             :                     && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
    1459             :                     && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
    1460             :                     variant&>
    1461          14 :         operator=(_Tp&& __rhs)
    1462             :         noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
    1463             :                  && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
    1464             :         {
    1465          14 :           constexpr auto __index = __accepted_index<_Tp>;
    1466          14 :           if (index() == __index)
    1467           0 :             std::get<__index>(*this) = std::forward<_Tp>(__rhs);
    1468             :           else
    1469             :             {
    1470             :               using _Tj = __accepted_type<_Tp&&>;
    1471             :               if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
    1472             :                             || !is_nothrow_move_constructible_v<_Tj>)
    1473          14 :                 this->emplace<__index>(std::forward<_Tp>(__rhs));
    1474             :               else
    1475             :                 // _GLIBCXX_RESOLVE_LIB_DEFECTS
    1476             :                 // 3585. converting assignment with immovable alternative
    1477             :                 this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs)));
    1478             :             }
    1479          14 :           return *this;
    1480             :         }
    1481             : 
    1482             :       template<typename _Tp, typename... _Args>
    1483             :         enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
    1484             :                     _Tp&>
    1485             :         emplace(_Args&&... __args)
    1486             :         {
    1487             :           constexpr size_t __index = __index_of<_Tp>;
    1488             :           return this->emplace<__index>(std::forward<_Args>(__args)...);
    1489             :         }
    1490             : 
    1491             :       template<typename _Tp, typename _Up, typename... _Args>
    1492             :         enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
    1493             :                     && __exactly_once<_Tp>,
    1494             :                     _Tp&>
    1495             :         emplace(initializer_list<_Up> __il, _Args&&... __args)
    1496             :         {
    1497             :           constexpr size_t __index = __index_of<_Tp>;
    1498             :           return this->emplace<__index>(__il, std::forward<_Args>(__args)...);
    1499             :         }
    1500             : 
    1501             :       template<size_t _Np, typename... _Args>
    1502             :         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
    1503             :                                        _Args...>,
    1504             :                     variant_alternative_t<_Np, variant>&>
    1505          14 :         emplace(_Args&&... __args)
    1506             :         {
    1507             :           static_assert(_Np < sizeof...(_Types),
    1508             :                         "The index must be in [0, number of alternatives)");
    1509             :           using type = variant_alternative_t<_Np, variant>;
    1510             :           namespace __variant = std::__detail::__variant;
    1511             :           // Provide the strong exception-safety guarantee when possible,
    1512             :           // to avoid becoming valueless.
    1513             :           if constexpr (is_nothrow_constructible_v<type, _Args...>)
    1514             :             {
    1515          14 :               this->_M_reset();
    1516          14 :               __variant::__construct_by_index<_Np>(*this,
    1517             :                   std::forward<_Args>(__args)...);
    1518             :             }
    1519             :           else if constexpr (is_scalar_v<type>)
    1520             :             {
    1521             :               // This might invoke a potentially-throwing conversion operator:
    1522             :               const type __tmp(std::forward<_Args>(__args)...);
    1523             :               // But these steps won't throw:
    1524             :               this->_M_reset();
    1525             :               __variant::__construct_by_index<_Np>(*this, __tmp);
    1526             :             }
    1527             :           else if constexpr (__variant::_Never_valueless_alt<type>()
    1528             :               && _Traits::_S_move_assign)
    1529             :             {
    1530             :               // This construction might throw:
    1531             :               variant __tmp(in_place_index<_Np>,
    1532             :                             std::forward<_Args>(__args)...);
    1533             :               // But _Never_valueless_alt<type> means this won't:
    1534             :               *this = std::move(__tmp);
    1535             :             }
    1536             :           else
    1537             :             {
    1538             :               // This case only provides the basic exception-safety guarantee,
    1539             :               // i.e. the variant can become valueless.
    1540             :               this->_M_reset();
    1541             :               __variant::__construct_by_index<_Np>(*this,
    1542             :                 std::forward<_Args>(__args)...);
    1543             :             }
    1544          14 :           return std::get<_Np>(*this);
    1545             :         }
    1546             : 
    1547             :       template<size_t _Np, typename _Up, typename... _Args>
    1548             :         enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>,
    1549             :                                        initializer_list<_Up>&, _Args...>,
    1550             :                     variant_alternative_t<_Np, variant>&>
    1551             :         emplace(initializer_list<_Up> __il, _Args&&... __args)
    1552             :         {
    1553             :           static_assert(_Np < sizeof...(_Types),
    1554             :                         "The index must be in [0, number of alternatives)");
    1555             :           using type = variant_alternative_t<_Np, variant>;
    1556             :           namespace __variant = std::__detail::__variant;
    1557             :           // Provide the strong exception-safety guarantee when possible,
    1558             :           // to avoid becoming valueless.
    1559             :           if constexpr (is_nothrow_constructible_v<type,
    1560             :                                                    initializer_list<_Up>&,
    1561             :                                                    _Args...>)
    1562             :             {
    1563             :               this->_M_reset();
    1564             :               __variant::__construct_by_index<_Np>(*this, __il,
    1565             :                   std::forward<_Args>(__args)...);
    1566             :             }
    1567             :           else if constexpr (__variant::_Never_valueless_alt<type>()
    1568             :               && _Traits::_S_move_assign)
    1569             :             {
    1570             :               // This construction might throw:
    1571             :               variant __tmp(in_place_index<_Np>, __il,
    1572             :                             std::forward<_Args>(__args)...);
    1573             :               // But _Never_valueless_alt<type> means this won't:
    1574             :               *this = std::move(__tmp);
    1575             :             }
    1576             :           else
    1577             :             {
    1578             :               // This case only provides the basic exception-safety guarantee,
    1579             :               // i.e. the variant can become valueless.
    1580             :               this->_M_reset();
    1581             :               __variant::__construct_by_index<_Np>(*this, __il,
    1582             :                 std::forward<_Args>(__args)...);
    1583             :             }
    1584             :           return std::get<_Np>(*this);
    1585             :         }
    1586             : 
    1587           0 :       constexpr bool valueless_by_exception() const noexcept
    1588           0 :       { return !this->_M_valid(); }
    1589             : 
    1590          98 :       constexpr size_t index() const noexcept
    1591             :       {
    1592             :         using __index_type = typename _Base::__index_type;
    1593             :         if constexpr (__detail::__variant::__never_valueless<_Types...>())
    1594          91 :           return this->_M_index;
    1595             :         else if constexpr (sizeof...(_Types) <= __index_type(-1) / 2)
    1596           7 :           return make_signed_t<__index_type>(this->_M_index);
    1597             :         else
    1598             :           return size_t(__index_type(this->_M_index + 1)) - 1;
    1599             :       }
    1600             : 
    1601             :       void
    1602             :       swap(variant& __rhs)
    1603             :       noexcept((__is_nothrow_swappable<_Types>::value && ...)
    1604             :                && is_nothrow_move_constructible_v<variant>)
    1605             :       {
    1606             :         __detail::__variant::__raw_idx_visit(
    1607             :           [this, &__rhs](auto&& __rhs_mem, auto __rhs_index) mutable
    1608             :           {
    1609             :             if constexpr (__rhs_index != variant_npos)
    1610             :               {
    1611             :                 if (this->index() == __rhs_index)
    1612             :                   {
    1613             :                     auto& __this_mem =
    1614             :                       std::get<__rhs_index>(*this);
    1615             :                     using std::swap;
    1616             :                     swap(__this_mem, __rhs_mem);
    1617             :                   }
    1618             :                 else
    1619             :                   {
    1620             :                     if (!this->valueless_by_exception()) [[__likely__]]
    1621             :                       {
    1622             :                         auto __tmp(std::move(__rhs_mem));
    1623             :                         __rhs = std::move(*this);
    1624             :                         this->_M_destructive_move(__rhs_index,
    1625             :                                                   std::move(__tmp));
    1626             :                       }
    1627             :                     else
    1628             :                       {
    1629             :                         this->_M_destructive_move(__rhs_index,
    1630             :                                                   std::move(__rhs_mem));
    1631             :                         __rhs._M_reset();
    1632             :                       }
    1633             :                   }
    1634             :               }
    1635             :             else
    1636             :               {
    1637             :                 if (!this->valueless_by_exception()) [[__likely__]]
    1638             :                   {
    1639             :                     __rhs = std::move(*this);
    1640             :                     this->_M_reset();
    1641             :                   }
    1642             :               }
    1643             :           }, __rhs);
    1644             :       }
    1645             : 
    1646             :     private:
    1647             : 
    1648             : #if defined(__clang__) && __clang_major__ <= 7
    1649             :     public:
    1650             :       using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852
    1651             :     private:
    1652             : #endif
    1653             : 
    1654             :       template<size_t _Np, typename _Vp>
    1655             :         friend constexpr decltype(auto)
    1656             :         __detail::__variant::__get(_Vp&& __v) noexcept;
    1657             : 
    1658             : #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
    1659             :       template<typename... _Tp> \
    1660             :         friend constexpr bool \
    1661             :         operator __OP(const variant<_Tp...>& __lhs, \
    1662             :                       const variant<_Tp...>& __rhs);
    1663             : 
    1664             :       _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
    1665             :       _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
    1666             :       _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
    1667             :       _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
    1668             :       _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
    1669             :       _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
    1670             : 
    1671             : #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
    1672             :     };
    1673             : 
    1674             :   template<size_t _Np, typename... _Types>
    1675             :     constexpr variant_alternative_t<_Np, variant<_Types...>>&
    1676          27 :     get(variant<_Types...>& __v)
    1677             :     {
    1678             :       static_assert(_Np < sizeof...(_Types),
    1679             :                     "The index must be in [0, number of alternatives)");
    1680          27 :       if (__v.index() != _Np)
    1681           0 :         __throw_bad_variant_access(__v.valueless_by_exception());
    1682          27 :       return __detail::__variant::__get<_Np>(__v);
    1683             :     }
    1684             : 
    1685             :   template<size_t _Np, typename... _Types>
    1686             :     constexpr variant_alternative_t<_Np, variant<_Types...>>&&
    1687             :     get(variant<_Types...>&& __v)
    1688             :     {
    1689             :       static_assert(_Np < sizeof...(_Types),
    1690             :                     "The index must be in [0, number of alternatives)");
    1691             :       if (__v.index() != _Np)
    1692             :         __throw_bad_variant_access(__v.valueless_by_exception());
    1693             :       return __detail::__variant::__get<_Np>(std::move(__v));
    1694             :     }
    1695             : 
    1696             :   template<size_t _Np, typename... _Types>
    1697             :     constexpr const variant_alternative_t<_Np, variant<_Types...>>&
    1698             :     get(const variant<_Types...>& __v)
    1699             :     {
    1700             :       static_assert(_Np < sizeof...(_Types),
    1701             :                     "The index must be in [0, number of alternatives)");
    1702             :       if (__v.index() != _Np)
    1703             :         __throw_bad_variant_access(__v.valueless_by_exception());
    1704             :       return __detail::__variant::__get<_Np>(__v);
    1705             :     }
    1706             : 
    1707             :   template<size_t _Np, typename... _Types>
    1708             :     constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
    1709             :     get(const variant<_Types...>&& __v)
    1710             :     {
    1711             :       static_assert(_Np < sizeof...(_Types),
    1712             :                     "The index must be in [0, number of alternatives)");
    1713             :       if (__v.index() != _Np)
    1714             :         __throw_bad_variant_access(__v.valueless_by_exception());
    1715             :       return __detail::__variant::__get<_Np>(std::move(__v));
    1716             :     }
    1717             : 
    1718             :   /// @cond undocumented
    1719             :   template<typename _Result_type, typename _Visitor, typename... _Variants>
    1720             :     constexpr decltype(auto)
    1721           4 :     __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
    1722             :     {
    1723           4 :       constexpr auto& __vtable = __detail::__variant::__gen_vtable<
    1724             :         _Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
    1725             : 
    1726           4 :       auto __func_ptr = __vtable._M_access(__variants.index()...);
    1727           4 :       return (*__func_ptr)(std::forward<_Visitor>(__visitor),
    1728           4 :                            std::forward<_Variants>(__variants)...);
    1729             :     }
    1730             :   /// @endcond
    1731             : 
    1732             :   template<typename _Visitor, typename... _Variants>
    1733             :     constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
    1734             :     visit(_Visitor&& __visitor, _Variants&&... __variants)
    1735             :     {
    1736             :       namespace __variant = std::__detail::__variant;
    1737             : 
    1738             :       if ((__variant::__as(__variants).valueless_by_exception() || ...))
    1739             :         __throw_bad_variant_access("std::visit: variant is valueless");
    1740             : 
    1741             :       using _Result_type
    1742             :         = __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
    1743             : 
    1744             :       using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
    1745             : 
    1746             :       if constexpr (sizeof...(_Variants) == 1)
    1747             :         {
    1748             :           using _Vp = decltype(__variant::__as(std::declval<_Variants>()...));
    1749             : 
    1750             :           constexpr bool __visit_rettypes_match = __detail::__variant::
    1751             :             __check_visitor_results<_Visitor, _Vp>(
    1752             :               make_index_sequence<variant_size_v<remove_reference_t<_Vp>>>());
    1753             :           if constexpr (!__visit_rettypes_match)
    1754             :             {
    1755             :               static_assert(__visit_rettypes_match,
    1756             :                           "std::visit requires the visitor to have the same "
    1757             :                           "return type for all alternatives of a variant");
    1758             :               return;
    1759             :             }
    1760             :           else
    1761             :             return std::__do_visit<_Tag>(
    1762             :               std::forward<_Visitor>(__visitor),
    1763             :               static_cast<_Vp>(__variants)...);
    1764             :         }
    1765             :       else
    1766             :         return std::__do_visit<_Tag>(
    1767             :           std::forward<_Visitor>(__visitor),
    1768             :           __variant::__as(std::forward<_Variants>(__variants))...);
    1769             :     }
    1770             : 
    1771             : #if __cplusplus > 201703L
    1772             :   template<typename _Res, typename _Visitor, typename... _Variants>
    1773             :     constexpr _Res
    1774             :     visit(_Visitor&& __visitor, _Variants&&... __variants)
    1775             :     {
    1776             :       namespace __variant = std::__detail::__variant;
    1777             : 
    1778             :       if ((__variant::__as(__variants).valueless_by_exception() || ...))
    1779             :         __throw_bad_variant_access("std::visit<R>: variant is valueless");
    1780             : 
    1781             :       return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor),
    1782             :           __variant::__as(std::forward<_Variants>(__variants))...);
    1783             :     }
    1784             : #endif
    1785             : 
    1786             :   /// @cond undocumented
    1787             :   template<bool, typename... _Types>
    1788             :     struct __variant_hash_call_base_impl
    1789             :     {
    1790             :       size_t
    1791             :       operator()(const variant<_Types...>& __t) const
    1792             :       noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
    1793             :       {
    1794             :         size_t __ret;
    1795             :         __detail::__variant::__raw_visit(
    1796             :           [&__t, &__ret](auto&& __t_mem) mutable
    1797             :           {
    1798             :             using _Type = __remove_cvref_t<decltype(__t_mem)>;
    1799             :             if constexpr (!is_same_v<_Type,
    1800             :                                      __detail::__variant::__variant_cookie>)
    1801             :               __ret = std::hash<size_t>{}(__t.index())
    1802             :                       + std::hash<_Type>{}(__t_mem);
    1803             :             else
    1804             :               __ret = std::hash<size_t>{}(__t.index());
    1805             :           }, __t);
    1806             :         return __ret;
    1807             :       }
    1808             :     };
    1809             : 
    1810             :   template<typename... _Types>
    1811             :     struct __variant_hash_call_base_impl<false, _Types...> {};
    1812             : 
    1813             :   template<typename... _Types>
    1814             :     using __variant_hash_call_base =
    1815             :     __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
    1816             :                                    __enable_hash_call &&...), _Types...>;
    1817             :   /// @endcond
    1818             : 
    1819             :   template<typename... _Types>
    1820             :     struct hash<variant<_Types...>>
    1821             :     : private __detail::__variant::_Variant_hash_base<
    1822             :         variant<_Types...>, std::index_sequence_for<_Types...>>,
    1823             :       public __variant_hash_call_base<_Types...>
    1824             :     {
    1825             :       using result_type [[__deprecated__]] = size_t;
    1826             :       using argument_type [[__deprecated__]] = variant<_Types...>;
    1827             :     };
    1828             : 
    1829             :   template<>
    1830             :     struct hash<monostate>
    1831             :     {
    1832             :       using result_type [[__deprecated__]] = size_t;
    1833             :       using argument_type [[__deprecated__]] = monostate;
    1834             : 
    1835             :       size_t
    1836             :       operator()(const monostate&) const noexcept
    1837             :       {
    1838             :         constexpr size_t __magic_monostate_hash = -7777;
    1839             :         return __magic_monostate_hash;
    1840             :       }
    1841             :     };
    1842             : 
    1843             :   template<typename... _Types>
    1844             :     struct __is_fast_hash<hash<variant<_Types...>>>
    1845             :     : bool_constant<(__is_fast_hash<_Types>::value && ...)>
    1846             :     { };
    1847             : 
    1848             : _GLIBCXX_END_NAMESPACE_VERSION
    1849             : } // namespace std
    1850             : 
    1851             : #endif // C++17
    1852             : 
    1853             : #endif // _GLIBCXX_VARIANT

Generated by: LCOV version 1.14