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