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