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