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