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> 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 appearence 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> struct __deduce_visit_result { }; 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, 741 bool _Ti_is_cv_bool = is_same_v<remove_cv_t<_Ti>, bool>, 742 typename = void> 743 struct _Build_FUN 744 { 745 // This function means 'using _Build_FUN<I, T, Ti>::_S_fun;' is valid, 746 // but only static functions will be considered in the call below. 747 void _S_fun(); 748 }; 749 750 // ... for which Ti x[] = {std::forward<T>(t)}; is well-formed, 751 template<size_t _Ind, typename _Tp, typename _Ti> 752 struct _Build_FUN<_Ind, _Tp, _Ti, false, 753 void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>> 754 { 755 // This is the FUN function for type _Ti, with index _Ind 756 static integral_constant<size_t, _Ind> _S_fun(_Ti); 757 }; 758 759 // ... and if Ti is cv bool, remove_cvref_t<T> is bool. 760 template<size_t _Ind, typename _Tp, typename _Ti> 761 struct _Build_FUN<_Ind, _Tp, _Ti, true, 762 enable_if_t<is_same_v<__remove_cvref_t<_Tp>, bool>>> 763 { 764 // This is the FUN function for when _Ti is cv bool, with index _Ind 765 static integral_constant<size_t, _Ind> _S_fun(_Ti); 766 }; 767 768 template<typename _Tp, typename _Variant, 769 typename = make_index_sequence<variant_size_v<_Variant>>> 770 struct _Build_FUNs; 771 772 template<typename _Tp, typename... _Ti, size_t... _Ind> 773 struct _Build_FUNs<_Tp, variant<_Ti...>, index_sequence<_Ind...>> 774 : _Build_FUN<_Ind, _Tp, _Ti>... 775 { 776 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...; 777 }; 778 779 // The index j of the overload FUN(Tj) selected by overload resolution 780 // for FUN(std::forward<_Tp>(t)) 781 template<typename _Tp, typename _Variant> 782 using _FUN_type 783 = decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>())); 784 785 // The index selected for FUN(std::forward<T>(t)), or variant_npos if none. 786 template<typename _Tp, typename _Variant, typename = void> 787 struct __accepted_index 788 : integral_constant<size_t, variant_npos> 789 { }; 790 791 template<typename _Tp, typename _Variant> 792 struct __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>> 793 : _FUN_type<_Tp, _Variant> 794 { }; 795 796 // Returns the raw storage for __v. 797 template<typename _Variant> 798 void* __get_storage(_Variant&& __v) noexcept 799 { return __v._M_storage(); } 800 801 template <typename _Maybe_variant_cookie, typename _Variant> 802 struct _Extra_visit_slot_needed 803 { 804 template <typename> struct _Variant_never_valueless; 805 806 template <typename... _Types> 807 struct _Variant_never_valueless<variant<_Types...>> 808 : bool_constant<__variant::__never_valueless<_Types...>()> {}; 809 810 static constexpr bool value = 811 (is_same_v<_Maybe_variant_cookie, __variant_cookie> 812 || is_same_v<_Maybe_variant_cookie, __variant_idx_cookie>) 813 && !_Variant_never_valueless<__remove_cvref_t<_Variant>>::value; 814 }; 815 816 // Used for storing a multi-dimensional vtable. 817 template<typename _Tp, size_t... _Dimensions> 818 struct _Multi_array; 819 820 // Partial specialization with rank zero, stores a single _Tp element. 821 template<typename _Tp> 822 struct _Multi_array<_Tp> 823 { 824 template<typename> 825 struct __untag_result 826 : false_type 827 { using element_type = _Tp; }; 828 829 template <typename... _Args> 830 struct __untag_result<const void(*)(_Args...)> 831 : false_type 832 { using element_type = void(*)(_Args...); }; 833 834 template <typename... _Args> 835 struct __untag_result<__variant_cookie(*)(_Args...)> 836 : false_type 837 { using element_type = void(*)(_Args...); }; 838 839 template <typename... _Args> 840 struct __untag_result<__variant_idx_cookie(*)(_Args...)> 841 : false_type 842 { using element_type = void(*)(_Args...); }; 843 844 template <typename _Res, typename... _Args> 845 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)> 846 : true_type 847 { using element_type = _Res(*)(_Args...); }; 848 849 using __result_is_deduced = __untag_result<_Tp>; 850 851 constexpr const typename __untag_result<_Tp>::element_type& 852 _M_access() const 853 { return _M_data; } 854 855 typename __untag_result<_Tp>::element_type _M_data; 856 }; 857 858 // Partial specialization with rank >= 1. 859 template<typename _Ret, 860 typename _Visitor, 861 typename... _Variants, 862 size_t __first, size_t... __rest> 863 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...> 864 { 865 static constexpr size_t __index = 866 sizeof...(_Variants) - sizeof...(__rest) - 1; 867 868 using _Variant = typename _Nth_type<__index, _Variants...>::type; 869 870 static constexpr int __do_cookie = 871 _Extra_visit_slot_needed<_Ret, _Variant>::value ? 1 : 0; 872 873 using _Tp = _Ret(*)(_Visitor, _Variants...); 874 875 template<typename... _Args> 876 constexpr decltype(auto) 877 _M_access(size_t __first_index, _Args... __rest_indices) const 878 { 879 return _M_arr[__first_index + __do_cookie] 880 ._M_access(__rest_indices...); 881 } 882 883 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie]; 884 }; 885 886 // Creates a multi-dimensional vtable recursively. 887 // 888 // For example, 889 // visit([](auto, auto){}, 890 // variant<int, char>(), // typedef'ed as V1 891 // variant<float, double, long double>()) // typedef'ed as V2 892 // will trigger instantiations of: 893 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 2, 3>, 894 // tuple<V1&&, V2&&>, std::index_sequence<>> 895 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>, 896 // tuple<V1&&, V2&&>, std::index_sequence<0>> 897 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 898 // tuple<V1&&, V2&&>, std::index_sequence<0, 0>> 899 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 900 // tuple<V1&&, V2&&>, std::index_sequence<0, 1>> 901 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 902 // tuple<V1&&, V2&&>, std::index_sequence<0, 2>> 903 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&), 3>, 904 // tuple<V1&&, V2&&>, std::index_sequence<1>> 905 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 906 // tuple<V1&&, V2&&>, std::index_sequence<1, 0>> 907 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 908 // tuple<V1&&, V2&&>, std::index_sequence<1, 1>> 909 // __gen_vtable_impl<_Multi_array<void(*)(V1&&, V2&&)>, 910 // tuple<V1&&, V2&&>, std::index_sequence<1, 2>> 911 // The returned multi-dimensional vtable can be fast accessed by the visitor 912 // using index calculation. 913 template<typename _Array_type, typename _Index_seq> 914 struct __gen_vtable_impl; 915 916 // Defines the _S_apply() member that returns a _Multi_array populated 917 // with function pointers that perform the visitation expressions e(m) 918 // for each valid pack of indexes into the variant types _Variants. 919 // 920 // This partial specialization builds up the index sequences by recursively 921 // calling _S_apply() on the next specialization of __gen_vtable_impl. 922 // The base case of the recursion defines the actual function pointers. 923 template<typename _Result_type, typename _Visitor, size_t... __dimensions, 924 typename... _Variants, size_t... __indices> 925 struct __gen_vtable_impl< 926 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>, 927 std::index_sequence<__indices...>> 928 { 929 using _Next = 930 remove_reference_t<typename _Nth_type<sizeof...(__indices), 931 _Variants...>::type>; 932 using _Array_type = 933 _Multi_array<_Result_type (*)(_Visitor, _Variants...), 934 __dimensions...>; 935 936 static constexpr _Array_type 937 _S_apply() 938 { 939 _Array_type __vtable{}; 940 _S_apply_all_alts( 941 __vtable, make_index_sequence<variant_size_v<_Next>>()); 942 return __vtable; 943 } 944 945 template<size_t... __var_indices> 946 static constexpr void 947 _S_apply_all_alts(_Array_type& __vtable, 948 std::index_sequence<__var_indices...>) 949 { 950 if constexpr (_Extra_visit_slot_needed<_Result_type, _Next>::value) 951 (_S_apply_single_alt<true, __var_indices>( 952 __vtable._M_arr[__var_indices + 1], 953 &(__vtable._M_arr[0])), ...); 954 else 955 (_S_apply_single_alt<false, __var_indices>( 956 __vtable._M_arr[__var_indices]), ...); 957 } 958 959 template<bool __do_cookie, size_t __index, typename _Tp> 960 static constexpr void 961 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element = nullptr) 962 { 963 if constexpr (__do_cookie) 964 { 965 __element = __gen_vtable_impl< 966 _Tp, 967 std::index_sequence<__indices..., __index>>::_S_apply(); 968 *__cookie_element = __gen_vtable_impl< 969 _Tp, 970 std::index_sequence<__indices..., variant_npos>>::_S_apply(); 971 } 972 else 973 { 974 __element = __gen_vtable_impl< 975 remove_reference_t<decltype(__element)>, 976 std::index_sequence<__indices..., __index>>::_S_apply(); 977 } 978 } 979 }; 980 981 // This partial specialization is the base case for the recursion. 982 // It populates a _Multi_array element with the address of a function 983 // that invokes the visitor with the alternatives specified by __indices. 984 template<typename _Result_type, typename _Visitor, typename... _Variants, 985 size_t... __indices> 986 struct __gen_vtable_impl< 987 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>, 988 std::index_sequence<__indices...>> 989 { 990 using _Array_type = 991 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>; 992 993 template<size_t __index, typename _Variant> 994 static constexpr decltype(auto) 995 __element_by_index_or_cookie(_Variant&& __var) noexcept 996 { 997 if constexpr (__index != variant_npos) 998 return __variant::__get<__index>(std::forward<_Variant>(__var)); 999 else 1000 return __variant_cookie{}; 1001 } 1002 1003 static constexpr decltype(auto) 1004 __visit_invoke(_Visitor&& __visitor, _Variants... __vars) 1005 { 1006 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>) 1007 // For raw visitation using indices, pass the indices to the visitor 1008 // 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 integral_constant<size_t, __indices>()...); 1013 else if constexpr (is_same_v<_Result_type, __variant_cookie>) 1014 // For raw visitation without indices, and discard the return value: 1015 std::__invoke(std::forward<_Visitor>(__visitor), 1016 __element_by_index_or_cookie<__indices>( 1017 std::forward<_Variants>(__vars))...); 1018 else if constexpr (_Array_type::__result_is_deduced::value) 1019 // For the usual std::visit case deduce the return value: 1020 return std::__invoke(std::forward<_Visitor>(__visitor), 1021 __element_by_index_or_cookie<__indices>( 1022 std::forward<_Variants>(__vars))...); 1023 else // for std::visit<R> use INVOKE<R> 1024 return std::__invoke_r<_Result_type>( 1025 std::forward<_Visitor>(__visitor), 1026 __variant::__get<__indices>(std::forward<_Variants>(__vars))...); 1027 } 1028 1029 static constexpr auto 1030 _S_apply() 1031 { return _Array_type{&__visit_invoke}; } 1032 }; 1033 1034 template<typename _Result_type, typename _Visitor, typename... _Variants> 1035 struct __gen_vtable 1036 { 1037 using _Array_type = 1038 _Multi_array<_Result_type (*)(_Visitor, _Variants...), 1039 variant_size_v<remove_reference_t<_Variants>>...>; 1040 1041 static constexpr _Array_type _S_vtable 1042 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply(); 1043 }; 1044 1045 template<size_t _Np, typename _Tp> 1046 struct _Base_dedup : public _Tp { }; 1047 1048 template<typename _Variant, typename __indices> 1049 struct _Variant_hash_base; 1050 1051 template<typename... _Types, size_t... __indices> 1052 struct _Variant_hash_base<variant<_Types...>, 1053 std::index_sequence<__indices...>> 1054 : _Base_dedup<__indices, __poison_hash<remove_const_t<_Types>>>... { }; 1055 1056 template<size_t _Np, typename _Variant> 1057 using __get_t = decltype(std::get<_Np>(std::declval<_Variant>())); 1058 1059 // Return type of std::visit. 1060 template<typename _Visitor, typename... _Variants> 1061 using __visit_result_t 1062 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>; 1063 1064} // namespace __variant 1065} // namespace __detail 1066 1067 template<size_t _Np, typename _Variant, typename... _Args> 1068 void __variant_construct_by_index(_Variant& __v, _Args&&... __args) 1069 { 1070 __v._M_index = _Np; 1071 auto&& __storage = __detail::__variant::__get<_Np>(__v); 1072 ::new ((void*)std::addressof(__storage)) 1073 remove_reference_t<decltype(__storage)> 1074 (std::forward<_Args>(__args)...); 1075 } 1076 1077 template<typename _Tp, typename... _Types> 1078 constexpr bool 1079 holds_alternative(const variant<_Types...>& __v) noexcept 1080 { 1081 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1082 "T must occur exactly once in alternatives"); 1083 return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>; 1084 } 1085 1086 template<typename _Tp, typename... _Types> 1087 constexpr _Tp& get(variant<_Types...>& __v) 1088 { 1089 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1090 "T must occur exactly once in alternatives"); 1091 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1092 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); 1093 } 1094 1095 template<typename _Tp, typename... _Types> 1096 constexpr _Tp&& get(variant<_Types...>&& __v) 1097 { 1098 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1099 "T must occur exactly once in alternatives"); 1100 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1101 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( 1102 std::move(__v)); 1103 } 1104 1105 template<typename _Tp, typename... _Types> 1106 constexpr const _Tp& get(const variant<_Types...>& __v) 1107 { 1108 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1109 "T must occur exactly once in alternatives"); 1110 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1111 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>(__v); 1112 } 1113 1114 template<typename _Tp, typename... _Types> 1115 constexpr const _Tp&& get(const variant<_Types...>&& __v) 1116 { 1117 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1118 "T must occur exactly once in alternatives"); 1119 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1120 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( 1121 std::move(__v)); 1122 } 1123 1124 template<size_t _Np, typename... _Types> 1125 constexpr add_pointer_t<variant_alternative_t<_Np, variant<_Types...>>> 1126 get_if(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<size_t _Np, typename... _Types> 1138 constexpr 1139 add_pointer_t<const variant_alternative_t<_Np, variant<_Types...>>> 1140 get_if(const variant<_Types...>* __ptr) noexcept 1141 { 1142 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; 1143 static_assert(_Np < sizeof...(_Types), 1144 "The index must be in [0, number of alternatives)"); 1145 static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void"); 1146 if (__ptr && __ptr->index() == _Np) 1147 return std::addressof(__detail::__variant::__get<_Np>(*__ptr)); 1148 return nullptr; 1149 } 1150 1151 template<typename _Tp, typename... _Types> 1152 constexpr add_pointer_t<_Tp> 1153 get_if(variant<_Types...>* __ptr) noexcept 1154 { 1155 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1156 "T must occur exactly once in alternatives"); 1157 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1158 return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( 1159 __ptr); 1160 } 1161 1162 template<typename _Tp, typename... _Types> 1163 constexpr add_pointer_t<const _Tp> 1164 get_if(const variant<_Types...>* __ptr) noexcept 1165 { 1166 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1167 "T must occur exactly once in alternatives"); 1168 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1169 return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( 1170 __ptr); 1171 } 1172 1173 struct monostate { }; 1174 1175#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ 1176 template<typename... _Types> \ 1177 constexpr bool operator __OP(const variant<_Types...>& __lhs, \ 1178 const variant<_Types...>& __rhs) \ 1179 { \ 1180 bool __ret = true; \ 1181 __detail::__variant::__raw_idx_visit( \ 1182 [&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \ 1183 { \ 1184 if constexpr (__rhs_index != variant_npos) \ 1185 { \ 1186 if (__lhs.index() == __rhs_index) \ 1187 { \ 1188 auto& __this_mem = std::get<__rhs_index>(__lhs); \ 1189 __ret = __this_mem __OP __rhs_mem; \ 1190 } \ 1191 else \ 1192 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \ 1193 } \ 1194 else \ 1195 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \ 1196 }, __rhs); \ 1197 return __ret; \ 1198 } 1199 1200 _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) 1201 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) 1202 _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) 1203 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) 1204 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) 1205 _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) 1206 1207#undef _VARIANT_RELATION_FUNCTION_TEMPLATE 1208 1209 constexpr bool operator==(monostate, monostate) noexcept { return true; } 1210 1211#ifdef __cpp_lib_three_way_comparison 1212 template<typename... _Types> 1213 requires (three_way_comparable<_Types> && ...) 1214 constexpr 1215 common_comparison_category_t<compare_three_way_result_t<_Types>...> 1216 operator<=>(const variant<_Types...>& __v, const variant<_Types...>& __w) 1217 { 1218 common_comparison_category_t<compare_three_way_result_t<_Types>...> __ret 1219 = strong_ordering::equal; 1220 1221 __detail::__variant::__raw_idx_visit( 1222 [&__ret, &__v] (auto&& __w_mem, auto __w_index) mutable 1223 { 1224 if constexpr (__w_index != variant_npos) 1225 { 1226 if (__v.index() == __w_index) 1227 { 1228 auto& __this_mem = std::get<__w_index>(__v); 1229 __ret = __this_mem <=> __w_mem; 1230 return; 1231 } 1232 } 1233 __ret = (__v.index() + 1) <=> (__w_index + 1); 1234 }, __w); 1235 return __ret; 1236 } 1237 1238 constexpr strong_ordering 1239 operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; } 1240#else 1241 constexpr bool operator!=(monostate, monostate) noexcept { return false; } 1242 constexpr bool operator<(monostate, monostate) noexcept { return false; } 1243 constexpr bool operator>(monostate, monostate) noexcept { return false; } 1244 constexpr bool operator<=(monostate, monostate) noexcept { return true; } 1245 constexpr bool operator>=(monostate, monostate) noexcept { return true; } 1246#endif 1247 1248 template<typename _Visitor, typename... _Variants> 1249 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> 1250 visit(_Visitor&&, _Variants&&...); 1251 1252 template<typename... _Types> 1253 inline enable_if_t<(is_move_constructible_v<_Types> && ...) 1254 && (is_swappable_v<_Types> && ...)> 1255 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) 1256 noexcept(noexcept(__lhs.swap(__rhs))) 1257 { __lhs.swap(__rhs); } 1258 1259 template<typename... _Types> 1260 enable_if_t<!((is_move_constructible_v<_Types> && ...) 1261 && (is_swappable_v<_Types> && ...))> 1262 swap(variant<_Types...>&, variant<_Types...>&) = delete; 1263 1264 class bad_variant_access : public exception 1265 { 1266 public: 1267 bad_variant_access() noexcept { } 1268 1269 const char* what() const noexcept override 1270 { return _M_reason; } 1271 1272 private: 1273 bad_variant_access(const char* __reason) noexcept : _M_reason(__reason) { } 1274 1275 // Must point to a string with static storage duration: 1276 const char* _M_reason = "bad variant access"; 1277 1278 friend void __throw_bad_variant_access(const char* __what); 1279 }; 1280 1281 // Must only be called with a string literal 1282 inline void 1283 __throw_bad_variant_access(const char* __what) 1284 { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); } 1285 1286 inline void 1287 __throw_bad_variant_access(bool __valueless) 1288 { 1289 if (__valueless) [[__unlikely__]] 1290 __throw_bad_variant_access("std::get: variant is valueless"); 1291 else 1292 __throw_bad_variant_access("std::get: wrong index for variant"); 1293 } 1294 1295 template<typename... _Types> 1296 class variant 1297 : private __detail::__variant::_Variant_base<_Types...>, 1298 private _Enable_default_constructor< 1299 __detail::__variant::_Traits<_Types...>::_S_default_ctor, 1300 variant<_Types...>>, 1301 private _Enable_copy_move< 1302 __detail::__variant::_Traits<_Types...>::_S_copy_ctor, 1303 __detail::__variant::_Traits<_Types...>::_S_copy_assign, 1304 __detail::__variant::_Traits<_Types...>::_S_move_ctor, 1305 __detail::__variant::_Traits<_Types...>::_S_move_assign, 1306 variant<_Types...>> 1307 { 1308 private: 1309 template <typename... _UTypes, typename _Tp> 1310 friend decltype(auto) __variant_cast(_Tp&&); 1311 template<size_t _Np, typename _Variant, typename... _Args> 1312 friend void __variant_construct_by_index(_Variant& __v, 1313 _Args&&... __args); 1314 1315 static_assert(sizeof...(_Types) > 0, 1316 "variant must have at least one alternative"); 1317 static_assert(!(std::is_reference_v<_Types> || ...), 1318 "variant must have no reference alternative"); 1319 static_assert(!(std::is_void_v<_Types> || ...), 1320 "variant must have no void alternative"); 1321 1322 using _Base = __detail::__variant::_Variant_base<_Types...>; 1323 using _Default_ctor_enabler = 1324 _Enable_default_constructor< 1325 __detail::__variant::_Traits<_Types...>::_S_default_ctor, 1326 variant<_Types...>>; 1327 1328 template<typename _Tp> 1329 static constexpr bool __not_self 1330 = !is_same_v<__remove_cvref_t<_Tp>, variant>; 1331 1332 template<typename _Tp> 1333 static constexpr bool 1334 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>; 1335 1336 template<typename _Tp> 1337 static constexpr size_t __accepted_index 1338 = __detail::__variant::__accepted_index<_Tp, variant>::value; 1339 1340 template<size_t _Np, typename = enable_if_t<(_Np < sizeof...(_Types))>> 1341 using __to_type = variant_alternative_t<_Np, variant>; 1342 1343 template<typename _Tp, typename = enable_if_t<__not_self<_Tp>>> 1344 using __accepted_type = __to_type<__accepted_index<_Tp>>; 1345 1346 template<typename _Tp> 1347 static constexpr size_t __index_of = 1348 __detail::__variant::__index_of_v<_Tp, _Types...>; 1349 1350 using _Traits = __detail::__variant::_Traits<_Types...>; 1351 1352 template<typename _Tp> 1353 struct __is_in_place_tag : false_type { }; 1354 template<typename _Tp> 1355 struct __is_in_place_tag<in_place_type_t<_Tp>> : true_type { }; 1356 template<size_t _Np> 1357 struct __is_in_place_tag<in_place_index_t<_Np>> : true_type { }; 1358 1359 template<typename _Tp> 1360 static constexpr bool __not_in_place_tag 1361 = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value; 1362 1363 public: 1364 variant() = default; 1365 variant(const variant& __rhs) = default; 1366 variant(variant&&) = default; 1367 variant& operator=(const variant&) = default; 1368 variant& operator=(variant&&) = default; 1369 ~variant() = default; 1370 1371 template<typename _Tp, 1372 typename = enable_if_t<sizeof...(_Types) != 0>, 1373 typename = enable_if_t<__not_in_place_tag<_Tp>>, 1374 typename _Tj = __accepted_type<_Tp&&>, 1375 typename = enable_if_t<__exactly_once<_Tj> 1376 && is_constructible_v<_Tj, _Tp>>> 1377 constexpr 1378 variant(_Tp&& __t) 1379 noexcept(is_nothrow_constructible_v<_Tj, _Tp>) 1380 : variant(in_place_index<__accepted_index<_Tp>>, 1381 std::forward<_Tp>(__t)) 1382 { } 1383 1384 template<typename _Tp, typename... _Args, 1385 typename = enable_if_t<__exactly_once<_Tp> 1386 && is_constructible_v<_Tp, _Args...>>> 1387 constexpr explicit 1388 variant(in_place_type_t<_Tp>, _Args&&... __args) 1389 : variant(in_place_index<__index_of<_Tp>>, 1390 std::forward<_Args>(__args)...) 1391 { } 1392 1393 template<typename _Tp, typename _Up, typename... _Args, 1394 typename = enable_if_t<__exactly_once<_Tp> 1395 && is_constructible_v<_Tp, 1396 initializer_list<_Up>&, _Args...>>> 1397 constexpr explicit 1398 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il, 1399 _Args&&... __args) 1400 : variant(in_place_index<__index_of<_Tp>>, __il, 1401 std::forward<_Args>(__args)...) 1402 { } 1403 1404 template<size_t _Np, typename... _Args, 1405 typename _Tp = __to_type<_Np>, 1406 typename = enable_if_t<is_constructible_v<_Tp, _Args...>>> 1407 constexpr explicit 1408 variant(in_place_index_t<_Np>, _Args&&... __args) 1409 : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...), 1410 _Default_ctor_enabler(_Enable_default_constructor_tag{}) 1411 { } 1412 1413 template<size_t _Np, typename _Up, typename... _Args, 1414 typename _Tp = __to_type<_Np>, 1415 typename = enable_if_t<is_constructible_v<_Tp, 1416 initializer_list<_Up>&, 1417 _Args...>>> 1418 constexpr explicit 1419 variant(in_place_index_t<_Np>, initializer_list<_Up> __il, 1420 _Args&&... __args) 1421 : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...), 1422 _Default_ctor_enabler(_Enable_default_constructor_tag{}) 1423 { } 1424 1425 template<typename _Tp> 1426 enable_if_t<__exactly_once<__accepted_type<_Tp&&>> 1427 && is_constructible_v<__accepted_type<_Tp&&>, _Tp> 1428 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>, 1429 variant&> 1430 operator=(_Tp&& __rhs) 1431 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp> 1432 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>) 1433 { 1434 constexpr auto __index = __accepted_index<_Tp>; 1435 if (index() == __index) 1436 std::get<__index>(*this) = std::forward<_Tp>(__rhs); 1437 else 1438 { 1439 using _Tj = __accepted_type<_Tp&&>; 1440 if constexpr (is_nothrow_constructible_v<_Tj, _Tp> 1441 || !is_nothrow_move_constructible_v<_Tj>) 1442 this->emplace<__index>(std::forward<_Tp>(__rhs)); 1443 else 1444 operator=(variant(std::forward<_Tp>(__rhs))); 1445 } 1446 return *this; 1447 } 1448 1449 template<typename _Tp, typename... _Args> 1450 enable_if_t<is_constructible_v<_Tp, _Args...> && __exactly_once<_Tp>, 1451 _Tp&> 1452 emplace(_Args&&... __args) 1453 { 1454 constexpr size_t __index = __index_of<_Tp>; 1455 return this->emplace<__index>(std::forward<_Args>(__args)...); 1456 } 1457 1458 template<typename _Tp, typename _Up, typename... _Args> 1459 enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...> 1460 && __exactly_once<_Tp>, 1461 _Tp&> 1462 emplace(initializer_list<_Up> __il, _Args&&... __args) 1463 { 1464 constexpr size_t __index = __index_of<_Tp>; 1465 return this->emplace<__index>(__il, std::forward<_Args>(__args)...); 1466 } 1467 1468 template<size_t _Np, typename... _Args> 1469 enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>, 1470 _Args...>, 1471 variant_alternative_t<_Np, variant>&> 1472 emplace(_Args&&... __args) 1473 { 1474 static_assert(_Np < sizeof...(_Types), 1475 "The index must be in [0, number of alternatives)"); 1476 using type = variant_alternative_t<_Np, variant>; 1477 // Provide the strong exception-safety guarantee when possible, 1478 // to avoid becoming valueless. 1479 if constexpr (is_nothrow_constructible_v<type, _Args...>) 1480 { 1481 this->_M_reset(); 1482 __variant_construct_by_index<_Np>(*this, 1483 std::forward<_Args>(__args)...); 1484 } 1485 else if constexpr (is_scalar_v<type>) 1486 { 1487 // This might invoke a potentially-throwing conversion operator: 1488 const type __tmp(std::forward<_Args>(__args)...); 1489 // But these steps won't throw: 1490 this->_M_reset(); 1491 __variant_construct_by_index<_Np>(*this, __tmp); 1492 } 1493 else if constexpr (__detail::__variant::_Never_valueless_alt<type>() 1494 && _Traits::_S_move_assign) 1495 { 1496 // This construction might throw: 1497 variant __tmp(in_place_index<_Np>, 1498 std::forward<_Args>(__args)...); 1499 // But _Never_valueless_alt<type> means this won't: 1500 *this = std::move(__tmp); 1501 } 1502 else 1503 { 1504 // This case only provides the basic exception-safety guarantee, 1505 // i.e. the variant can become valueless. 1506 this->_M_reset(); 1507 __try 1508 { 1509 __variant_construct_by_index<_Np>(*this, 1510 std::forward<_Args>(__args)...); 1511 } 1512 __catch (...) 1513 { 1514 this->_M_index = variant_npos; 1515 __throw_exception_again; 1516 } 1517 } 1518 return std::get<_Np>(*this); 1519 } 1520 1521 template<size_t _Np, typename _Up, typename... _Args> 1522 enable_if_t<is_constructible_v<variant_alternative_t<_Np, variant>, 1523 initializer_list<_Up>&, _Args...>, 1524 variant_alternative_t<_Np, variant>&> 1525 emplace(initializer_list<_Up> __il, _Args&&... __args) 1526 { 1527 static_assert(_Np < sizeof...(_Types), 1528 "The index must be in [0, number of alternatives)"); 1529 using type = variant_alternative_t<_Np, variant>; 1530 // Provide the strong exception-safety guarantee when possible, 1531 // to avoid becoming valueless. 1532 if constexpr (is_nothrow_constructible_v<type, 1533 initializer_list<_Up>&, 1534 _Args...>) 1535 { 1536 this->_M_reset(); 1537 __variant_construct_by_index<_Np>(*this, __il, 1538 std::forward<_Args>(__args)...); 1539 } 1540 else if constexpr (__detail::__variant::_Never_valueless_alt<type>() 1541 && _Traits::_S_move_assign) 1542 { 1543 // This construction might throw: 1544 variant __tmp(in_place_index<_Np>, __il, 1545 std::forward<_Args>(__args)...); 1546 // But _Never_valueless_alt<type> means this won't: 1547 *this = std::move(__tmp); 1548 } 1549 else 1550 { 1551 // This case only provides the basic exception-safety guarantee, 1552 // i.e. the variant can become valueless. 1553 this->_M_reset(); 1554 __try 1555 { 1556 __variant_construct_by_index<_Np>(*this, __il, 1557 std::forward<_Args>(__args)...); 1558 } 1559 __catch (...) 1560 { 1561 this->_M_index = variant_npos; 1562 __throw_exception_again; 1563 } 1564 } 1565 return std::get<_Np>(*this); 1566 } 1567 1568 constexpr bool valueless_by_exception() const noexcept 1569 { return !this->_M_valid(); } 1570 1571 constexpr size_t index() const noexcept 1572 { 1573 using __index_type = typename _Base::__index_type; 1574 if constexpr (__detail::__variant::__never_valueless<_Types...>()) 1575 return this->_M_index; 1576 else if constexpr (sizeof...(_Types) <= __index_type(-1) / 2) 1577 return make_signed_t<__index_type>(this->_M_index); 1578 else 1579 return size_t(__index_type(this->_M_index + 1)) - 1; 1580 } 1581 1582 void 1583 swap(variant& __rhs) 1584 noexcept((__is_nothrow_swappable<_Types>::value && ...) 1585 && is_nothrow_move_constructible_v<variant>) 1586 { 1587 __detail::__variant::__raw_idx_visit( 1588 [this, &__rhs](auto&& __rhs_mem, auto __rhs_index) mutable 1589 { 1590 if constexpr (__rhs_index != variant_npos) 1591 { 1592 if (this->index() == __rhs_index) 1593 { 1594 auto& __this_mem = 1595 std::get<__rhs_index>(*this); 1596 using std::swap; 1597 swap(__this_mem, __rhs_mem); 1598 } 1599 else 1600 { 1601 if (!this->valueless_by_exception()) [[__likely__]] 1602 { 1603 auto __tmp(std::move(__rhs_mem)); 1604 __rhs = std::move(*this); 1605 this->_M_destructive_move(__rhs_index, 1606 std::move(__tmp)); 1607 } 1608 else 1609 { 1610 this->_M_destructive_move(__rhs_index, 1611 std::move(__rhs_mem)); 1612 __rhs._M_reset(); 1613 } 1614 } 1615 } 1616 else 1617 { 1618 if (!this->valueless_by_exception()) [[__likely__]] 1619 { 1620 __rhs = std::move(*this); 1621 this->_M_reset(); 1622 } 1623 } 1624 }, __rhs); 1625 } 1626 1627 private: 1628 1629#if defined(__clang__) && __clang_major__ <= 7 1630 public: 1631 using _Base::_M_u; // See https://bugs.llvm.org/show_bug.cgi?id=31852 1632 private: 1633#endif 1634 1635 template<size_t _Np, typename _Vp> 1636 friend constexpr decltype(auto) 1637 __detail::__variant::__get(_Vp&& __v) noexcept; 1638 1639 template<typename _Vp> 1640 friend void* 1641 __detail::__variant::__get_storage(_Vp&& __v) noexcept; 1642 1643#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \ 1644 template<typename... _Tp> \ 1645 friend constexpr bool \ 1646 operator __OP(const variant<_Tp...>& __lhs, \ 1647 const variant<_Tp...>& __rhs); 1648 1649 _VARIANT_RELATION_FUNCTION_TEMPLATE(<) 1650 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=) 1651 _VARIANT_RELATION_FUNCTION_TEMPLATE(==) 1652 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=) 1653 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=) 1654 _VARIANT_RELATION_FUNCTION_TEMPLATE(>) 1655 1656#undef _VARIANT_RELATION_FUNCTION_TEMPLATE 1657 }; 1658 1659 template<size_t _Np, typename... _Types> 1660 constexpr variant_alternative_t<_Np, variant<_Types...>>& 1661 get(variant<_Types...>& __v) 1662 { 1663 static_assert(_Np < sizeof...(_Types), 1664 "The index must be in [0, number of alternatives)"); 1665 if (__v.index() != _Np) 1666 __throw_bad_variant_access(__v.valueless_by_exception()); 1667 return __detail::__variant::__get<_Np>(__v); 1668 } 1669 1670 template<size_t _Np, typename... _Types> 1671 constexpr variant_alternative_t<_Np, variant<_Types...>>&& 1672 get(variant<_Types...>&& __v) 1673 { 1674 static_assert(_Np < sizeof...(_Types), 1675 "The index must be in [0, number of alternatives)"); 1676 if (__v.index() != _Np) 1677 __throw_bad_variant_access(__v.valueless_by_exception()); 1678 return __detail::__variant::__get<_Np>(std::move(__v)); 1679 } 1680 1681 template<size_t _Np, typename... _Types> 1682 constexpr const variant_alternative_t<_Np, variant<_Types...>>& 1683 get(const variant<_Types...>& __v) 1684 { 1685 static_assert(_Np < sizeof...(_Types), 1686 "The index must be in [0, number of alternatives)"); 1687 if (__v.index() != _Np) 1688 __throw_bad_variant_access(__v.valueless_by_exception()); 1689 return __detail::__variant::__get<_Np>(__v); 1690 } 1691 1692 template<size_t _Np, typename... _Types> 1693 constexpr const variant_alternative_t<_Np, variant<_Types...>>&& 1694 get(const variant<_Types...>&& __v) 1695 { 1696 static_assert(_Np < sizeof...(_Types), 1697 "The index must be in [0, number of alternatives)"); 1698 if (__v.index() != _Np) 1699 __throw_bad_variant_access(__v.valueless_by_exception()); 1700 return __detail::__variant::__get<_Np>(std::move(__v)); 1701 } 1702 1703 template<typename _Result_type, typename _Visitor, typename... _Variants> 1704 constexpr decltype(auto) 1705 __do_visit(_Visitor&& __visitor, _Variants&&... __variants) 1706 { 1707 constexpr auto& __vtable = __detail::__variant::__gen_vtable< 1708 _Result_type, _Visitor&&, _Variants&&...>::_S_vtable; 1709 1710 auto __func_ptr = __vtable._M_access(__variants.index()...); 1711 return (*__func_ptr)(std::forward<_Visitor>(__visitor), 1712 std::forward<_Variants>(__variants)...); 1713 } 1714 1715 template<typename _Visitor, typename... _Variants> 1716 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> 1717 visit(_Visitor&& __visitor, _Variants&&... __variants) 1718 { 1719 if ((__variants.valueless_by_exception() || ...)) 1720 __throw_bad_variant_access("std::visit: variant is valueless"); 1721 1722 using _Result_type 1723 = __detail::__variant::__visit_result_t<_Visitor, _Variants...>; 1724 1725 using _Tag = __detail::__variant::__deduce_visit_result<_Result_type>; 1726 1727 return std::__do_visit<_Tag>(std::forward<_Visitor>(__visitor), 1728 std::forward<_Variants>(__variants)...); 1729 } 1730 1731#if __cplusplus > 201703L 1732 template<typename _Res, typename _Visitor, typename... _Variants> 1733 constexpr _Res 1734 visit(_Visitor&& __visitor, _Variants&&... __variants) 1735 { 1736 if ((__variants.valueless_by_exception() || ...)) 1737 __throw_bad_variant_access("std::visit<R>: variant is valueless"); 1738 1739 return std::__do_visit<_Res>(std::forward<_Visitor>(__visitor), 1740 std::forward<_Variants>(__variants)...); 1741 } 1742#endif 1743 1744 template<bool, typename... _Types> 1745 struct __variant_hash_call_base_impl 1746 { 1747 size_t 1748 operator()(const variant<_Types...>& __t) const 1749 noexcept((is_nothrow_invocable_v<hash<decay_t<_Types>>, _Types> && ...)) 1750 { 1751 size_t __ret; 1752 __detail::__variant::__raw_visit( 1753 [&__t, &__ret](auto&& __t_mem) mutable 1754 { 1755 using _Type = __remove_cvref_t<decltype(__t_mem)>; 1756 if constexpr (!is_same_v<_Type, 1757 __detail::__variant::__variant_cookie>) 1758 __ret = std::hash<size_t>{}(__t.index()) 1759 + std::hash<_Type>{}(__t_mem); 1760 else 1761 __ret = std::hash<size_t>{}(__t.index()); 1762 }, __t); 1763 return __ret; 1764 } 1765 }; 1766 1767 template<typename... _Types> 1768 struct __variant_hash_call_base_impl<false, _Types...> {}; 1769 1770 template<typename... _Types> 1771 using __variant_hash_call_base = 1772 __variant_hash_call_base_impl<(__poison_hash<remove_const_t<_Types>>:: 1773 __enable_hash_call &&...), _Types...>; 1774 1775 template<typename... _Types> 1776 struct hash<variant<_Types...>> 1777 : private __detail::__variant::_Variant_hash_base< 1778 variant<_Types...>, std::index_sequence_for<_Types...>>, 1779 public __variant_hash_call_base<_Types...> 1780 { 1781 using result_type [[__deprecated__]] = size_t; 1782 using argument_type [[__deprecated__]] = variant<_Types...>; 1783 }; 1784 1785 template<> 1786 struct hash<monostate> 1787 { 1788 using result_type [[__deprecated__]] = size_t; 1789 using argument_type [[__deprecated__]] = monostate; 1790 1791 size_t 1792 operator()(const monostate&) const noexcept 1793 { 1794 constexpr size_t __magic_monostate_hash = -7777; 1795 return __magic_monostate_hash; 1796 } 1797 }; 1798 1799 template<typename... _Types> 1800 struct __is_fast_hash<hash<variant<_Types...>>> 1801 : bool_constant<(__is_fast_hash<_Types>::value && ...)> 1802 { }; 1803 1804_GLIBCXX_END_NAMESPACE_VERSION 1805} // namespace std 1806 1807#endif // C++17 1808 1809#endif // _GLIBCXX_VARIANT 1810