xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/variant (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1b17d1066Smrg// <variant> -*- C++ -*-
2b17d1066Smrg
3b1e83836Smrg// Copyright (C) 2016-2022 Free Software Foundation, Inc.
4b17d1066Smrg//
5b17d1066Smrg// This file is part of the GNU ISO C++ Library.  This library is free
6b17d1066Smrg// software; you can redistribute it and/or modify it under the
7b17d1066Smrg// terms of the GNU General Public License as published by the
8b17d1066Smrg// Free Software Foundation; either version 3, or (at your option)
9b17d1066Smrg// any later version.
10b17d1066Smrg
11b17d1066Smrg// This library is distributed in the hope that it will be useful,
12b17d1066Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
13b17d1066Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14b17d1066Smrg// GNU General Public License for more details.
15b17d1066Smrg
16b17d1066Smrg// Under Section 7 of GPL version 3, you are granted additional
17b17d1066Smrg// permissions described in the GCC Runtime Library Exception, version
18b17d1066Smrg// 3.1, as published by the Free Software Foundation.
19b17d1066Smrg
20b17d1066Smrg// You should have received a copy of the GNU General Public License and
21b17d1066Smrg// a copy of the GCC Runtime Library Exception along with this program;
22b17d1066Smrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23b17d1066Smrg// <http://www.gnu.org/licenses/>.
24b17d1066Smrg
25b17d1066Smrg/** @file variant
26a448f87cSmrg *  This is the `<variant>` C++ Library header.
27b17d1066Smrg */
28b17d1066Smrg
29b17d1066Smrg#ifndef _GLIBCXX_VARIANT
30b17d1066Smrg#define _GLIBCXX_VARIANT 1
31b17d1066Smrg
32b17d1066Smrg#pragma GCC system_header
33b17d1066Smrg
34b17d1066Smrg#if __cplusplus >= 201703L
35b17d1066Smrg
36b1e83836Smrg#include <initializer_list>
37b17d1066Smrg#include <type_traits>
38b17d1066Smrg#include <bits/enable_special_members.h>
39b1e83836Smrg#include <bits/exception_defines.h>
40b17d1066Smrg#include <bits/functional_hash.h>
41b17d1066Smrg#include <bits/invoke.h>
42b17d1066Smrg#include <bits/parse_numbers.h>
43b17d1066Smrg#include <bits/stl_iterator_base_types.h>
44b17d1066Smrg#include <bits/stl_iterator_base_funcs.h>
45b17d1066Smrg#include <bits/stl_construct.h>
46b1e83836Smrg#include <bits/utility.h> // in_place_index_t
47b1e83836Smrg#if __cplusplus >= 202002L
48fb8a8121Smrg# include <compare>
49fb8a8121Smrg#endif
50b17d1066Smrg
51b1e83836Smrg#if __cpp_concepts >= 202002L && __cpp_constexpr >= 201811L
52b1e83836Smrg// P2231R1 constexpr needs constexpr unions and constrained destructors.
53b1e83836Smrg# define __cpp_lib_variant 202106L
54b1e83836Smrg#else
55b1e83836Smrg# include <ext/aligned_buffer.h> // Use __aligned_membuf instead of union.
56b1e83836Smrg# define __cpp_lib_variant 202102L
57b1e83836Smrg#endif
58b1e83836Smrg
59b17d1066Smrgnamespace std _GLIBCXX_VISIBILITY(default)
60b17d1066Smrg{
61a3e9eb18Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
62a3e9eb18Smrg
63b17d1066Smrg  template<typename... _Types> class tuple;
64b17d1066Smrg  template<typename... _Types> class variant;
65b17d1066Smrg  template <typename> struct hash;
66b17d1066Smrg
67b17d1066Smrg  template<typename _Variant>
68b17d1066Smrg    struct variant_size;
69b17d1066Smrg
70b17d1066Smrg  template<typename _Variant>
71b17d1066Smrg    struct variant_size<const _Variant> : variant_size<_Variant> {};
72b17d1066Smrg
73b17d1066Smrg  template<typename _Variant>
74b17d1066Smrg    struct variant_size<volatile _Variant> : variant_size<_Variant> {};
75b17d1066Smrg
76b17d1066Smrg  template<typename _Variant>
77b17d1066Smrg    struct variant_size<const volatile _Variant> : variant_size<_Variant> {};
78b17d1066Smrg
79b17d1066Smrg  template<typename... _Types>
80b17d1066Smrg    struct variant_size<variant<_Types...>>
81b17d1066Smrg    : std::integral_constant<size_t, sizeof...(_Types)> {};
82b17d1066Smrg
83b17d1066Smrg  template<typename _Variant>
84b17d1066Smrg    inline constexpr size_t variant_size_v = variant_size<_Variant>::value;
85b17d1066Smrg
86b1e83836Smrg  template<typename... _Types>
87b1e83836Smrg    inline constexpr size_t
88b1e83836Smrg    variant_size_v<variant<_Types...>> = sizeof...(_Types);
89b1e83836Smrg
90b1e83836Smrg  template<typename... _Types>
91b1e83836Smrg    inline constexpr size_t
92b1e83836Smrg    variant_size_v<const variant<_Types...>> = sizeof...(_Types);
93b1e83836Smrg
94b17d1066Smrg  template<size_t _Np, typename _Variant>
95b17d1066Smrg    struct variant_alternative;
96b17d1066Smrg
97b1e83836Smrg  template<size_t _Np, typename... _Types>
98b1e83836Smrg    struct variant_alternative<_Np, variant<_Types...>>
99b1e83836Smrg    {
100b1e83836Smrg      static_assert(_Np < sizeof...(_Types));
101b17d1066Smrg
102b1e83836Smrg      using type = typename _Nth_type<_Np, _Types...>::type;
103b1e83836Smrg    };
104b17d1066Smrg
105b17d1066Smrg  template<size_t _Np, typename _Variant>
106b17d1066Smrg    using variant_alternative_t =
107b17d1066Smrg      typename variant_alternative<_Np, _Variant>::type;
108b17d1066Smrg
109b17d1066Smrg  template<size_t _Np, typename _Variant>
110b17d1066Smrg    struct variant_alternative<_Np, const _Variant>
111b17d1066Smrg    { using type = add_const_t<variant_alternative_t<_Np, _Variant>>; };
112b17d1066Smrg
113b17d1066Smrg  template<size_t _Np, typename _Variant>
114b17d1066Smrg    struct variant_alternative<_Np, volatile _Variant>
115b17d1066Smrg    { using type = add_volatile_t<variant_alternative_t<_Np, _Variant>>; };
116b17d1066Smrg
117b17d1066Smrg  template<size_t _Np, typename _Variant>
118b17d1066Smrg    struct variant_alternative<_Np, const volatile _Variant>
119b17d1066Smrg    { using type = add_cv_t<variant_alternative_t<_Np, _Variant>>; };
120b17d1066Smrg
121b17d1066Smrg  inline constexpr size_t variant_npos = -1;
122b17d1066Smrg
123b17d1066Smrg  template<size_t _Np, typename... _Types>
124b17d1066Smrg    constexpr variant_alternative_t<_Np, variant<_Types...>>&
125b17d1066Smrg    get(variant<_Types...>&);
126b17d1066Smrg
127b17d1066Smrg  template<size_t _Np, typename... _Types>
128b17d1066Smrg    constexpr variant_alternative_t<_Np, variant<_Types...>>&&
129b17d1066Smrg    get(variant<_Types...>&&);
130b17d1066Smrg
131b17d1066Smrg  template<size_t _Np, typename... _Types>
132b17d1066Smrg    constexpr variant_alternative_t<_Np, variant<_Types...>> const&
133b17d1066Smrg    get(const variant<_Types...>&);
134b17d1066Smrg
135b17d1066Smrg  template<size_t _Np, typename... _Types>
136b17d1066Smrg    constexpr variant_alternative_t<_Np, variant<_Types...>> const&&
137b17d1066Smrg    get(const variant<_Types...>&&);
138b17d1066Smrg
139fb8a8121Smrg  template<typename _Result_type, typename _Visitor, typename... _Variants>
140181254a7Smrg    constexpr decltype(auto)
141181254a7Smrg    __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
142181254a7Smrg
143181254a7Smrg  template <typename... _Types, typename _Tp>
144b1e83836Smrg    _GLIBCXX20_CONSTEXPR
145181254a7Smrg    decltype(auto)
146181254a7Smrg    __variant_cast(_Tp&& __rhs)
147181254a7Smrg    {
148181254a7Smrg      if constexpr (is_lvalue_reference_v<_Tp>)
149181254a7Smrg	{
150181254a7Smrg	  if constexpr (is_const_v<remove_reference_t<_Tp>>)
151181254a7Smrg	    return static_cast<const variant<_Types...>&>(__rhs);
152181254a7Smrg	  else
153181254a7Smrg	    return static_cast<variant<_Types...>&>(__rhs);
154181254a7Smrg	}
155181254a7Smrg      else
156181254a7Smrg        return static_cast<variant<_Types...>&&>(__rhs);
157181254a7Smrg    }
158181254a7Smrg
159b17d1066Smrgnamespace __detail
160b17d1066Smrg{
161b17d1066Smrgnamespace __variant
162b17d1066Smrg{
163181254a7Smrg  // used for raw visitation
164181254a7Smrg  struct __variant_cookie {};
165181254a7Smrg  // used for raw visitation with indices passed in
166181254a7Smrg  struct __variant_idx_cookie { using type = __variant_idx_cookie; };
167fb8a8121Smrg  // Used to enable deduction (and same-type checking) for std::visit:
168b1e83836Smrg  template<typename _Tp> struct __deduce_visit_result { using type = _Tp; };
169181254a7Smrg
170fb8a8121Smrg  // Visit variants that might be valueless.
171fb8a8121Smrg  template<typename _Visitor, typename... _Variants>
172fb8a8121Smrg    constexpr void
173fb8a8121Smrg    __raw_visit(_Visitor&& __visitor, _Variants&&... __variants)
174fb8a8121Smrg    {
175fb8a8121Smrg      std::__do_visit<__variant_cookie>(std::forward<_Visitor>(__visitor),
176fb8a8121Smrg				        std::forward<_Variants>(__variants)...);
177fb8a8121Smrg    }
178fb8a8121Smrg
179fb8a8121Smrg  // Visit variants that might be valueless, passing indices to the visitor.
180fb8a8121Smrg  template<typename _Visitor, typename... _Variants>
181fb8a8121Smrg    constexpr void
182fb8a8121Smrg    __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants)
183fb8a8121Smrg    {
184fb8a8121Smrg      std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor),
185fb8a8121Smrg	  std::forward<_Variants>(__variants)...);
186fb8a8121Smrg    }
187fb8a8121Smrg
188b1e83836Smrg  // The __as function templates implement the exposition-only "as-variant"
189b1e83836Smrg
190b1e83836Smrg  template<typename... _Types>
191b1e83836Smrg    constexpr std::variant<_Types...>&
192b1e83836Smrg    __as(std::variant<_Types...>& __v) noexcept
193b1e83836Smrg    { return __v; }
194b1e83836Smrg
195b1e83836Smrg  template<typename... _Types>
196b1e83836Smrg    constexpr const std::variant<_Types...>&
197b1e83836Smrg    __as(const std::variant<_Types...>& __v) noexcept
198b1e83836Smrg    { return __v; }
199b1e83836Smrg
200b1e83836Smrg  template<typename... _Types>
201b1e83836Smrg    constexpr std::variant<_Types...>&&
202b1e83836Smrg    __as(std::variant<_Types...>&& __v) noexcept
203b1e83836Smrg    { return std::move(__v); }
204b1e83836Smrg
205b1e83836Smrg  template<typename... _Types>
206b1e83836Smrg    constexpr const std::variant<_Types...>&&
207b1e83836Smrg    __as(const std::variant<_Types...>&& __v) noexcept
208b1e83836Smrg    { return std::move(__v); }
209b1e83836Smrg
210b1e83836Smrg  // For C++17:
211fb8a8121Smrg  // _Uninitialized<T> is guaranteed to be a trivially destructible type,
212fb8a8121Smrg  // even if T is not.
213b1e83836Smrg  // For C++20:
214b1e83836Smrg  // _Uninitialized<T> is trivially destructible iff T is, so _Variant_union
215b1e83836Smrg  // needs a constrained non-trivial destructor.
216fb8a8121Smrg  template<typename _Type, bool = std::is_trivially_destructible_v<_Type>>
217b17d1066Smrg    struct _Uninitialized;
218b17d1066Smrg
219b17d1066Smrg  template<typename _Type>
220b17d1066Smrg    struct _Uninitialized<_Type, true>
221b17d1066Smrg    {
222b17d1066Smrg      template<typename... _Args>
223181254a7Smrg	constexpr
224181254a7Smrg	_Uninitialized(in_place_index_t<0>, _Args&&... __args)
225b17d1066Smrg	: _M_storage(std::forward<_Args>(__args)...)
226b17d1066Smrg	{ }
227b17d1066Smrg
228181254a7Smrg      constexpr const _Type& _M_get() const & noexcept
229b17d1066Smrg      { return _M_storage; }
230b17d1066Smrg
231181254a7Smrg      constexpr _Type& _M_get() & noexcept
232b17d1066Smrg      { return _M_storage; }
233b17d1066Smrg
234181254a7Smrg      constexpr const _Type&& _M_get() const && noexcept
235b17d1066Smrg      { return std::move(_M_storage); }
236b17d1066Smrg
237181254a7Smrg      constexpr _Type&& _M_get() && noexcept
238b17d1066Smrg      { return std::move(_M_storage); }
239b17d1066Smrg
240b17d1066Smrg      _Type _M_storage;
241b17d1066Smrg    };
242b17d1066Smrg
243b17d1066Smrg  template<typename _Type>
244b17d1066Smrg    struct _Uninitialized<_Type, false>
245b17d1066Smrg    {
246b1e83836Smrg#if __cpp_lib_variant >= 202106L
247b1e83836Smrg      template<typename... _Args>
248b1e83836Smrg	constexpr
249b1e83836Smrg	_Uninitialized(in_place_index_t<0>, _Args&&... __args)
250b1e83836Smrg	: _M_storage(std::forward<_Args>(__args)...)
251b1e83836Smrg	{ }
252b1e83836Smrg
253b1e83836Smrg      constexpr ~_Uninitialized() { }
254b1e83836Smrg
255b1e83836Smrg      _Uninitialized(const _Uninitialized&) = default;
256b1e83836Smrg      _Uninitialized(_Uninitialized&&) = default;
257b1e83836Smrg      _Uninitialized& operator=(const _Uninitialized&) = default;
258b1e83836Smrg      _Uninitialized& operator=(_Uninitialized&&) = default;
259b1e83836Smrg
260b1e83836Smrg      constexpr const _Type& _M_get() const & noexcept
261b1e83836Smrg      { return _M_storage; }
262b1e83836Smrg
263b1e83836Smrg      constexpr _Type& _M_get() & noexcept
264b1e83836Smrg      { return _M_storage; }
265b1e83836Smrg
266b1e83836Smrg      constexpr const _Type&& _M_get() const && noexcept
267b1e83836Smrg      { return std::move(_M_storage); }
268b1e83836Smrg
269b1e83836Smrg      constexpr _Type&& _M_get() && noexcept
270b1e83836Smrg      { return std::move(_M_storage); }
271b1e83836Smrg
272b1e83836Smrg      struct _Empty_byte { };
273b1e83836Smrg
274b1e83836Smrg      union {
275b1e83836Smrg	_Empty_byte _M_empty;
276b1e83836Smrg	_Type _M_storage;
277b1e83836Smrg      };
278b1e83836Smrg#else
279b17d1066Smrg      template<typename... _Args>
280181254a7Smrg	constexpr
281181254a7Smrg	_Uninitialized(in_place_index_t<0>, _Args&&... __args)
282181254a7Smrg	{
283181254a7Smrg	  ::new ((void*)std::addressof(_M_storage))
284181254a7Smrg	    _Type(std::forward<_Args>(__args)...);
285181254a7Smrg	}
286b17d1066Smrg
287181254a7Smrg      const _Type& _M_get() const & noexcept
288b17d1066Smrg      { return *_M_storage._M_ptr(); }
289b17d1066Smrg
290181254a7Smrg      _Type& _M_get() & noexcept
291b17d1066Smrg      { return *_M_storage._M_ptr(); }
292b17d1066Smrg
293181254a7Smrg      const _Type&& _M_get() const && noexcept
294b17d1066Smrg      { return std::move(*_M_storage._M_ptr()); }
295b17d1066Smrg
296181254a7Smrg      _Type&& _M_get() && noexcept
297b17d1066Smrg      { return std::move(*_M_storage._M_ptr()); }
298b17d1066Smrg
299b17d1066Smrg      __gnu_cxx::__aligned_membuf<_Type> _M_storage;
300b1e83836Smrg#endif
301b17d1066Smrg    };
302b17d1066Smrg
303b17d1066Smrg  template<size_t _Np, typename _Union>
304181254a7Smrg    constexpr decltype(auto)
305b1e83836Smrg    __get_n(_Union&& __u) noexcept
306b17d1066Smrg    {
307b1e83836Smrg      if constexpr (_Np == 0)
308b1e83836Smrg	return std::forward<_Union>(__u)._M_first._M_get();
309b1e83836Smrg      else if constexpr (_Np == 1)
310b1e83836Smrg	return std::forward<_Union>(__u)._M_rest._M_first._M_get();
311b1e83836Smrg      else if constexpr (_Np == 2)
312b1e83836Smrg	return std::forward<_Union>(__u)._M_rest._M_rest._M_first._M_get();
313b1e83836Smrg      else
314b1e83836Smrg	return __variant::__get_n<_Np - 3>(
315b1e83836Smrg		 std::forward<_Union>(__u)._M_rest._M_rest._M_rest);
316b17d1066Smrg    }
317b17d1066Smrg
318b17d1066Smrg  // Returns the typed storage for __v.
319b17d1066Smrg  template<size_t _Np, typename _Variant>
320181254a7Smrg    constexpr decltype(auto)
321181254a7Smrg    __get(_Variant&& __v) noexcept
322b1e83836Smrg    { return __variant::__get_n<_Np>(std::forward<_Variant>(__v)._M_u); }
323b17d1066Smrg
324*0a307195Smrg  // Gets the _Uninitialized to construct into for __u.
325*0a307195Smrg  template<size_t _Np, typename _Union>
326*0a307195Smrg    constexpr decltype(auto)
327*0a307195Smrg    __construct_n(_Union& __u) noexcept
328*0a307195Smrg    {
329*0a307195Smrg      if constexpr (_Np == 0)
330*0a307195Smrg	return &__u._M_first;
331*0a307195Smrg      else if constexpr (_Np == 1)
332*0a307195Smrg	{
333*0a307195Smrg	  std::_Construct(&__u._M_rest);
334*0a307195Smrg	  return &__u._M_rest._M_first;
335*0a307195Smrg	}
336*0a307195Smrg      else if constexpr (_Np == 2)
337*0a307195Smrg	{
338*0a307195Smrg	  std::_Construct(&__u._M_rest);
339*0a307195Smrg	  std::_Construct(&__u._M_rest._M_rest);
340*0a307195Smrg	  return &__u._M_rest._M_rest._M_first;
341*0a307195Smrg	}
342*0a307195Smrg      else
343*0a307195Smrg	{
344*0a307195Smrg	  std::_Construct(&__u._M_rest);
345*0a307195Smrg	  std::_Construct(&__u._M_rest._M_rest);
346*0a307195Smrg	  std::_Construct(&__u._M_rest._M_rest._M_rest);
347*0a307195Smrg	  return __variant::__construct_n<_Np - 3>(__u._M_rest._M_rest._M_rest);
348*0a307195Smrg	}
349*0a307195Smrg    }
350*0a307195Smrg
351a3e9eb18Smrg  template<typename... _Types>
352a3e9eb18Smrg    struct _Traits
353a3e9eb18Smrg    {
354a3e9eb18Smrg      static constexpr bool _S_default_ctor =
355a3e9eb18Smrg	  is_default_constructible_v<typename _Nth_type<0, _Types...>::type>;
356a3e9eb18Smrg      static constexpr bool _S_copy_ctor =
357a3e9eb18Smrg	  (is_copy_constructible_v<_Types> && ...);
358a3e9eb18Smrg      static constexpr bool _S_move_ctor =
359a3e9eb18Smrg	  (is_move_constructible_v<_Types> && ...);
360a3e9eb18Smrg      static constexpr bool _S_copy_assign =
361181254a7Smrg	  _S_copy_ctor
362a3e9eb18Smrg	  && (is_copy_assignable_v<_Types> && ...);
363a3e9eb18Smrg      static constexpr bool _S_move_assign =
364a3e9eb18Smrg	  _S_move_ctor
365a3e9eb18Smrg	  && (is_move_assignable_v<_Types> && ...);
366a3e9eb18Smrg
367a3e9eb18Smrg      static constexpr bool _S_trivial_dtor =
368a3e9eb18Smrg	  (is_trivially_destructible_v<_Types> && ...);
369a3e9eb18Smrg      static constexpr bool _S_trivial_copy_ctor =
370a3e9eb18Smrg	  (is_trivially_copy_constructible_v<_Types> && ...);
371a3e9eb18Smrg      static constexpr bool _S_trivial_move_ctor =
372a3e9eb18Smrg	  (is_trivially_move_constructible_v<_Types> && ...);
373a3e9eb18Smrg      static constexpr bool _S_trivial_copy_assign =
374181254a7Smrg	  _S_trivial_dtor && _S_trivial_copy_ctor
375181254a7Smrg	  && (is_trivially_copy_assignable_v<_Types> && ...);
376a3e9eb18Smrg      static constexpr bool _S_trivial_move_assign =
377181254a7Smrg	  _S_trivial_dtor && _S_trivial_move_ctor
378181254a7Smrg	  && (is_trivially_move_assignable_v<_Types> && ...);
379a3e9eb18Smrg
380a3e9eb18Smrg      // The following nothrow traits are for non-trivial SMFs. Trivial SMFs
381a3e9eb18Smrg      // are always nothrow.
382a3e9eb18Smrg      static constexpr bool _S_nothrow_default_ctor =
383a3e9eb18Smrg	  is_nothrow_default_constructible_v<
384a3e9eb18Smrg	      typename _Nth_type<0, _Types...>::type>;
385a3e9eb18Smrg      static constexpr bool _S_nothrow_copy_ctor = false;
386a3e9eb18Smrg      static constexpr bool _S_nothrow_move_ctor =
387a3e9eb18Smrg	  (is_nothrow_move_constructible_v<_Types> && ...);
388a3e9eb18Smrg      static constexpr bool _S_nothrow_copy_assign = false;
389a3e9eb18Smrg      static constexpr bool _S_nothrow_move_assign =
390181254a7Smrg	  _S_nothrow_move_ctor
391181254a7Smrg	  && (is_nothrow_move_assignable_v<_Types> && ...);
392a3e9eb18Smrg    };
393a3e9eb18Smrg
394b17d1066Smrg  // Defines members and ctors.
395b17d1066Smrg  template<typename... _Types>
396b1e83836Smrg    union _Variadic_union
397b1e83836Smrg    {
398b1e83836Smrg      _Variadic_union() = default;
399b1e83836Smrg
400b1e83836Smrg      template<size_t _Np, typename... _Args>
401b1e83836Smrg	_Variadic_union(in_place_index_t<_Np>, _Args&&...) = delete;
402b1e83836Smrg    };
403b17d1066Smrg
404b17d1066Smrg  template<typename _First, typename... _Rest>
405b17d1066Smrg    union _Variadic_union<_First, _Rest...>
406b17d1066Smrg    {
407b17d1066Smrg      constexpr _Variadic_union() : _M_rest() { }
408b17d1066Smrg
409b17d1066Smrg      template<typename... _Args>
410b1e83836Smrg	constexpr
411b1e83836Smrg	_Variadic_union(in_place_index_t<0>, _Args&&... __args)
412b17d1066Smrg	: _M_first(in_place_index<0>, std::forward<_Args>(__args)...)
413b17d1066Smrg	{ }
414b17d1066Smrg
415b17d1066Smrg      template<size_t _Np, typename... _Args>
416b1e83836Smrg	constexpr
417b1e83836Smrg	_Variadic_union(in_place_index_t<_Np>, _Args&&... __args)
418b17d1066Smrg	: _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...)
419b17d1066Smrg	{ }
420b17d1066Smrg
421b1e83836Smrg#if __cpp_lib_variant >= 202106L
422b1e83836Smrg      _Variadic_union(const _Variadic_union&) = default;
423b1e83836Smrg      _Variadic_union(_Variadic_union&&) = default;
424b1e83836Smrg      _Variadic_union& operator=(const _Variadic_union&) = default;
425b1e83836Smrg      _Variadic_union& operator=(_Variadic_union&&) = default;
426b1e83836Smrg
427b1e83836Smrg      ~_Variadic_union() = default;
428b1e83836Smrg
429b1e83836Smrg      constexpr ~_Variadic_union()
430b1e83836Smrg	requires (!__has_trivial_destructor(_First))
431b1e83836Smrg	      || (!__has_trivial_destructor(_Variadic_union<_Rest...>))
432b1e83836Smrg      { }
433b1e83836Smrg#endif
434b1e83836Smrg
435b17d1066Smrg      _Uninitialized<_First> _M_first;
436b17d1066Smrg      _Variadic_union<_Rest...> _M_rest;
437b17d1066Smrg    };
438b17d1066Smrg
439181254a7Smrg  // _Never_valueless_alt is true for variant alternatives that can
440181254a7Smrg  // always be placed in a variant without it becoming valueless.
441181254a7Smrg
442181254a7Smrg  // For suitably-small, trivially copyable types we can create temporaries
443181254a7Smrg  // on the stack and then memcpy them into place.
444181254a7Smrg  template<typename _Tp>
445181254a7Smrg    struct _Never_valueless_alt
446181254a7Smrg    : __and_<bool_constant<sizeof(_Tp) <= 256>, is_trivially_copyable<_Tp>>
447181254a7Smrg    { };
448181254a7Smrg
449181254a7Smrg  // Specialize _Never_valueless_alt for other types which have a
450181254a7Smrg  // non-throwing and cheap move construction and move assignment operator,
451181254a7Smrg  // so that emplacing the type will provide the strong exception-safety
452181254a7Smrg  // guarantee, by creating and moving a temporary.
453181254a7Smrg  // Whether _Never_valueless_alt<T> is true or not affects the ABI of a
454181254a7Smrg  // variant using that alternative, so we can't change the value later!
455181254a7Smrg
456181254a7Smrg  // True if every alternative in _Types... can be emplaced in a variant
457181254a7Smrg  // without it becoming valueless. If this is true, variant<_Types...>
458181254a7Smrg  // can never be valueless, which enables some minor optimizations.
459181254a7Smrg  template <typename... _Types>
460181254a7Smrg    constexpr bool __never_valueless()
461181254a7Smrg    {
462181254a7Smrg      return _Traits<_Types...>::_S_move_assign
463181254a7Smrg	&& (_Never_valueless_alt<_Types>::value && ...);
464181254a7Smrg    }
465181254a7Smrg
466b17d1066Smrg  // Defines index and the dtor, possibly trivial.
467b17d1066Smrg  template<bool __trivially_destructible, typename... _Types>
468b17d1066Smrg    struct _Variant_storage;
469b17d1066Smrg
470b17d1066Smrg  template <typename... _Types>
471b17d1066Smrg    using __select_index =
472181254a7Smrg      typename __select_int::_Select_int_base<sizeof...(_Types),
473b17d1066Smrg					      unsigned char,
474b17d1066Smrg					      unsigned short>::type::value_type;
475b17d1066Smrg
476b17d1066Smrg  template<typename... _Types>
477b17d1066Smrg    struct _Variant_storage<false, _Types...>
478b17d1066Smrg    {
479fb8a8121Smrg      constexpr
480fb8a8121Smrg      _Variant_storage()
481fb8a8121Smrg      : _M_index(static_cast<__index_type>(variant_npos))
482b17d1066Smrg      { }
483b17d1066Smrg
484fb8a8121Smrg      template<size_t _Np, typename... _Args>
485fb8a8121Smrg	constexpr
486fb8a8121Smrg	_Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
487fb8a8121Smrg	: _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
488fb8a8121Smrg	_M_index{_Np}
489fb8a8121Smrg	{ }
490b17d1066Smrg
491b1e83836Smrg      constexpr void
492b1e83836Smrg      _M_reset()
493b17d1066Smrg      {
494fb8a8121Smrg	if (!_M_valid()) [[unlikely]]
495fb8a8121Smrg	  return;
496fb8a8121Smrg
497fb8a8121Smrg	std::__do_visit<void>([](auto&& __this_mem) mutable
498fb8a8121Smrg	  {
499fb8a8121Smrg	    std::_Destroy(std::__addressof(__this_mem));
500fb8a8121Smrg	  }, __variant_cast<_Types...>(*this));
501fb8a8121Smrg
502fb8a8121Smrg	_M_index = static_cast<__index_type>(variant_npos);
503b17d1066Smrg      }
504b17d1066Smrg
505b1e83836Smrg      _GLIBCXX20_CONSTEXPR
506b17d1066Smrg      ~_Variant_storage()
507b17d1066Smrg      { _M_reset(); }
508b17d1066Smrg
509a3e9eb18Smrg      constexpr bool
510a3e9eb18Smrg      _M_valid() const noexcept
511a3e9eb18Smrg      {
512fb8a8121Smrg	if constexpr (__variant::__never_valueless<_Types...>())
513181254a7Smrg	  return true;
514a3e9eb18Smrg	return this->_M_index != __index_type(variant_npos);
515a3e9eb18Smrg      }
516a3e9eb18Smrg
517b17d1066Smrg      _Variadic_union<_Types...> _M_u;
518b17d1066Smrg      using __index_type = __select_index<_Types...>;
519b17d1066Smrg      __index_type _M_index;
520b17d1066Smrg    };
521b17d1066Smrg
522b17d1066Smrg  template<typename... _Types>
523b17d1066Smrg    struct _Variant_storage<true, _Types...>
524b17d1066Smrg    {
525fb8a8121Smrg      constexpr
526fb8a8121Smrg      _Variant_storage()
527fb8a8121Smrg      : _M_index(static_cast<__index_type>(variant_npos))
528b17d1066Smrg      { }
529b17d1066Smrg
530fb8a8121Smrg      template<size_t _Np, typename... _Args>
531fb8a8121Smrg	constexpr
532fb8a8121Smrg	_Variant_storage(in_place_index_t<_Np>, _Args&&... __args)
533fb8a8121Smrg	: _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...),
534fb8a8121Smrg	_M_index{_Np}
535fb8a8121Smrg	{ }
536fb8a8121Smrg
537b1e83836Smrg      constexpr void
538b1e83836Smrg      _M_reset() noexcept
539fb8a8121Smrg      { _M_index = static_cast<__index_type>(variant_npos); }
540b17d1066Smrg
541a3e9eb18Smrg      constexpr bool
542a3e9eb18Smrg      _M_valid() const noexcept
543a3e9eb18Smrg      {
544fb8a8121Smrg	if constexpr (__variant::__never_valueless<_Types...>())
545181254a7Smrg	  return true;
546b1e83836Smrg	// It would be nice if we could just return true for -fno-exceptions.
547b1e83836Smrg	// It's possible (but inadvisable) that a std::variant could become
548b1e83836Smrg	// valueless in a translation unit compiled with -fexceptions and then
549b1e83836Smrg	// be passed to functions compiled with -fno-exceptions. We would need
550b1e83836Smrg	// some #ifdef _GLIBCXX_NO_EXCEPTIONS_GLOBALLY property to elide all
551b1e83836Smrg	// checks for valueless_by_exception().
552fb8a8121Smrg	return this->_M_index != static_cast<__index_type>(variant_npos);
553a3e9eb18Smrg      }
554a3e9eb18Smrg
555b17d1066Smrg      _Variadic_union<_Types...> _M_u;
556b17d1066Smrg      using __index_type = __select_index<_Types...>;
557b17d1066Smrg      __index_type _M_index;
558b17d1066Smrg    };
559b17d1066Smrg
560b1e83836Smrg  // Implementation of v.emplace<N>(args...).
561b1e83836Smrg  template<size_t _Np, bool _Triv, typename... _Types, typename... _Args>
562b1e83836Smrg    _GLIBCXX20_CONSTEXPR
563b1e83836Smrg    inline void
564b1e83836Smrg    __emplace(_Variant_storage<_Triv, _Types...>& __v, _Args&&... __args)
565b1e83836Smrg    {
566b1e83836Smrg      __v._M_reset();
567*0a307195Smrg      auto* __addr = __variant::__construct_n<_Np>(__v._M_u);
568*0a307195Smrg      std::_Construct(__addr, in_place_index<0>,
569*0a307195Smrg		      std::forward<_Args>(__args)...);
570b1e83836Smrg      // Construction didn't throw, so can set the new index now:
571b1e83836Smrg      __v._M_index = _Np;
572b1e83836Smrg    }
573b1e83836Smrg
574b17d1066Smrg  template<typename... _Types>
575a3e9eb18Smrg    using _Variant_storage_alias =
576a3e9eb18Smrg	_Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
577a3e9eb18Smrg
578a3e9eb18Smrg  // The following are (Copy|Move) (ctor|assign) layers for forwarding
579a3e9eb18Smrg  // triviality and handling non-trivial SMF behaviors.
580a3e9eb18Smrg
581a3e9eb18Smrg  template<bool, typename... _Types>
582a3e9eb18Smrg    struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
583b17d1066Smrg    {
584a3e9eb18Smrg      using _Base = _Variant_storage_alias<_Types...>;
585a3e9eb18Smrg      using _Base::_Base;
586b17d1066Smrg
587b1e83836Smrg      _GLIBCXX20_CONSTEXPR
588a3e9eb18Smrg      _Copy_ctor_base(const _Copy_ctor_base& __rhs)
589a3e9eb18Smrg	  noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor)
590b17d1066Smrg      {
591b1e83836Smrg	__variant::__raw_idx_visit(
592b1e83836Smrg	  [this](auto&& __rhs_mem, auto __rhs_index) mutable
593b1e83836Smrg	  {
594b1e83836Smrg	    constexpr size_t __j = __rhs_index;
595b1e83836Smrg	    if constexpr (__j != variant_npos)
596b1e83836Smrg	      std::_Construct(std::__addressof(this->_M_u),
597b1e83836Smrg			      in_place_index<__j>, __rhs_mem);
598b1e83836Smrg	  }, __variant_cast<_Types...>(__rhs));
599b1e83836Smrg	this->_M_index = __rhs._M_index;
600b17d1066Smrg      }
601b17d1066Smrg
602a3e9eb18Smrg      _Copy_ctor_base(_Copy_ctor_base&&) = default;
603a3e9eb18Smrg      _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default;
604a3e9eb18Smrg      _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default;
605a3e9eb18Smrg    };
606a3e9eb18Smrg
607a3e9eb18Smrg  template<typename... _Types>
608a3e9eb18Smrg    struct _Copy_ctor_base<true, _Types...> : _Variant_storage_alias<_Types...>
609a3e9eb18Smrg    {
610a3e9eb18Smrg      using _Base = _Variant_storage_alias<_Types...>;
611a3e9eb18Smrg      using _Base::_Base;
612a3e9eb18Smrg    };
613a3e9eb18Smrg
614a3e9eb18Smrg  template<typename... _Types>
615a3e9eb18Smrg    using _Copy_ctor_alias =
616a3e9eb18Smrg	_Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>;
617a3e9eb18Smrg
618a3e9eb18Smrg  template<bool, typename... _Types>
619a3e9eb18Smrg    struct _Move_ctor_base : _Copy_ctor_alias<_Types...>
620a3e9eb18Smrg    {
621a3e9eb18Smrg      using _Base = _Copy_ctor_alias<_Types...>;
622a3e9eb18Smrg      using _Base::_Base;
623a3e9eb18Smrg
624b1e83836Smrg      _GLIBCXX20_CONSTEXPR
625a3e9eb18Smrg      _Move_ctor_base(_Move_ctor_base&& __rhs)
626a3e9eb18Smrg	  noexcept(_Traits<_Types...>::_S_nothrow_move_ctor)
627b17d1066Smrg      {
628b1e83836Smrg	__variant::__raw_idx_visit(
629b1e83836Smrg	  [this](auto&& __rhs_mem, auto __rhs_index) mutable
630a3e9eb18Smrg	  {
631b1e83836Smrg	    constexpr size_t __j = __rhs_index;
632b1e83836Smrg	    if constexpr (__j != variant_npos)
633b1e83836Smrg	      std::_Construct(std::__addressof(this->_M_u),
634b1e83836Smrg			      in_place_index<__j>,
635b1e83836Smrg			      std::forward<decltype(__rhs_mem)>(__rhs_mem));
636b1e83836Smrg	  }, __variant_cast<_Types...>(std::move(__rhs)));
637b1e83836Smrg	this->_M_index = __rhs._M_index;
638a3e9eb18Smrg      }
6398b6133e5Smrg
640a3e9eb18Smrg      _Move_ctor_base(const _Move_ctor_base&) = default;
641a3e9eb18Smrg      _Move_ctor_base& operator=(const _Move_ctor_base&) = default;
642a3e9eb18Smrg      _Move_ctor_base& operator=(_Move_ctor_base&&) = default;
643a3e9eb18Smrg    };
644a3e9eb18Smrg
645a3e9eb18Smrg  template<typename... _Types>
646a3e9eb18Smrg    struct _Move_ctor_base<true, _Types...> : _Copy_ctor_alias<_Types...>
647a3e9eb18Smrg    {
648a3e9eb18Smrg      using _Base = _Copy_ctor_alias<_Types...>;
649a3e9eb18Smrg      using _Base::_Base;
650a3e9eb18Smrg    };
651a3e9eb18Smrg
652a3e9eb18Smrg  template<typename... _Types>
653a3e9eb18Smrg    using _Move_ctor_alias =
654a3e9eb18Smrg	_Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>;
655a3e9eb18Smrg
656a3e9eb18Smrg  template<bool, typename... _Types>
657a3e9eb18Smrg    struct _Copy_assign_base : _Move_ctor_alias<_Types...>
658a3e9eb18Smrg    {
659a3e9eb18Smrg      using _Base = _Move_ctor_alias<_Types...>;
660a3e9eb18Smrg      using _Base::_Base;
661a3e9eb18Smrg
662b1e83836Smrg      _GLIBCXX20_CONSTEXPR
663a3e9eb18Smrg      _Copy_assign_base&
664a3e9eb18Smrg      operator=(const _Copy_assign_base& __rhs)
665a3e9eb18Smrg	  noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
66614f5a3b0Smrg      {
667fb8a8121Smrg	__variant::__raw_idx_visit(
668fb8a8121Smrg	  [this](auto&& __rhs_mem, auto __rhs_index) mutable
6698b6133e5Smrg	  {
670b1e83836Smrg	    constexpr size_t __j = __rhs_index;
671b1e83836Smrg	    if constexpr (__j == variant_npos)
672b1e83836Smrg	      this->_M_reset(); // Make *this valueless.
673b1e83836Smrg	    else if (this->_M_index == __j)
674b1e83836Smrg	      __variant::__get<__j>(*this) = __rhs_mem;
675181254a7Smrg	    else
676181254a7Smrg	      {
677b1e83836Smrg		using _Tj = typename _Nth_type<__j, _Types...>::type;
678b1e83836Smrg		if constexpr (is_nothrow_copy_constructible_v<_Tj>
679b1e83836Smrg			      || !is_nothrow_move_constructible_v<_Tj>)
680b1e83836Smrg		  __variant::__emplace<__j>(*this, __rhs_mem);
681181254a7Smrg		else
682b1e83836Smrg		  {
683b1e83836Smrg		    using _Variant = variant<_Types...>;
684b1e83836Smrg		    _Variant& __self = __variant_cast<_Types...>(*this);
685b1e83836Smrg		    __self = _Variant(in_place_index<__j>, __rhs_mem);
6868b6133e5Smrg		  }
6878b6133e5Smrg	      }
688181254a7Smrg	  }, __variant_cast<_Types...>(__rhs));
6898b6133e5Smrg	return *this;
6908b6133e5Smrg      }
6918b6133e5Smrg
692a3e9eb18Smrg      _Copy_assign_base(const _Copy_assign_base&) = default;
693a3e9eb18Smrg      _Copy_assign_base(_Copy_assign_base&&) = default;
694a3e9eb18Smrg      _Copy_assign_base& operator=(_Copy_assign_base&&) = default;
695a3e9eb18Smrg    };
696b17d1066Smrg
697a3e9eb18Smrg  template<typename... _Types>
698a3e9eb18Smrg    struct _Copy_assign_base<true, _Types...> : _Move_ctor_alias<_Types...>
699a3e9eb18Smrg    {
700a3e9eb18Smrg      using _Base = _Move_ctor_alias<_Types...>;
701a3e9eb18Smrg      using _Base::_Base;
702a3e9eb18Smrg    };
703a3e9eb18Smrg
704a3e9eb18Smrg  template<typename... _Types>
705a3e9eb18Smrg    using _Copy_assign_alias =
706181254a7Smrg      _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>;
707a3e9eb18Smrg
708a3e9eb18Smrg  template<bool, typename... _Types>
709a3e9eb18Smrg    struct _Move_assign_base : _Copy_assign_alias<_Types...>
710a3e9eb18Smrg    {
711a3e9eb18Smrg      using _Base = _Copy_assign_alias<_Types...>;
712a3e9eb18Smrg      using _Base::_Base;
713a3e9eb18Smrg
714b1e83836Smrg      _GLIBCXX20_CONSTEXPR
715a3e9eb18Smrg      _Move_assign_base&
716a3e9eb18Smrg      operator=(_Move_assign_base&& __rhs)
717a3e9eb18Smrg	  noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
718b17d1066Smrg      {
719fb8a8121Smrg	__variant::__raw_idx_visit(
720fb8a8121Smrg	  [this](auto&& __rhs_mem, auto __rhs_index) mutable
721b17d1066Smrg	  {
722b1e83836Smrg	    constexpr size_t __j = __rhs_index;
723b1e83836Smrg	    if constexpr (__j != variant_npos)
724b17d1066Smrg	      {
725b1e83836Smrg		if (this->_M_index == __j)
726b1e83836Smrg		  __variant::__get<__j>(*this) = std::move(__rhs_mem);
727181254a7Smrg		else
728b1e83836Smrg		  {
729b1e83836Smrg		    using _Tj = typename _Nth_type<__j, _Types...>::type;
730b1e83836Smrg		    if constexpr (is_nothrow_move_constructible_v<_Tj>)
731b1e83836Smrg		      __variant::__emplace<__j>(*this, std::move(__rhs_mem));
732b1e83836Smrg		    else
733b1e83836Smrg		      {
734b1e83836Smrg			using _Variant = variant<_Types...>;
735b1e83836Smrg			_Variant& __self = __variant_cast<_Types...>(*this);
736b1e83836Smrg			__self.template emplace<__j>(std::move(__rhs_mem));
737b1e83836Smrg		      }
738b1e83836Smrg		  }
739b17d1066Smrg	      }
740b17d1066Smrg	    else
741181254a7Smrg	      this->_M_reset();
742181254a7Smrg	  }, __variant_cast<_Types...>(__rhs));
743b17d1066Smrg	return *this;
744b17d1066Smrg      }
745b17d1066Smrg
746a3e9eb18Smrg      _Move_assign_base(const _Move_assign_base&) = default;
747a3e9eb18Smrg      _Move_assign_base(_Move_assign_base&&) = default;
748a3e9eb18Smrg      _Move_assign_base& operator=(const _Move_assign_base&) = default;
749a3e9eb18Smrg    };
75014f5a3b0Smrg
751a3e9eb18Smrg  template<typename... _Types>
752a3e9eb18Smrg    struct _Move_assign_base<true, _Types...> : _Copy_assign_alias<_Types...>
75314f5a3b0Smrg    {
754a3e9eb18Smrg      using _Base = _Copy_assign_alias<_Types...>;
755a3e9eb18Smrg      using _Base::_Base;
756a3e9eb18Smrg    };
757a3e9eb18Smrg
758a3e9eb18Smrg  template<typename... _Types>
759a3e9eb18Smrg    using _Move_assign_alias =
760181254a7Smrg      _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>;
761a3e9eb18Smrg
762a3e9eb18Smrg  template<typename... _Types>
763a3e9eb18Smrg    struct _Variant_base : _Move_assign_alias<_Types...>
764a3e9eb18Smrg    {
765a3e9eb18Smrg      using _Base = _Move_assign_alias<_Types...>;
766a3e9eb18Smrg
767a3e9eb18Smrg      constexpr
768b1e83836Smrg      _Variant_base() noexcept(_Traits<_Types...>::_S_nothrow_default_ctor)
769a3e9eb18Smrg      : _Variant_base(in_place_index<0>) { }
770a3e9eb18Smrg
771a3e9eb18Smrg      template<size_t _Np, typename... _Args>
772a3e9eb18Smrg	constexpr explicit
773a3e9eb18Smrg	_Variant_base(in_place_index_t<_Np> __i, _Args&&... __args)
774a3e9eb18Smrg	: _Base(__i, std::forward<_Args>(__args)...)
775a3e9eb18Smrg	{ }
776a3e9eb18Smrg
777a3e9eb18Smrg      _Variant_base(const _Variant_base&) = default;
778a3e9eb18Smrg      _Variant_base(_Variant_base&&) = default;
779a3e9eb18Smrg      _Variant_base& operator=(const _Variant_base&) = default;
780a3e9eb18Smrg      _Variant_base& operator=(_Variant_base&&) = default;
781b17d1066Smrg    };
782b17d1066Smrg
783b17d1066Smrg  template<typename _Tp, typename... _Types>
784b1e83836Smrg    inline constexpr bool __exactly_once
785b1e83836Smrg      = std::__find_uniq_type_in_pack<_Tp, _Types...>() < sizeof...(_Types);
786b17d1066Smrg
787fb8a8121Smrg  // Helper used to check for valid conversions that don't involve narrowing.
788fb8a8121Smrg  template<typename _Ti> struct _Arr { _Ti _M_x[1]; };
789b17d1066Smrg
790b1e83836Smrg  // "Build an imaginary function FUN(Ti) for each alternative type Ti"
791b1e83836Smrg  template<size_t _Ind, typename _Tp, typename _Ti, typename = void>
792fb8a8121Smrg    struct _Build_FUN
793b17d1066Smrg    {
794fb8a8121Smrg      // This function means 'using _Build_FUN<I, T, Ti>::_S_fun;' is valid,
795fb8a8121Smrg      // but only static functions will be considered in the call below.
796fb8a8121Smrg      void _S_fun();
797b17d1066Smrg    };
798b17d1066Smrg
799b1e83836Smrg  // "... for which Ti x[] = {std::forward<T>(t)}; is well-formed."
800fb8a8121Smrg  template<size_t _Ind, typename _Tp, typename _Ti>
801b1e83836Smrg    struct _Build_FUN<_Ind, _Tp, _Ti,
802fb8a8121Smrg		      void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>>
803b17d1066Smrg    {
804fb8a8121Smrg      // This is the FUN function for type _Ti, with index _Ind
805fb8a8121Smrg      static integral_constant<size_t, _Ind> _S_fun(_Ti);
806b17d1066Smrg    };
807b17d1066Smrg
808fb8a8121Smrg  template<typename _Tp, typename _Variant,
809fb8a8121Smrg	   typename = make_index_sequence<variant_size_v<_Variant>>>
810fb8a8121Smrg    struct _Build_FUNs;
811fb8a8121Smrg
812fb8a8121Smrg  template<typename _Tp, typename... _Ti, size_t... _Ind>
813fb8a8121Smrg    struct _Build_FUNs<_Tp, variant<_Ti...>, index_sequence<_Ind...>>
814fb8a8121Smrg    : _Build_FUN<_Ind, _Tp, _Ti>...
815fb8a8121Smrg    {
816fb8a8121Smrg      using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...;
817fb8a8121Smrg    };
818fb8a8121Smrg
819fb8a8121Smrg  // The index j of the overload FUN(Tj) selected by overload resolution
820fb8a8121Smrg  // for FUN(std::forward<_Tp>(t))
821fb8a8121Smrg  template<typename _Tp, typename _Variant>
822fb8a8121Smrg    using _FUN_type
823fb8a8121Smrg      = decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>()));
824fb8a8121Smrg
825fb8a8121Smrg  // The index selected for FUN(std::forward<T>(t)), or variant_npos if none.
826b17d1066Smrg  template<typename _Tp, typename _Variant, typename = void>
827b17d1066Smrg    struct __accepted_index
828fb8a8121Smrg    : integral_constant<size_t, variant_npos>
829fb8a8121Smrg    { };
830b17d1066Smrg
831fb8a8121Smrg  template<typename _Tp, typename _Variant>
832fb8a8121Smrg    struct __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>>
833fb8a8121Smrg    : _FUN_type<_Tp, _Variant>
834fb8a8121Smrg    { };
835b17d1066Smrg
836181254a7Smrg  template <typename _Maybe_variant_cookie, typename _Variant>
837181254a7Smrg    struct _Extra_visit_slot_needed
838181254a7Smrg    {
839181254a7Smrg      template <typename> struct _Variant_never_valueless;
840181254a7Smrg
841181254a7Smrg      template <typename... _Types>
842181254a7Smrg	struct _Variant_never_valueless<variant<_Types...>>
843fb8a8121Smrg	: bool_constant<__variant::__never_valueless<_Types...>()> {};
844181254a7Smrg
845181254a7Smrg      static constexpr bool value =
846181254a7Smrg	(is_same_v<_Maybe_variant_cookie, __variant_cookie>
847181254a7Smrg	 || is_same_v<_Maybe_variant_cookie, __variant_idx_cookie>)
848181254a7Smrg	&& !_Variant_never_valueless<__remove_cvref_t<_Variant>>::value;
849181254a7Smrg    };
850181254a7Smrg
851181254a7Smrg  // Used for storing a multi-dimensional vtable.
852b17d1066Smrg  template<typename _Tp, size_t... _Dimensions>
853181254a7Smrg    struct _Multi_array;
854181254a7Smrg
855181254a7Smrg  // Partial specialization with rank zero, stores a single _Tp element.
856181254a7Smrg  template<typename _Tp>
857181254a7Smrg    struct _Multi_array<_Tp>
858b17d1066Smrg    {
859fb8a8121Smrg      template<typename>
860fb8a8121Smrg	struct __untag_result
861fb8a8121Smrg	: false_type
862fb8a8121Smrg	{ using element_type = _Tp; };
863fb8a8121Smrg
864fb8a8121Smrg      template <typename... _Args>
865fb8a8121Smrg	struct __untag_result<const void(*)(_Args...)>
866fb8a8121Smrg	: false_type
867fb8a8121Smrg	{ using element_type = void(*)(_Args...); };
868fb8a8121Smrg
869fb8a8121Smrg      template <typename... _Args>
870fb8a8121Smrg	struct __untag_result<__variant_cookie(*)(_Args...)>
871fb8a8121Smrg	: false_type
872fb8a8121Smrg	{ using element_type = void(*)(_Args...); };
873fb8a8121Smrg
874fb8a8121Smrg      template <typename... _Args>
875fb8a8121Smrg	struct __untag_result<__variant_idx_cookie(*)(_Args...)>
876fb8a8121Smrg	: false_type
877fb8a8121Smrg	{ using element_type = void(*)(_Args...); };
878fb8a8121Smrg
879fb8a8121Smrg      template <typename _Res, typename... _Args>
880fb8a8121Smrg	struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)>
881fb8a8121Smrg	: true_type
882fb8a8121Smrg	{ using element_type = _Res(*)(_Args...); };
883fb8a8121Smrg
884fb8a8121Smrg      using __result_is_deduced = __untag_result<_Tp>;
885fb8a8121Smrg
886fb8a8121Smrg      constexpr const typename __untag_result<_Tp>::element_type&
887b17d1066Smrg      _M_access() const
888b17d1066Smrg      { return _M_data; }
889b17d1066Smrg
890fb8a8121Smrg      typename __untag_result<_Tp>::element_type _M_data;
891b17d1066Smrg    };
892b17d1066Smrg
893181254a7Smrg  // Partial specialization with rank >= 1.
894181254a7Smrg  template<typename _Ret,
895181254a7Smrg	   typename _Visitor,
896181254a7Smrg	   typename... _Variants,
897181254a7Smrg	   size_t __first, size_t... __rest>
898181254a7Smrg    struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...>
899b17d1066Smrg    {
900181254a7Smrg      static constexpr size_t __index =
901181254a7Smrg	sizeof...(_Variants) - sizeof...(__rest) - 1;
902181254a7Smrg
903181254a7Smrg      using _Variant = typename _Nth_type<__index, _Variants...>::type;
904181254a7Smrg
905181254a7Smrg      static constexpr int __do_cookie =
906181254a7Smrg	_Extra_visit_slot_needed<_Ret, _Variant>::value ? 1 : 0;
907181254a7Smrg
908181254a7Smrg      using _Tp = _Ret(*)(_Visitor, _Variants...);
909181254a7Smrg
910b17d1066Smrg      template<typename... _Args>
911fb8a8121Smrg	constexpr decltype(auto)
912b17d1066Smrg	_M_access(size_t __first_index, _Args... __rest_indices) const
913181254a7Smrg        {
914181254a7Smrg	  return _M_arr[__first_index + __do_cookie]
915181254a7Smrg	    ._M_access(__rest_indices...);
916181254a7Smrg	}
917b17d1066Smrg
918181254a7Smrg      _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie];
919b17d1066Smrg    };
920b17d1066Smrg
921b17d1066Smrg  // Creates a multi-dimensional vtable recursively.
922b17d1066Smrg  //
923b17d1066Smrg  // For example,
924b17d1066Smrg  // visit([](auto, auto){},
925b17d1066Smrg  //       variant<int, char>(),  // typedef'ed as V1
926b17d1066Smrg  //       variant<float, double, long double>())  // typedef'ed as V2
927b17d1066Smrg  // will trigger instantiations of:
928fb8a8121Smrg  // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>,
929b17d1066Smrg  //                   tuple<V1&&, V2&&>, std::index_sequence<>>
930fb8a8121Smrg  //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
931b17d1066Smrg  //                     tuple<V1&&, V2&&>, std::index_sequence<0>>
932fb8a8121Smrg  //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
933b17d1066Smrg  //                       tuple<V1&&, V2&&>, std::index_sequence<0, 0>>
934fb8a8121Smrg  //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
935b17d1066Smrg  //                       tuple<V1&&, V2&&>, std::index_sequence<0, 1>>
936fb8a8121Smrg  //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
937b17d1066Smrg  //                       tuple<V1&&, V2&&>, std::index_sequence<0, 2>>
938fb8a8121Smrg  //   __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>,
939b17d1066Smrg  //                     tuple<V1&&, V2&&>, std::index_sequence<1>>
940fb8a8121Smrg  //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
941b17d1066Smrg  //                       tuple<V1&&, V2&&>, std::index_sequence<1, 0>>
942fb8a8121Smrg  //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
943b17d1066Smrg  //                       tuple<V1&&, V2&&>, std::index_sequence<1, 1>>
944fb8a8121Smrg  //     __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>,
945b17d1066Smrg  //                       tuple<V1&&, V2&&>, std::index_sequence<1, 2>>
946b17d1066Smrg  // The returned multi-dimensional vtable can be fast accessed by the visitor
947b17d1066Smrg  // using index calculation.
948fb8a8121Smrg  template<typename _Array_type, typename _Index_seq>
949b17d1066Smrg    struct __gen_vtable_impl;
950b17d1066Smrg
951181254a7Smrg  // Defines the _S_apply() member that returns a _Multi_array populated
952181254a7Smrg  // with function pointers that perform the visitation expressions e(m)
953181254a7Smrg  // for each valid pack of indexes into the variant types _Variants.
954181254a7Smrg  //
955181254a7Smrg  // This partial specialization builds up the index sequences by recursively
956181254a7Smrg  // calling _S_apply() on the next specialization of __gen_vtable_impl.
957181254a7Smrg  // The base case of the recursion defines the actual function pointers.
958fb8a8121Smrg  template<typename _Result_type, typename _Visitor, size_t... __dimensions,
959b17d1066Smrg	   typename... _Variants, size_t... __indices>
960b17d1066Smrg    struct __gen_vtable_impl<
961b17d1066Smrg	_Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>,
962fb8a8121Smrg	std::index_sequence<__indices...>>
963b17d1066Smrg    {
964b17d1066Smrg      using _Next =
965b17d1066Smrg	  remove_reference_t<typename _Nth_type<sizeof...(__indices),
966b17d1066Smrg			     _Variants...>::type>;
967b17d1066Smrg      using _Array_type =
968b17d1066Smrg	  _Multi_array<_Result_type (*)(_Visitor, _Variants...),
969b17d1066Smrg		       __dimensions...>;
970b17d1066Smrg
971b17d1066Smrg      static constexpr _Array_type
972b17d1066Smrg      _S_apply()
973b17d1066Smrg      {
974b17d1066Smrg	_Array_type __vtable{};
975b17d1066Smrg	_S_apply_all_alts(
976b17d1066Smrg	  __vtable, make_index_sequence<variant_size_v<_Next>>());
977b17d1066Smrg	return __vtable;
978b17d1066Smrg      }
979b17d1066Smrg
980b17d1066Smrg      template<size_t... __var_indices>
981b17d1066Smrg	static constexpr void
982b17d1066Smrg	_S_apply_all_alts(_Array_type& __vtable,
983b17d1066Smrg			  std::index_sequence<__var_indices...>)
984b17d1066Smrg	{
985181254a7Smrg	  if constexpr (_Extra_visit_slot_needed<_Result_type, _Next>::value)
986181254a7Smrg	    (_S_apply_single_alt<true, __var_indices>(
987181254a7Smrg	      __vtable._M_arr[__var_indices + 1],
988181254a7Smrg	      &(__vtable._M_arr[0])), ...);
989181254a7Smrg	  else
990181254a7Smrg	    (_S_apply_single_alt<false, __var_indices>(
991b17d1066Smrg	      __vtable._M_arr[__var_indices]), ...);
992b17d1066Smrg	}
993b17d1066Smrg
994181254a7Smrg      template<bool __do_cookie, size_t __index, typename _Tp>
995b17d1066Smrg	static constexpr void
996181254a7Smrg	_S_apply_single_alt(_Tp& __element, _Tp* __cookie_element = nullptr)
997b17d1066Smrg	{
998181254a7Smrg	  if constexpr (__do_cookie)
999181254a7Smrg	    {
1000b17d1066Smrg	      __element = __gen_vtable_impl<
1001181254a7Smrg		_Tp,
1002181254a7Smrg		std::index_sequence<__indices..., __index>>::_S_apply();
1003181254a7Smrg	      *__cookie_element = __gen_vtable_impl<
1004181254a7Smrg		_Tp,
1005181254a7Smrg		std::index_sequence<__indices..., variant_npos>>::_S_apply();
1006181254a7Smrg	    }
1007181254a7Smrg	  else
1008181254a7Smrg	    {
1009b1e83836Smrg	      auto __tmp_element = __gen_vtable_impl<
1010fb8a8121Smrg		remove_reference_t<decltype(__element)>,
1011b17d1066Smrg		std::index_sequence<__indices..., __index>>::_S_apply();
1012b1e83836Smrg	      static_assert(is_same_v<_Tp, decltype(__tmp_element)>,
1013b1e83836Smrg			    "std::visit requires the visitor to have the same "
1014b1e83836Smrg			    "return type for all alternatives of a variant");
1015b1e83836Smrg	      __element = __tmp_element;
1016b17d1066Smrg	    }
1017181254a7Smrg	}
1018b17d1066Smrg    };
1019b17d1066Smrg
1020181254a7Smrg  // This partial specialization is the base case for the recursion.
1021181254a7Smrg  // It populates a _Multi_array element with the address of a function
1022181254a7Smrg  // that invokes the visitor with the alternatives specified by __indices.
1023fb8a8121Smrg  template<typename _Result_type, typename _Visitor, typename... _Variants,
1024b17d1066Smrg	   size_t... __indices>
1025b17d1066Smrg    struct __gen_vtable_impl<
1026b17d1066Smrg      _Multi_array<_Result_type (*)(_Visitor, _Variants...)>,
1027fb8a8121Smrg		   std::index_sequence<__indices...>>
1028b17d1066Smrg    {
1029b17d1066Smrg      using _Array_type =
1030181254a7Smrg	  _Multi_array<_Result_type (*)(_Visitor, _Variants...)>;
1031181254a7Smrg
1032181254a7Smrg      template<size_t __index, typename _Variant>
1033181254a7Smrg	static constexpr decltype(auto)
1034181254a7Smrg	__element_by_index_or_cookie(_Variant&& __var) noexcept
1035181254a7Smrg        {
1036181254a7Smrg	  if constexpr (__index != variant_npos)
1037181254a7Smrg	    return __variant::__get<__index>(std::forward<_Variant>(__var));
1038181254a7Smrg	  else
1039181254a7Smrg	    return __variant_cookie{};
1040181254a7Smrg	}
1041181254a7Smrg
1042181254a7Smrg      static constexpr decltype(auto)
1043fb8a8121Smrg      __visit_invoke(_Visitor&& __visitor, _Variants... __vars)
1044181254a7Smrg      {
1045181254a7Smrg	if constexpr (is_same_v<_Result_type, __variant_idx_cookie>)
1046fb8a8121Smrg	  // For raw visitation using indices, pass the indices to the visitor
1047fb8a8121Smrg	  // and discard the return value:
1048fb8a8121Smrg	  std::__invoke(std::forward<_Visitor>(__visitor),
1049181254a7Smrg	      __element_by_index_or_cookie<__indices>(
1050181254a7Smrg		std::forward<_Variants>(__vars))...,
1051181254a7Smrg	      integral_constant<size_t, __indices>()...);
1052fb8a8121Smrg	else if constexpr (is_same_v<_Result_type, __variant_cookie>)
1053fb8a8121Smrg	  // For raw visitation without indices, and discard the return value:
1054fb8a8121Smrg	  std::__invoke(std::forward<_Visitor>(__visitor),
1055181254a7Smrg	      __element_by_index_or_cookie<__indices>(
1056181254a7Smrg		std::forward<_Variants>(__vars))...);
1057fb8a8121Smrg	else if constexpr (_Array_type::__result_is_deduced::value)
1058fb8a8121Smrg	  // For the usual std::visit case deduce the return value:
1059181254a7Smrg	  return std::__invoke(std::forward<_Visitor>(__visitor),
1060181254a7Smrg	      __element_by_index_or_cookie<__indices>(
1061181254a7Smrg		std::forward<_Variants>(__vars))...);
1062fb8a8121Smrg	else // for std::visit<R> use INVOKE<R>
1063fb8a8121Smrg	  return std::__invoke_r<_Result_type>(
1064fb8a8121Smrg	      std::forward<_Visitor>(__visitor),
1065fb8a8121Smrg	      __variant::__get<__indices>(std::forward<_Variants>(__vars))...);
1066b17d1066Smrg      }
1067b17d1066Smrg
1068b17d1066Smrg      static constexpr auto
1069b17d1066Smrg      _S_apply()
1070b1e83836Smrg      {
1071b1e83836Smrg	if constexpr (_Array_type::__result_is_deduced::value)
1072b1e83836Smrg	  {
1073b1e83836Smrg	    constexpr bool __visit_ret_type_mismatch =
1074b1e83836Smrg	      !is_same_v<typename _Result_type::type,
1075b1e83836Smrg			 decltype(__visit_invoke(std::declval<_Visitor>(),
1076b1e83836Smrg				    std::declval<_Variants>()...))>;
1077b1e83836Smrg	    if constexpr (__visit_ret_type_mismatch)
1078b1e83836Smrg	      {
1079b1e83836Smrg		struct __cannot_match {};
1080b1e83836Smrg		return __cannot_match{};
1081b1e83836Smrg	      }
1082b1e83836Smrg	    else
1083b1e83836Smrg	      return _Array_type{&__visit_invoke};
1084b1e83836Smrg	  }
1085b1e83836Smrg	else
1086b1e83836Smrg	  return _Array_type{&__visit_invoke};
1087b1e83836Smrg      }
1088b17d1066Smrg    };
1089b17d1066Smrg
1090fb8a8121Smrg  template<typename _Result_type, typename _Visitor, typename... _Variants>
1091b17d1066Smrg    struct __gen_vtable
1092b17d1066Smrg    {
1093b17d1066Smrg      using _Array_type =
1094181254a7Smrg	  _Multi_array<_Result_type (*)(_Visitor, _Variants...),
1095b17d1066Smrg		       variant_size_v<remove_reference_t<_Variants>>...>;
1096b17d1066Smrg
1097181254a7Smrg      static constexpr _Array_type _S_vtable
1098fb8a8121Smrg	= __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply();
1099b17d1066Smrg    };
1100b17d1066Smrg
1101b17d1066Smrg  template<size_t _Np, typename _Tp>
1102b17d1066Smrg    struct _Base_dedup : public _Tp { };
1103b17d1066Smrg
1104b17d1066Smrg  template<typename _Variant, typename __indices>
1105b17d1066Smrg    struct _Variant_hash_base;
1106b17d1066Smrg
1107b17d1066Smrg  template<typename... _Types, size_t... __indices>
1108b17d1066Smrg    struct _Variant_hash_base<variant<_Types...>,
1109b17d1066Smrg			      std::index_sequence<__indices...>>
1110b17d1066Smrg    : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { };
1111b17d1066Smrg
1112b1e83836Smrg  // Equivalent to decltype(get<_Np>(as-variant(declval<_Variant>())))
1113b1e83836Smrg  template<size_t _Np, typename _Variant,
1114b1e83836Smrg      typename _AsV = decltype(__variant::__as(std::declval<_Variant>())),
1115b1e83836Smrg      typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>>
1116b1e83836Smrg    using __get_t
1117b1e83836Smrg      = __conditional_t<is_lvalue_reference_v<_Variant>, _Tp&, _Tp&&>;
1118a448f87cSmrg
1119a448f87cSmrg  // Return type of std::visit.
1120a448f87cSmrg  template<typename _Visitor, typename... _Variants>
1121a448f87cSmrg    using __visit_result_t
1122a448f87cSmrg      = invoke_result_t<_Visitor, __get_t<0, _Variants>...>;
1123a448f87cSmrg
1124b1e83836Smrg  template<typename _Tp, typename... _Types>
1125b1e83836Smrg    constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...);
1126b1e83836Smrg
1127b1e83836Smrg  template <typename _Visitor, typename _Variant, size_t... _Idxs>
1128b1e83836Smrg    constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>)
1129b1e83836Smrg    {
1130b1e83836Smrg      return __same_types<
1131b1e83836Smrg	invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>...
1132b1e83836Smrg	>;
1133b1e83836Smrg    }
1134b1e83836Smrg
1135b17d1066Smrg} // namespace __variant
1136b17d1066Smrg} // namespace __detail
1137b17d1066Smrg
1138b17d1066Smrg  template<typename _Tp, typename... _Types>
1139a3e9eb18Smrg    constexpr bool
1140a3e9eb18Smrg    holds_alternative(const variant<_Types...>& __v) noexcept
1141b17d1066Smrg    {
1142b17d1066Smrg      static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1143fb8a8121Smrg		    "T must occur exactly once in alternatives");
1144b1e83836Smrg      return __v.index() == std::__find_uniq_type_in_pack<_Tp, _Types...>();
1145b17d1066Smrg    }
1146b17d1066Smrg
1147b17d1066Smrg  template<typename _Tp, typename... _Types>
1148b1e83836Smrg    constexpr _Tp&
1149b1e83836Smrg    get(variant<_Types...>& __v)
1150b17d1066Smrg    {
1151b17d1066Smrg      static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1152fb8a8121Smrg		    "T must occur exactly once in alternatives");
1153b1e83836Smrg      constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1154b1e83836Smrg      return std::get<__n>(__v);
1155b17d1066Smrg    }
1156b17d1066Smrg
1157b17d1066Smrg  template<typename _Tp, typename... _Types>
1158b1e83836Smrg    constexpr _Tp&&
1159b1e83836Smrg    get(variant<_Types...>&& __v)
1160b17d1066Smrg    {
1161b17d1066Smrg      static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1162fb8a8121Smrg		    "T must occur exactly once in alternatives");
1163b1e83836Smrg      constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1164b1e83836Smrg      return std::get<__n>(std::move(__v));
1165b17d1066Smrg    }
1166b17d1066Smrg
1167b17d1066Smrg  template<typename _Tp, typename... _Types>
1168b1e83836Smrg    constexpr const _Tp&
1169b1e83836Smrg    get(const variant<_Types...>& __v)
1170b17d1066Smrg    {
1171b17d1066Smrg      static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1172fb8a8121Smrg		    "T must occur exactly once in alternatives");
1173b1e83836Smrg      constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1174b1e83836Smrg      return std::get<__n>(__v);
1175b17d1066Smrg    }
1176b17d1066Smrg
1177b17d1066Smrg  template<typename _Tp, typename... _Types>
1178b1e83836Smrg    constexpr const _Tp&&
1179b1e83836Smrg    get(const variant<_Types...>&& __v)
1180b17d1066Smrg    {
1181b17d1066Smrg      static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1182fb8a8121Smrg		    "T must occur exactly once in alternatives");
1183b1e83836Smrg      constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1184b1e83836Smrg      return std::get<__n>(std::move(__v));
1185b17d1066Smrg    }
1186b17d1066Smrg
1187b17d1066Smrg  template<size_t _Np, typename... _Types>
1188a3e9eb18Smrg    constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>>
1189b17d1066Smrg    get_if(variant<_Types...>* __ptr) noexcept
1190b17d1066Smrg    {
1191b17d1066Smrg      using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1192b17d1066Smrg      static_assert(_Np < sizeof...(_Types),
1193fb8a8121Smrg		    "The index must be in [0, number of alternatives)");
1194fb8a8121Smrg      static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void");
1195b17d1066Smrg      if (__ptr && __ptr->index() == _Np)
1196181254a7Smrg	return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
1197b17d1066Smrg      return nullptr;
1198b17d1066Smrg    }
1199b17d1066Smrg
1200b17d1066Smrg  template<size_t _Np, typename... _Types>
1201a3e9eb18Smrg    constexpr
1202b17d1066Smrg    add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>>
1203b17d1066Smrg    get_if(const variant<_Types...>* __ptr) noexcept
1204b17d1066Smrg    {
1205b17d1066Smrg      using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>;
1206b17d1066Smrg      static_assert(_Np < sizeof...(_Types),
1207fb8a8121Smrg		    "The index must be in [0, number of alternatives)");
1208fb8a8121Smrg      static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void");
1209b17d1066Smrg      if (__ptr && __ptr->index() == _Np)
1210181254a7Smrg	return std::addressof(__detail::__variant::__get<_Np>(*__ptr));
1211b17d1066Smrg      return nullptr;
1212b17d1066Smrg    }
1213b17d1066Smrg
1214b17d1066Smrg  template<typename _Tp, typename... _Types>
1215a3e9eb18Smrg    constexpr add_pointer_t<_Tp>
1216b17d1066Smrg    get_if(variant<_Types...>* __ptr) noexcept
1217b17d1066Smrg    {
1218b17d1066Smrg      static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1219fb8a8121Smrg		    "T must occur exactly once in alternatives");
1220fb8a8121Smrg      static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1221b1e83836Smrg      constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1222b1e83836Smrg      return std::get_if<__n>(__ptr);
1223b17d1066Smrg    }
1224b17d1066Smrg
1225b17d1066Smrg  template<typename _Tp, typename... _Types>
1226a3e9eb18Smrg    constexpr add_pointer_t<const _Tp>
1227181254a7Smrg    get_if(const variant<_Types...>* __ptr) noexcept
1228b17d1066Smrg    {
1229b17d1066Smrg      static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>,
1230fb8a8121Smrg		    "T must occur exactly once in alternatives");
1231fb8a8121Smrg      static_assert(!is_void_v<_Tp>, "_Tp must not be void");
1232b1e83836Smrg      constexpr size_t __n = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1233b1e83836Smrg      return std::get_if<__n>(__ptr);
1234b17d1066Smrg    }
1235b17d1066Smrg
1236b17d1066Smrg  struct monostate { };
1237b17d1066Smrg
1238b17d1066Smrg#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
1239b17d1066Smrg  template<typename... _Types> \
1240b17d1066Smrg    constexpr bool operator __OP(const variant<_Types...>& __lhs, \
1241b17d1066Smrg				 const variant<_Types...>& __rhs) \
1242b17d1066Smrg    { \
1243181254a7Smrg      bool __ret = true; \
1244fb8a8121Smrg      __detail::__variant::__raw_idx_visit( \
1245fb8a8121Smrg        [&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \
1246181254a7Smrg        { \
1247181254a7Smrg	  if constexpr (__rhs_index != variant_npos) \
1248181254a7Smrg	    { \
1249181254a7Smrg	      if (__lhs.index() == __rhs_index) \
1250181254a7Smrg	        { \
1251181254a7Smrg		  auto& __this_mem = std::get<__rhs_index>(__lhs);	\
1252181254a7Smrg                  __ret = __this_mem __OP __rhs_mem; \
1253181254a7Smrg                } \
1254181254a7Smrg	      else \
1255181254a7Smrg		__ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
1256181254a7Smrg            } \
1257181254a7Smrg          else \
1258181254a7Smrg            __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
1259181254a7Smrg	}, __rhs); \
1260181254a7Smrg      return __ret; \
1261fb8a8121Smrg    }
1262b17d1066Smrg
1263b17d1066Smrg  _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
1264b17d1066Smrg  _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
1265b17d1066Smrg  _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
1266b17d1066Smrg  _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
1267b17d1066Smrg  _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
1268b17d1066Smrg  _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
1269b17d1066Smrg
1270b17d1066Smrg#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1271b17d1066Smrg
1272fb8a8121Smrg  constexpr bool operator==(monostate, monostate) noexcept { return true; }
1273fb8a8121Smrg
1274fb8a8121Smrg#ifdef __cpp_lib_three_way_comparison
1275fb8a8121Smrg  template<typename... _Types>
1276fb8a8121Smrg    requires (three_way_comparable<_Types> && ...)
1277fb8a8121Smrg    constexpr
1278fb8a8121Smrg    common_comparison_category_t<compare_three_way_result_t<_Types>...>
1279fb8a8121Smrg    operator<=>(const variant<_Types...>& __v, const variant<_Types...>& __w)
1280fb8a8121Smrg    {
1281fb8a8121Smrg      common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret
1282fb8a8121Smrg	= strong_ordering::equal;
1283fb8a8121Smrg
1284fb8a8121Smrg      __detail::__variant::__raw_idx_visit(
1285fb8a8121Smrg	[&__ret, &__v] (auto&& __w_mem, auto __w_index) mutable
1286fb8a8121Smrg	{
1287fb8a8121Smrg	  if constexpr (__w_index != variant_npos)
1288fb8a8121Smrg	    {
1289fb8a8121Smrg	      if (__v.index() == __w_index)
1290fb8a8121Smrg		{
1291fb8a8121Smrg		  auto& __this_mem = std::get<__w_index>(__v);
1292fb8a8121Smrg		  __ret = __this_mem <=> __w_mem;
1293fb8a8121Smrg		  return;
1294fb8a8121Smrg		}
1295fb8a8121Smrg	    }
1296fb8a8121Smrg	  __ret = (__v.index() + 1) <=> (__w_index + 1);
1297fb8a8121Smrg	}, __w);
1298fb8a8121Smrg      return __ret;
1299fb8a8121Smrg    }
1300fb8a8121Smrg
1301fb8a8121Smrg  constexpr strong_ordering
1302fb8a8121Smrg  operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; }
1303fb8a8121Smrg#else
1304fb8a8121Smrg  constexpr bool operator!=(monostate, monostate) noexcept { return false; }
1305fb8a8121Smrg  constexpr bool operator<(monostate, monostate) noexcept { return false; }
1306fb8a8121Smrg  constexpr bool operator>(monostate, monostate) noexcept { return false; }
1307fb8a8121Smrg  constexpr bool operator<=(monostate, monostate) noexcept { return true; }
1308fb8a8121Smrg  constexpr bool operator>=(monostate, monostate) noexcept { return true; }
1309fb8a8121Smrg#endif
1310fb8a8121Smrg
1311b17d1066Smrg  template<typename _Visitor, typename... _Variants>
1312a448f87cSmrg    constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1313a448f87cSmrg    visit(_Visitor&&, _Variants&&...);
1314b17d1066Smrg
1315b17d1066Smrg  template<typename... _Types>
1316b1e83836Smrg    _GLIBCXX20_CONSTEXPR
1317b17d1066Smrg    inline enable_if_t<(is_move_constructible_v<_Types> && ...)
1318b17d1066Smrg			&& (is_swappable_v<_Types> && ...)>
1319b17d1066Smrg    swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs)
1320b17d1066Smrg    noexcept(noexcept(__lhs.swap(__rhs)))
1321b17d1066Smrg    { __lhs.swap(__rhs); }
1322b17d1066Smrg
1323b17d1066Smrg  template<typename... _Types>
1324b17d1066Smrg    enable_if_t<!((is_move_constructible_v<_Types> && ...)
1325b17d1066Smrg		   && (is_swappable_v<_Types> && ...))>
1326b17d1066Smrg    swap(variant<_Types...>&, variant<_Types...>&) = delete;
1327b17d1066Smrg
1328b17d1066Smrg  class bad_variant_access : public exception
1329b17d1066Smrg  {
1330b17d1066Smrg  public:
1331fb8a8121Smrg    bad_variant_access() noexcept { }
1332fb8a8121Smrg
1333b17d1066Smrg    const char* what() const noexcept override
1334b17d1066Smrg    { return _M_reason; }
1335b17d1066Smrg
1336b17d1066Smrg  private:
1337fb8a8121Smrg    bad_variant_access(const char* __reason) noexcept : _M_reason(__reason) { }
1338b17d1066Smrg
1339fb8a8121Smrg    // Must point to a string with static storage duration:
1340fb8a8121Smrg    const char* _M_reason = "bad variant access";
1341b17d1066Smrg
1342b17d1066Smrg    friend void __throw_bad_variant_access(const char* __what);
1343b17d1066Smrg  };
1344b17d1066Smrg
1345fb8a8121Smrg  // Must only be called with a string literal
1346b17d1066Smrg  inline void
1347b17d1066Smrg  __throw_bad_variant_access(const char* __what)
1348b17d1066Smrg  { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
1349b17d1066Smrg
1350fb8a8121Smrg  inline void
1351fb8a8121Smrg  __throw_bad_variant_access(bool __valueless)
1352fb8a8121Smrg  {
1353fb8a8121Smrg    if (__valueless) [[__unlikely__]]
1354fb8a8121Smrg      __throw_bad_variant_access("std::get: variant is valueless");
1355fb8a8121Smrg    else
1356fb8a8121Smrg      __throw_bad_variant_access("std::get: wrong index for variant");
1357fb8a8121Smrg  }
1358fb8a8121Smrg
1359b17d1066Smrg  template<typename... _Types>
1360b17d1066Smrg    class variant
1361b17d1066Smrg    : private __detail::__variant::_Variant_base<_Types...>,
1362b17d1066Smrg      private _Enable_default_constructor<
1363a3e9eb18Smrg	__detail::__variant::_Traits<_Types...>::_S_default_ctor,
1364a3e9eb18Smrg	  variant<_Types...>>,
1365b17d1066Smrg      private _Enable_copy_move<
1366a3e9eb18Smrg	__detail::__variant::_Traits<_Types...>::_S_copy_ctor,
1367a3e9eb18Smrg	__detail::__variant::_Traits<_Types...>::_S_copy_assign,
1368a3e9eb18Smrg	__detail::__variant::_Traits<_Types...>::_S_move_ctor,
1369a3e9eb18Smrg	__detail::__variant::_Traits<_Types...>::_S_move_assign,
1370b17d1066Smrg	variant<_Types...>>
1371b17d1066Smrg    {
1372b17d1066Smrg    private:
1373181254a7Smrg      template <typename... _UTypes, typename _Tp>
1374b1e83836Smrg	friend _GLIBCXX20_CONSTEXPR decltype(auto)
1375b1e83836Smrg	__variant_cast(_Tp&&);
1376181254a7Smrg
1377b17d1066Smrg      static_assert(sizeof...(_Types) > 0,
1378b17d1066Smrg		    "variant must have at least one alternative");
1379b17d1066Smrg      static_assert(!(std::is_reference_v<_Types> || ...),
1380b17d1066Smrg		    "variant must have no reference alternative");
1381b17d1066Smrg      static_assert(!(std::is_void_v<_Types> || ...),
1382b17d1066Smrg		    "variant must have no void alternative");
1383b17d1066Smrg
1384b17d1066Smrg      using _Base = __detail::__variant::_Variant_base<_Types...>;
1385b17d1066Smrg      using _Default_ctor_enabler =
1386b17d1066Smrg	_Enable_default_constructor<
1387a3e9eb18Smrg	  __detail::__variant::_Traits<_Types...>::_S_default_ctor,
1388a3e9eb18Smrg	    variant<_Types...>>;
1389b17d1066Smrg
1390b17d1066Smrg      template<typename _Tp>
1391181254a7Smrg	static constexpr bool __not_self
1392181254a7Smrg	  = !is_same_v<__remove_cvref_t<_Tp>, variant>;
1393181254a7Smrg
1394181254a7Smrg      template<typename _Tp>
1395b17d1066Smrg	static constexpr bool
1396b17d1066Smrg	__exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>;
1397b17d1066Smrg
1398b17d1066Smrg      template<typename _Tp>
1399fb8a8121Smrg	static constexpr size_t __accepted_index
1400fb8a8121Smrg	  = __detail::__variant::__accepted_index<_Tp, variant>::value;
1401b17d1066Smrg
1402181254a7Smrg      template<size_t _Np, typename = enable_if_t<(_Np < sizeof...(_Types))>>
1403b1e83836Smrg	using __to_type = typename _Nth_type<_Np, _Types...>::type;
1404b17d1066Smrg
1405181254a7Smrg      template<typename _Tp, typename = enable_if_t<__not_self<_Tp>>>
1406b17d1066Smrg	using __accepted_type = __to_type<__accepted_index<_Tp>>;
1407b17d1066Smrg
1408b17d1066Smrg      template<typename _Tp>
1409b1e83836Smrg	static constexpr size_t __index_of
1410b1e83836Smrg	  = std::__find_uniq_type_in_pack<_Tp, _Types...>();
1411b17d1066Smrg
1412a3e9eb18Smrg      using _Traits = __detail::__variant::_Traits<_Types...>;
1413a3e9eb18Smrg
1414a3e9eb18Smrg      template<typename _Tp>
1415a3e9eb18Smrg	struct __is_in_place_tag : false_type { };
1416a3e9eb18Smrg      template<typename _Tp>
1417a3e9eb18Smrg	struct __is_in_place_tag<in_place_type_t<_Tp>> : true_type { };
1418a3e9eb18Smrg      template<size_t _Np>
1419a3e9eb18Smrg	struct __is_in_place_tag<in_place_index_t<_Np>> : true_type { };
1420a3e9eb18Smrg
1421a3e9eb18Smrg      template<typename _Tp>
1422a3e9eb18Smrg	static constexpr bool __not_in_place_tag
1423181254a7Smrg	  = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value;
1424a3e9eb18Smrg
1425b17d1066Smrg    public:
1426a3e9eb18Smrg      variant() = default;
1427a3e9eb18Smrg      variant(const variant& __rhs) = default;
1428a3e9eb18Smrg      variant(variant&&) = default;
1429a3e9eb18Smrg      variant& operator=(const variant&) = default;
1430a3e9eb18Smrg      variant& operator=(variant&&) = default;
1431b1e83836Smrg      _GLIBCXX20_CONSTEXPR ~variant() = default;
1432b17d1066Smrg
1433b17d1066Smrg      template<typename _Tp,
1434181254a7Smrg	       typename = enable_if_t<sizeof...(_Types) != 0>,
1435a3e9eb18Smrg	       typename = enable_if_t<__not_in_place_tag<_Tp>>,
1436181254a7Smrg	       typename _Tj = __accepted_type<_Tp&&>,
1437181254a7Smrg	       typename = enable_if_t<__exactly_once<_Tj>
1438181254a7Smrg				      && is_constructible_v<_Tj, _Tp>>>
1439b17d1066Smrg	constexpr
1440b17d1066Smrg	variant(_Tp&& __t)
1441181254a7Smrg	noexcept(is_nothrow_constructible_v<_Tj, _Tp>)
1442fb8a8121Smrg	: variant(in_place_index<__accepted_index<_Tp>>,
1443a3e9eb18Smrg		  std::forward<_Tp>(__t))
1444181254a7Smrg	{ }
1445b17d1066Smrg
1446b17d1066Smrg      template<typename _Tp, typename... _Args,
1447b17d1066Smrg	       typename = enable_if_t<__exactly_once<_Tp>
1448181254a7Smrg				      && is_constructible_v<_Tp, _Args...>>>
1449b17d1066Smrg	constexpr explicit
1450b17d1066Smrg	variant(in_place_type_t<_Tp>, _Args&&... __args)
1451a3e9eb18Smrg	: variant(in_place_index<__index_of<_Tp>>,
1452a3e9eb18Smrg		  std::forward<_Args>(__args)...)
1453181254a7Smrg	{ }
1454b17d1066Smrg
1455b17d1066Smrg      template<typename _Tp, typename _Up, typename... _Args,
1456b17d1066Smrg	       typename = enable_if_t<__exactly_once<_Tp>
1457181254a7Smrg				      && is_constructible_v<_Tp,
1458181254a7Smrg					   initializer_list<_Up>&, _Args...>>>
1459b17d1066Smrg	constexpr explicit
1460b17d1066Smrg	variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
1461b17d1066Smrg		_Args&&... __args)
1462b17d1066Smrg	: variant(in_place_index<__index_of<_Tp>>, __il,
1463b17d1066Smrg		  std::forward<_Args>(__args)...)
1464181254a7Smrg	{ }
1465b17d1066Smrg
1466b17d1066Smrg      template<size_t _Np, typename... _Args,
1467181254a7Smrg	       typename _Tp = __to_type<_Np>,
1468181254a7Smrg	       typename = enable_if_t<is_constructible_v<_Tp, _Args...>>>
1469b17d1066Smrg	constexpr explicit
1470b17d1066Smrg	variant(in_place_index_t<_Np>, _Args&&... __args)
1471b17d1066Smrg	: _Base(in_place_index<_Np>, std::forward<_Args>(__args)...),
1472b17d1066Smrg	_Default_ctor_enabler(_Enable_default_constructor_tag{})
1473181254a7Smrg	{ }
1474b17d1066Smrg
1475b17d1066Smrg      template<size_t _Np, typename _Up, typename... _Args,
1476181254a7Smrg	       typename _Tp = __to_type<_Np>,
1477181254a7Smrg	       typename = enable_if_t<is_constructible_v<_Tp,
1478181254a7Smrg							 initializer_list<_Up>&,
1479181254a7Smrg							 _Args...>>>
1480b17d1066Smrg	constexpr explicit
1481b17d1066Smrg	variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
1482b17d1066Smrg		_Args&&... __args)
1483b17d1066Smrg	: _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...),
1484b17d1066Smrg	_Default_ctor_enabler(_Enable_default_constructor_tag{})
1485181254a7Smrg	{ }
1486b17d1066Smrg
1487b17d1066Smrg      template<typename _Tp>
1488b1e83836Smrg	_GLIBCXX20_CONSTEXPR
1489b17d1066Smrg	enable_if_t<__exactly_once<__accepted_type<_Tp&&>>
1490181254a7Smrg		    && is_constructible_v<__accepted_type<_Tp&&>, _Tp>
1491181254a7Smrg		    && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>,
1492181254a7Smrg		    variant&>
1493b17d1066Smrg	operator=(_Tp&& __rhs)
1494181254a7Smrg	noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp>
1495181254a7Smrg		 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>)
1496b17d1066Smrg	{
1497fb8a8121Smrg	  constexpr auto __index = __accepted_index<_Tp>;
1498b17d1066Smrg	  if (index() == __index)
1499b17d1066Smrg	    std::get<__index>(*this) = std::forward<_Tp>(__rhs);
1500b17d1066Smrg	  else
1501181254a7Smrg	    {
1502181254a7Smrg	      using _Tj = __accepted_type<_Tp&&>;
1503181254a7Smrg	      if constexpr (is_nothrow_constructible_v<_Tj, _Tp>
1504181254a7Smrg			    || !is_nothrow_move_constructible_v<_Tj>)
1505b17d1066Smrg		this->emplace<__index>(std::forward<_Tp>(__rhs));
1506181254a7Smrg	      else
1507b1e83836Smrg		// _GLIBCXX_RESOLVE_LIB_DEFECTS
1508b1e83836Smrg		// 3585. converting assignment with immovable alternative
1509b1e83836Smrg		this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs)));
1510181254a7Smrg	    }
1511b17d1066Smrg	  return *this;
1512b17d1066Smrg	}
1513b17d1066Smrg
1514b17d1066Smrg      template<typename _Tp, typename... _Args>
1515b1e83836Smrg	_GLIBCXX20_CONSTEXPR
1516b17d1066Smrg	enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>,
1517b17d1066Smrg		    _Tp&>
1518b17d1066Smrg	emplace(_Args&&... __args)
1519b17d1066Smrg	{
1520181254a7Smrg	  constexpr size_t __index = __index_of<_Tp>;
1521181254a7Smrg	  return this->emplace<__index>(std::forward<_Args>(__args)...);
1522b17d1066Smrg	}
1523b17d1066Smrg
1524b17d1066Smrg      template<typename _Tp, typename _Up, typename... _Args>
1525b1e83836Smrg	_GLIBCXX20_CONSTEXPR
1526b17d1066Smrg	enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>
1527b17d1066Smrg		    && __exactly_once<_Tp>,
1528b17d1066Smrg		    _Tp&>
1529b17d1066Smrg	emplace(initializer_list<_Up> __il, _Args&&... __args)
1530b17d1066Smrg	{
1531181254a7Smrg	  constexpr size_t __index = __index_of<_Tp>;
1532181254a7Smrg	  return this->emplace<__index>(__il, std::forward<_Args>(__args)...);
1533b17d1066Smrg	}
1534b17d1066Smrg
1535b17d1066Smrg      template<size_t _Np, typename... _Args>
1536b1e83836Smrg	_GLIBCXX20_CONSTEXPR
1537b1e83836Smrg	enable_if_t<is_constructible_v<__to_type<_Np>, _Args...>,
1538b1e83836Smrg		    __to_type<_Np>&>
1539b17d1066Smrg	emplace(_Args&&... __args)
1540b17d1066Smrg	{
1541b1e83836Smrg	  namespace __variant = std::__detail::__variant;
1542b1e83836Smrg	  using type = typename _Nth_type<_Np, _Types...>::type;
1543181254a7Smrg	  // Provide the strong exception-safety guarantee when possible,
1544181254a7Smrg	  // to avoid becoming valueless.
1545181254a7Smrg	  if constexpr (is_nothrow_constructible_v<type, _Args...>)
1546181254a7Smrg	    {
1547b1e83836Smrg	      __variant::__emplace<_Np>(*this, std::forward<_Args>(__args)...);
1548181254a7Smrg	    }
1549181254a7Smrg	  else if constexpr (is_scalar_v<type>)
1550181254a7Smrg	    {
1551181254a7Smrg	      // This might invoke a potentially-throwing conversion operator:
1552181254a7Smrg	      const type __tmp(std::forward<_Args>(__args)...);
1553b1e83836Smrg	      // But this won't throw:
1554b1e83836Smrg	      __variant::__emplace<_Np>(*this, __tmp);
1555181254a7Smrg	    }
1556b1e83836Smrg	  else if constexpr (__variant::_Never_valueless_alt<type>()
1557181254a7Smrg	      && _Traits::_S_move_assign)
1558181254a7Smrg	    {
1559181254a7Smrg	      // This construction might throw:
1560181254a7Smrg	      variant __tmp(in_place_index<_Np>,
1561181254a7Smrg			    std::forward<_Args>(__args)...);
1562181254a7Smrg	      // But _Never_valueless_alt<type> means this won't:
1563181254a7Smrg	      *this = std::move(__tmp);
1564181254a7Smrg	    }
1565181254a7Smrg	  else
1566181254a7Smrg	    {
1567181254a7Smrg	      // This case only provides the basic exception-safety guarantee,
1568181254a7Smrg	      // i.e. the variant can become valueless.
1569b1e83836Smrg	      __variant::__emplace<_Np>(*this, std::forward<_Args>(__args)...);
1570181254a7Smrg	    }
1571b17d1066Smrg	  return std::get<_Np>(*this);
1572b17d1066Smrg	}
1573b17d1066Smrg
1574b17d1066Smrg      template<size_t _Np, typename _Up, typename... _Args>
1575b1e83836Smrg	_GLIBCXX20_CONSTEXPR
1576b1e83836Smrg	enable_if_t<is_constructible_v<__to_type<_Np>,
1577b17d1066Smrg				       initializer_list<_Up>&, _Args...>,
1578b1e83836Smrg		    __to_type<_Np>&>
1579b17d1066Smrg	emplace(initializer_list<_Up> __il, _Args&&... __args)
1580b17d1066Smrg	{
1581b1e83836Smrg	  namespace __variant = std::__detail::__variant;
1582b1e83836Smrg	  using type = typename _Nth_type<_Np, _Types...>::type;
1583181254a7Smrg	  // Provide the strong exception-safety guarantee when possible,
1584181254a7Smrg	  // to avoid becoming valueless.
1585181254a7Smrg	  if constexpr (is_nothrow_constructible_v<type,
1586181254a7Smrg						   initializer_list<_Up>&,
1587181254a7Smrg						   _Args...>)
1588181254a7Smrg	    {
1589b1e83836Smrg	      __variant::__emplace<_Np>(*this, __il,
1590181254a7Smrg					std::forward<_Args>(__args)...);
1591181254a7Smrg	    }
1592b1e83836Smrg	  else if constexpr (__variant::_Never_valueless_alt<type>()
1593181254a7Smrg	      && _Traits::_S_move_assign)
1594181254a7Smrg	    {
1595181254a7Smrg	      // This construction might throw:
1596181254a7Smrg	      variant __tmp(in_place_index<_Np>, __il,
1597181254a7Smrg			    std::forward<_Args>(__args)...);
1598181254a7Smrg	      // But _Never_valueless_alt<type> means this won't:
1599181254a7Smrg	      *this = std::move(__tmp);
1600181254a7Smrg	    }
1601181254a7Smrg	  else
1602181254a7Smrg	    {
1603181254a7Smrg	      // This case only provides the basic exception-safety guarantee,
1604181254a7Smrg	      // i.e. the variant can become valueless.
1605b1e83836Smrg	      __variant::__emplace<_Np>(*this, __il,
1606b17d1066Smrg					std::forward<_Args>(__args)...);
1607b17d1066Smrg	    }
1608b17d1066Smrg	  return std::get<_Np>(*this);
1609b17d1066Smrg	}
1610b17d1066Smrg
1611b1e83836Smrg      template<size_t _Np, typename... _Args>
1612b1e83836Smrg	enable_if_t<!(_Np < sizeof...(_Types))> emplace(_Args&&...) = delete;
1613b1e83836Smrg
1614b1e83836Smrg      template<typename _Tp, typename... _Args>
1615b1e83836Smrg	enable_if_t<!__exactly_once<_Tp>> emplace(_Args&&...) = delete;
1616b1e83836Smrg
1617b17d1066Smrg      constexpr bool valueless_by_exception() const noexcept
1618b17d1066Smrg      { return !this->_M_valid(); }
1619b17d1066Smrg
1620b17d1066Smrg      constexpr size_t index() const noexcept
1621b17d1066Smrg      {
1622fb8a8121Smrg	using __index_type = typename _Base::__index_type;
1623fb8a8121Smrg	if constexpr (__detail::__variant::__never_valueless<_Types...>())
1624b17d1066Smrg	  return this->_M_index;
1625fb8a8121Smrg	else if constexpr (sizeof...(_Types) <= __index_type(-1) / 2)
1626fb8a8121Smrg	  return make_signed_t<__index_type>(this->_M_index);
1627fb8a8121Smrg	else
1628fb8a8121Smrg	  return size_t(__index_type(this->_M_index + 1)) - 1;
1629b17d1066Smrg      }
1630b17d1066Smrg
1631b1e83836Smrg      _GLIBCXX20_CONSTEXPR
1632b17d1066Smrg      void
1633b17d1066Smrg      swap(variant& __rhs)
1634b17d1066Smrg      noexcept((__is_nothrow_swappable<_Types>::value && ...)
1635b17d1066Smrg	       && is_nothrow_move_constructible_v<variant>)
1636b17d1066Smrg      {
1637b1e83836Smrg	static_assert((is_move_constructible_v<_Types> && ...));
1638b1e83836Smrg
1639b1e83836Smrg	// Handle this here to simplify the visitation.
1640b1e83836Smrg	if (__rhs.valueless_by_exception()) [[__unlikely__]]
1641b1e83836Smrg	  {
1642b1e83836Smrg	    if (!this->valueless_by_exception()) [[__likely__]]
1643b1e83836Smrg	      __rhs.swap(*this);
1644b1e83836Smrg	    return;
1645b1e83836Smrg	  }
1646b1e83836Smrg
1647b1e83836Smrg	namespace __variant = __detail::__variant;
1648b1e83836Smrg
1649b1e83836Smrg	__variant::__raw_idx_visit(
1650fb8a8121Smrg	  [this, &__rhs](auto&& __rhs_mem, auto __rhs_index) mutable
1651b17d1066Smrg	  {
1652b1e83836Smrg	    constexpr size_t __j = __rhs_index;
1653b1e83836Smrg	    if constexpr (__j != variant_npos)
1654b17d1066Smrg	      {
1655b1e83836Smrg		if (this->index() == __j)
1656b17d1066Smrg		  {
1657181254a7Smrg		    using std::swap;
1658b1e83836Smrg		    swap(std::get<__j>(*this), __rhs_mem);
1659b17d1066Smrg		  }
1660b17d1066Smrg		else
1661b17d1066Smrg		  {
1662181254a7Smrg		    auto __tmp(std::move(__rhs_mem));
1663b1e83836Smrg
1664b1e83836Smrg		    if constexpr (_Traits::_S_trivial_move_assign)
1665181254a7Smrg		      __rhs = std::move(*this);
1666181254a7Smrg		    else
1667b1e83836Smrg		      __variant::__raw_idx_visit(
1668b1e83836Smrg			[&__rhs](auto&& __this_mem, auto __this_index) mutable
1669181254a7Smrg			{
1670b1e83836Smrg			  constexpr size_t __k = __this_index;
1671b1e83836Smrg			  if constexpr (__k != variant_npos)
1672b1e83836Smrg			    __variant::__emplace<__k>(__rhs,
1673b1e83836Smrg						      std::move(__this_mem));
1674b1e83836Smrg			}, *this);
1675b1e83836Smrg
1676b1e83836Smrg		    __variant::__emplace<__j>(*this, std::move(__tmp));
1677181254a7Smrg		  }
1678181254a7Smrg	      }
1679181254a7Smrg	  }, __rhs);
1680b17d1066Smrg      }
1681b17d1066Smrg
1682181254a7Smrg#if defined(__clang__) && __clang_major__ <= 7
1683b17d1066Smrg    public:
1684b17d1066Smrg      using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852
1685b17d1066Smrg#endif
1686b17d1066Smrg
1687b1e83836Smrg    private:
1688b17d1066Smrg      template<size_t _Np, typename _Vp>
1689181254a7Smrg	friend constexpr decltype(auto)
1690181254a7Smrg	__detail::__variant::__get(_Vp&& __v) noexcept;
1691b17d1066Smrg
1692b17d1066Smrg#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
1693b17d1066Smrg      template<typename... _Tp> \
1694b17d1066Smrg	friend constexpr bool \
1695b17d1066Smrg	operator __OP(const variant<_Tp...>& __lhs, \
1696b17d1066Smrg		      const variant<_Tp...>& __rhs);
1697b17d1066Smrg
1698b17d1066Smrg      _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
1699b17d1066Smrg      _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
1700b17d1066Smrg      _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
1701b17d1066Smrg      _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
1702b17d1066Smrg      _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
1703b17d1066Smrg      _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
1704b17d1066Smrg
1705b17d1066Smrg#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
1706b17d1066Smrg    };
1707b17d1066Smrg
1708b17d1066Smrg  template<size_t _Np, typename... _Types>
1709b17d1066Smrg    constexpr variant_alternative_t<_Np, variant<_Types...>>&
1710b17d1066Smrg    get(variant<_Types...>& __v)
1711b17d1066Smrg    {
1712b17d1066Smrg      static_assert(_Np < sizeof...(_Types),
1713fb8a8121Smrg		    "The index must be in [0, number of alternatives)");
1714b17d1066Smrg      if (__v.index() != _Np)
1715fb8a8121Smrg	__throw_bad_variant_access(__v.valueless_by_exception());
1716b17d1066Smrg      return __detail::__variant::__get<_Np>(__v);
1717b17d1066Smrg    }
1718b17d1066Smrg
1719b17d1066Smrg  template<size_t _Np, typename... _Types>
1720b17d1066Smrg    constexpr variant_alternative_t<_Np, variant<_Types...>>&&
1721b17d1066Smrg    get(variant<_Types...>&& __v)
1722b17d1066Smrg    {
1723b17d1066Smrg      static_assert(_Np < sizeof...(_Types),
1724fb8a8121Smrg		    "The index must be in [0, number of alternatives)");
1725b17d1066Smrg      if (__v.index() != _Np)
1726fb8a8121Smrg	__throw_bad_variant_access(__v.valueless_by_exception());
1727b17d1066Smrg      return __detail::__variant::__get<_Np>(std::move(__v));
1728b17d1066Smrg    }
1729b17d1066Smrg
1730b17d1066Smrg  template<size_t _Np, typename... _Types>
1731b17d1066Smrg    constexpr const variant_alternative_t<_Np, variant<_Types...>>&
1732b17d1066Smrg    get(const variant<_Types...>& __v)
1733b17d1066Smrg    {
1734b17d1066Smrg      static_assert(_Np < sizeof...(_Types),
1735fb8a8121Smrg		    "The index must be in [0, number of alternatives)");
1736b17d1066Smrg      if (__v.index() != _Np)
1737fb8a8121Smrg	__throw_bad_variant_access(__v.valueless_by_exception());
1738b17d1066Smrg      return __detail::__variant::__get<_Np>(__v);
1739b17d1066Smrg    }
1740b17d1066Smrg
1741b17d1066Smrg  template<size_t _Np, typename... _Types>
1742b17d1066Smrg    constexpr const variant_alternative_t<_Np, variant<_Types...>>&&
1743b17d1066Smrg    get(const variant<_Types...>&& __v)
1744b17d1066Smrg    {
1745b17d1066Smrg      static_assert(_Np < sizeof...(_Types),
1746fb8a8121Smrg		    "The index must be in [0, number of alternatives)");
1747b17d1066Smrg      if (__v.index() != _Np)
1748fb8a8121Smrg	__throw_bad_variant_access(__v.valueless_by_exception());
1749b17d1066Smrg      return __detail::__variant::__get<_Np>(std::move(__v));
1750b17d1066Smrg    }
1751b17d1066Smrg
1752b1e83836Smrg  /// @cond undocumented
1753fb8a8121Smrg  template<typename _Result_type, typename _Visitor, typename... _Variants>
1754181254a7Smrg    constexpr decltype(auto)
1755181254a7Smrg    __do_visit(_Visitor&& __visitor, _Variants&&... __variants)
1756181254a7Smrg    {
1757b1e83836Smrg      // Get the silly case of visiting no variants out of the way first.
1758b1e83836Smrg      if constexpr (sizeof...(_Variants) == 0)
1759b1e83836Smrg	{
1760b1e83836Smrg	  if constexpr (is_void_v<_Result_type>)
1761b1e83836Smrg	    return (void) std::forward<_Visitor>(__visitor)();
1762b1e83836Smrg	  else
1763b1e83836Smrg	    return std::forward<_Visitor>(__visitor)();
1764b1e83836Smrg	}
1765b1e83836Smrg      else
1766b1e83836Smrg	{
1767b1e83836Smrg	  constexpr size_t __max = 11; // "These go to eleven."
1768b1e83836Smrg
1769b1e83836Smrg	  // The type of the first variant in the pack.
1770b1e83836Smrg	  using _V0 = typename _Nth_type<0, _Variants...>::type;
1771b1e83836Smrg	  // The number of alternatives in that first variant.
1772b1e83836Smrg	  constexpr auto __n = variant_size_v<remove_reference_t<_V0>>;
1773b1e83836Smrg
1774b1e83836Smrg	  if constexpr (sizeof...(_Variants) > 1 || __n > __max)
1775b1e83836Smrg	    {
1776b1e83836Smrg	      // Use a jump table for the general case.
1777181254a7Smrg	      constexpr auto& __vtable = __detail::__variant::__gen_vtable<
1778181254a7Smrg		_Result_type, _Visitor&&, _Variants&&...>::_S_vtable;
1779181254a7Smrg
1780181254a7Smrg	      auto __func_ptr = __vtable._M_access(__variants.index()...);
1781181254a7Smrg	      return (*__func_ptr)(std::forward<_Visitor>(__visitor),
1782181254a7Smrg				   std::forward<_Variants>(__variants)...);
1783181254a7Smrg	    }
1784b1e83836Smrg	  else // We have a single variant with a small number of alternatives.
1785b1e83836Smrg	    {
1786b1e83836Smrg	      // A name for the first variant in the pack.
1787b1e83836Smrg	      _V0& __v0
1788b1e83836Smrg		= [](_V0& __v, ...) -> _V0& { return __v; }(__variants...);
1789b1e83836Smrg
1790b1e83836Smrg	      using __detail::__variant::_Multi_array;
1791b1e83836Smrg	      using __detail::__variant::__gen_vtable_impl;
1792b1e83836Smrg	      using _Ma = _Multi_array<_Result_type (*)(_Visitor&&, _V0&&)>;
1793b1e83836Smrg
1794b1e83836Smrg#ifdef _GLIBCXX_DEBUG
1795b1e83836Smrg# define _GLIBCXX_VISIT_UNREACHABLE __builtin_trap
1796b1e83836Smrg#else
1797b1e83836Smrg# define _GLIBCXX_VISIT_UNREACHABLE __builtin_unreachable
1798b1e83836Smrg#endif
1799b1e83836Smrg
1800b1e83836Smrg#define _GLIBCXX_VISIT_CASE(N)						\
1801b1e83836Smrg  case N:								\
1802b1e83836Smrg  {									\
1803b1e83836Smrg    if constexpr (N < __n)						\
1804b1e83836Smrg      {									\
1805b1e83836Smrg	return __gen_vtable_impl<_Ma, index_sequence<N>>::		\
1806b1e83836Smrg	  __visit_invoke(std::forward<_Visitor>(__visitor),		\
1807b1e83836Smrg			 std::forward<_V0>(__v0));		\
1808b1e83836Smrg      }									\
1809b1e83836Smrg    else _GLIBCXX_VISIT_UNREACHABLE();					\
1810b1e83836Smrg  }
1811b1e83836Smrg
1812b1e83836Smrg	      switch (__v0.index())
1813b1e83836Smrg		{
1814b1e83836Smrg		  _GLIBCXX_VISIT_CASE(0)
1815b1e83836Smrg		  _GLIBCXX_VISIT_CASE(1)
1816b1e83836Smrg		  _GLIBCXX_VISIT_CASE(2)
1817b1e83836Smrg		  _GLIBCXX_VISIT_CASE(3)
1818b1e83836Smrg		  _GLIBCXX_VISIT_CASE(4)
1819b1e83836Smrg		  _GLIBCXX_VISIT_CASE(5)
1820b1e83836Smrg		  _GLIBCXX_VISIT_CASE(6)
1821b1e83836Smrg		  _GLIBCXX_VISIT_CASE(7)
1822b1e83836Smrg		  _GLIBCXX_VISIT_CASE(8)
1823b1e83836Smrg		  _GLIBCXX_VISIT_CASE(9)
1824b1e83836Smrg		  _GLIBCXX_VISIT_CASE(10)
1825b1e83836Smrg		case variant_npos:
1826b1e83836Smrg		  using __detail::__variant::__variant_idx_cookie;
1827b1e83836Smrg		  using __detail::__variant::__variant_cookie;
1828b1e83836Smrg		  if constexpr (is_same_v<_Result_type, __variant_idx_cookie>
1829b1e83836Smrg				|| is_same_v<_Result_type, __variant_cookie>)
1830b1e83836Smrg		    {
1831b1e83836Smrg		      using _Npos = index_sequence<variant_npos>;
1832b1e83836Smrg		      return __gen_vtable_impl<_Ma, _Npos>::
1833b1e83836Smrg			__visit_invoke(std::forward<_Visitor>(__visitor),
1834b1e83836Smrg				       std::forward<_V0>(__v0));
1835b1e83836Smrg		    }
1836b1e83836Smrg		  else
1837b1e83836Smrg		    _GLIBCXX_VISIT_UNREACHABLE();
1838b1e83836Smrg		default:
1839b1e83836Smrg		  _GLIBCXX_VISIT_UNREACHABLE();
1840b1e83836Smrg		}
1841b1e83836Smrg#undef _GLIBCXX_VISIT_CASE
1842b1e83836Smrg#undef _GLIBCXX_VISIT_UNREACHABLE
1843b1e83836Smrg	    }
1844b1e83836Smrg	}
1845b1e83836Smrg    }
1846b1e83836Smrg  /// @endcond
1847181254a7Smrg
1848b17d1066Smrg  template<typename _Visitor, typename... _Variants>
1849a448f87cSmrg    constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...>
1850b17d1066Smrg    visit(_Visitor&& __visitor, _Variants&&... __variants)
1851b17d1066Smrg    {
1852b1e83836Smrg      namespace __variant = std::__detail::__variant;
1853b1e83836Smrg
1854b1e83836Smrg      if ((__variant::__as(__variants).valueless_by_exception() || ...))
1855fb8a8121Smrg	__throw_bad_variant_access("std::visit: variant is valueless");
1856b17d1066Smrg
1857a448f87cSmrg      using _Result_type
1858a448f87cSmrg	= __detail::__variant::__visit_result_t<_Visitor, _Variants...>;
1859fb8a8121Smrg
1860fb8a8121Smrg      using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>;
1861fb8a8121Smrg
1862b1e83836Smrg      if constexpr (sizeof...(_Variants) == 1)
1863b1e83836Smrg	{
1864b1e83836Smrg	  using _Vp = decltype(__variant::__as(std::declval<_Variants>()...));
1865b1e83836Smrg
1866b1e83836Smrg	  constexpr bool __visit_rettypes_match = __detail::__variant::
1867b1e83836Smrg	    __check_visitor_results<_Visitor, _Vp>(
1868b1e83836Smrg	      make_index_sequence<variant_size_v<remove_reference_t<_Vp>>>());
1869b1e83836Smrg	  if constexpr (!__visit_rettypes_match)
1870b1e83836Smrg	    {
1871b1e83836Smrg	      static_assert(__visit_rettypes_match,
1872b1e83836Smrg			  "std::visit requires the visitor to have the same "
1873b1e83836Smrg			  "return type for all alternatives of a variant");
1874b1e83836Smrg	      return;
1875b1e83836Smrg	    }
1876b1e83836Smrg	  else
1877b1e83836Smrg	    return std::__do_visit<_Tag>(
1878b1e83836Smrg	      std::forward<_Visitor>(__visitor),
1879b1e83836Smrg	      static_cast<_Vp>(__variants)...);
1880b1e83836Smrg	}
1881b1e83836Smrg      else
1882b1e83836Smrg	return std::__do_visit<_Tag>(
1883b1e83836Smrg	  std::forward<_Visitor>(__visitor),
1884b1e83836Smrg	  __variant::__as(std::forward<_Variants>(__variants))...);
1885b17d1066Smrg    }
1886b17d1066Smrg
1887181254a7Smrg#if __cplusplus > 201703L
1888181254a7Smrg  template<typename _Res, typename _Visitor, typename... _Variants>
1889181254a7Smrg    constexpr _Res
1890181254a7Smrg    visit(_Visitor&& __visitor, _Variants&&... __variants)
1891181254a7Smrg    {
1892b1e83836Smrg      namespace __variant = std::__detail::__variant;
1893b1e83836Smrg
1894b1e83836Smrg      if ((__variant::__as(__variants).valueless_by_exception() || ...))
1895fb8a8121Smrg	__throw_bad_variant_access("std::visit<R>: variant is valueless");
1896181254a7Smrg
1897fb8a8121Smrg      return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor),
1898b1e83836Smrg	  __variant::__as(std::forward<_Variants>(__variants))...);
1899181254a7Smrg    }
1900181254a7Smrg#endif
1901181254a7Smrg
1902b1e83836Smrg  /// @cond undocumented
1903b17d1066Smrg  template<bool, typename... _Types>
1904b17d1066Smrg    struct __variant_hash_call_base_impl
1905b17d1066Smrg    {
1906b17d1066Smrg      size_t
1907b17d1066Smrg      operator()(const variant<_Types...>& __t) const
1908b17d1066Smrg      noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...))
1909b17d1066Smrg      {
1910181254a7Smrg	size_t __ret;
1911fb8a8121Smrg	__detail::__variant::__raw_visit(
1912fb8a8121Smrg	  [&__t, &__ret](auto&& __t_mem) mutable
1913b17d1066Smrg	  {
1914181254a7Smrg	    using _Type = __remove_cvref_t<decltype(__t_mem)>;
1915181254a7Smrg	    if constexpr (!is_same_v<_Type,
1916181254a7Smrg			             __detail::__variant::__variant_cookie>)
1917181254a7Smrg	      __ret = std::hash<size_t>{}(__t.index())
1918181254a7Smrg		      + std::hash<_Type>{}(__t_mem);
1919181254a7Smrg	    else
1920181254a7Smrg	      __ret = std::hash<size_t>{}(__t.index());
1921181254a7Smrg	  }, __t);
1922181254a7Smrg	return __ret;
1923b17d1066Smrg      }
1924b17d1066Smrg    };
1925b17d1066Smrg
1926b17d1066Smrg  template<typename... _Types>
1927b17d1066Smrg    struct __variant_hash_call_base_impl<false, _Types...> {};
1928b17d1066Smrg
1929b17d1066Smrg  template<typename... _Types>
1930b17d1066Smrg    using __variant_hash_call_base =
1931b17d1066Smrg    __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>::
1932b17d1066Smrg				   __enable_hash_call &&...), _Types...>;
1933b1e83836Smrg  /// @endcond
1934b17d1066Smrg
1935b17d1066Smrg  template<typename... _Types>
1936b17d1066Smrg    struct hash<variant<_Types...>>
1937b17d1066Smrg    : private __detail::__variant::_Variant_hash_base<
1938b17d1066Smrg	variant<_Types...>, std::index_sequence_for<_Types...>>,
1939b17d1066Smrg      public __variant_hash_call_base<_Types...>
1940b17d1066Smrg    {
1941a3e9eb18Smrg      using result_type [[__deprecated__]] = size_t;
1942a3e9eb18Smrg      using argument_type [[__deprecated__]] = variant<_Types...>;
1943b17d1066Smrg    };
1944b17d1066Smrg
1945b17d1066Smrg  template<>
1946b17d1066Smrg    struct hash<monostate>
1947b17d1066Smrg    {
1948a3e9eb18Smrg      using result_type [[__deprecated__]] = size_t;
1949a3e9eb18Smrg      using argument_type [[__deprecated__]] = monostate;
1950b17d1066Smrg
1951b17d1066Smrg      size_t
1952fb8a8121Smrg      operator()(const monostate&) const noexcept
1953b17d1066Smrg      {
1954b17d1066Smrg	constexpr size_t __magic_monostate_hash = -7777;
1955b17d1066Smrg	return __magic_monostate_hash;
1956b17d1066Smrg      }
1957b17d1066Smrg    };
1958b17d1066Smrg
1959a3e9eb18Smrg  template<typename... _Types>
1960a3e9eb18Smrg    struct __is_fast_hash<hash<variant<_Types...>>>
1961a3e9eb18Smrg    : bool_constant<(__is_fast_hash<_Types>::value && ...)>
1962a3e9eb18Smrg    { };
1963a3e9eb18Smrg
1964b17d1066Smrg_GLIBCXX_END_NAMESPACE_VERSION
1965b17d1066Smrg} // namespace std
1966b17d1066Smrg
1967b17d1066Smrg#endif // C++17
1968b17d1066Smrg
1969b17d1066Smrg#endif // _GLIBCXX_VARIANT
1970