Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/11/variant
$ cat -n /usr/include/c++/11/variant 1 //
-*- 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 //
. 24 25 /** @file variant 26 * This is the `
` 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
37 #include
38 #include
39 #include
40 #include
41 #include
42 #include
43 #include
44 #include
45 #include
46 #include
47 #include
48 #if __cplusplus > 201703L 49 # include
50 #endif 51 52 namespace std _GLIBCXX_VISIBILITY(default) 53 { 54 _GLIBCXX_BEGIN_NAMESPACE_VERSION 55 56 namespace __detail 57 { 58 namespace __variant 59 { 60 template
61 struct _Nth_type; 62 63 template
64 struct _Nth_type<_Np, _First, _Rest...> 65 : _Nth_type<_Np-1, _Rest...> { }; 66 67 template
68 struct _Nth_type<0, _First, _Rest...> 69 { using type = _First; }; 70 71 } // namespace __variant 72 } // namespace __detail 73 74 #define __cpp_lib_variant 202102L 75 76 template
class tuple; 77 template
class variant; 78 template
struct hash; 79 80 template
81 struct variant_size; 82 83 template
84 struct variant_size
: variant_size<_Variant> {}; 85 86 template
87 struct variant_size
: variant_size<_Variant> {}; 88 89 template
90 struct variant_size
: variant_size<_Variant> {}; 91 92 template
93 struct variant_size
> 94 : std::integral_constant
{}; 95 96 template
97 inline constexpr size_t variant_size_v = variant_size<_Variant>::value; 98 99 template
100 struct variant_alternative; 101 102 template
103 struct variant_alternative<_Np, variant<_First, _Rest...>> 104 : variant_alternative<_Np-1, variant<_Rest...>> {}; 105 106 template
107 struct variant_alternative<0, variant<_First, _Rest...>> 108 { using type = _First; }; 109 110 template
111 using variant_alternative_t = 112 typename variant_alternative<_Np, _Variant>::type; 113 114 template
115 struct variant_alternative<_Np, const _Variant> 116 { using type = add_const_t
>; }; 117 118 template
119 struct variant_alternative<_Np, volatile _Variant> 120 { using type = add_volatile_t
>; }; 121 122 template
123 struct variant_alternative<_Np, const volatile _Variant> 124 { using type = add_cv_t
>; }; 125 126 inline constexpr size_t variant_npos = -1; 127 128 template
129 constexpr variant_alternative_t<_Np, variant<_Types...>>& 130 get(variant<_Types...>&); 131 132 template
133 constexpr variant_alternative_t<_Np, variant<_Types...>>&& 134 get(variant<_Types...>&&); 135 136 template
137 constexpr variant_alternative_t<_Np, variant<_Types...>> const& 138 get(const variant<_Types...>&); 139 140 template
141 constexpr variant_alternative_t<_Np, variant<_Types...>> const&& 142 get(const variant<_Types...>&&); 143 144 template
145 constexpr decltype(auto) 146 __do_visit(_Visitor&& __visitor, _Variants&&... __variants); 147 148 template
149 decltype(auto) 150 __variant_cast(_Tp&& __rhs) 151 { 152 if constexpr (is_lvalue_reference_v<_Tp>) 153 { 154 if constexpr (is_const_v
>) 155 return static_cast
&>(__rhs); 156 else 157 return static_cast
&>(__rhs); 158 } 159 else 160 return static_cast
&&>(__rhs); 161 } 162 163 namespace __detail 164 { 165 namespace __variant 166 { 167 // Returns the first appearance of _Tp in _Types. 168 // Returns sizeof...(_Types) if _Tp is not in _Types. 169 template
170 struct __index_of : std::integral_constant
{}; 171 172 template
173 inline constexpr size_t __index_of_v = __index_of<_Tp, _Types...>::value; 174 175 template
176 struct __index_of<_Tp, _First, _Rest...> : 177 std::integral_constant
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
struct __deduce_visit_result { using type = _Tp; }; 186 187 // Visit variants that might be valueless. 188 template
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
198 constexpr void 199 __raw_idx_visit(_Visitor&& __visitor, _Variants&&... __variants) 200 { 201 std::__do_visit<__variant_idx_cookie>(std::forward<_Visitor>(__visitor), 202 std::forward<_Variants>(__variants)...); 203 } 204 205 // The __as function templates implement the exposition-only "as-variant" 206 207 template
208 constexpr std::variant<_Types...>& 209 __as(std::variant<_Types...>& __v) noexcept 210 { return __v; } 211 212 template
213 constexpr const std::variant<_Types...>& 214 __as(const std::variant<_Types...>& __v) noexcept 215 { return __v; } 216 217 template
218 constexpr std::variant<_Types...>&& 219 __as(std::variant<_Types...>&& __v) noexcept 220 { return std::move(__v); } 221 222 template
223 constexpr const std::variant<_Types...>&& 224 __as(const std::variant<_Types...>&& __v) noexcept 225 { return std::move(__v); } 226 227 // _Uninitialized
is guaranteed to be a trivially destructible type, 228 // even if T is not. 229 template
> 230 struct _Uninitialized; 231 232 template
233 struct _Uninitialized<_Type, true> 234 { 235 template
236 constexpr 237 _Uninitialized(in_place_index_t<0>, _Args&&... __args) 238 : _M_storage(std::forward<_Args>(__args)...) 239 { } 240 241 constexpr const _Type& _M_get() const & noexcept 242 { return _M_storage; } 243 244 constexpr _Type& _M_get() & noexcept 245 { return _M_storage; } 246 247 constexpr const _Type&& _M_get() const && noexcept 248 { return std::move(_M_storage); } 249 250 constexpr _Type&& _M_get() && noexcept 251 { return std::move(_M_storage); } 252 253 _Type _M_storage; 254 }; 255 256 template
257 struct _Uninitialized<_Type, false> 258 { 259 template
260 constexpr 261 _Uninitialized(in_place_index_t<0>, _Args&&... __args) 262 { 263 ::new ((void*)std::addressof(_M_storage)) 264 _Type(std::forward<_Args>(__args)...); 265 } 266 267 const _Type& _M_get() const & noexcept 268 { return *_M_storage._M_ptr(); } 269 270 _Type& _M_get() & noexcept 271 { return *_M_storage._M_ptr(); } 272 273 const _Type&& _M_get() const && noexcept 274 { return std::move(*_M_storage._M_ptr()); } 275 276 _Type&& _M_get() && noexcept 277 { return std::move(*_M_storage._M_ptr()); } 278 279 __gnu_cxx::__aligned_membuf<_Type> _M_storage; 280 }; 281 282 template
283 constexpr decltype(auto) 284 __get(in_place_index_t<0>, _Union&& __u) noexcept 285 { return std::forward<_Union>(__u)._M_first._M_get(); } 286 287 template
288 constexpr decltype(auto) 289 __get(in_place_index_t<_Np>, _Union&& __u) noexcept 290 { 291 return __variant::__get(in_place_index<_Np-1>, 292 std::forward<_Union>(__u)._M_rest); 293 } 294 295 // Returns the typed storage for __v. 296 template
297 constexpr decltype(auto) 298 __get(_Variant&& __v) noexcept 299 { 300 return __variant::__get(std::in_place_index<_Np>, 301 std::forward<_Variant>(__v)._M_u); 302 } 303 304 template
305 struct _Traits 306 { 307 static constexpr bool _S_default_ctor = 308 is_default_constructible_v
::type>; 309 static constexpr bool _S_copy_ctor = 310 (is_copy_constructible_v<_Types> && ...); 311 static constexpr bool _S_move_ctor = 312 (is_move_constructible_v<_Types> && ...); 313 static constexpr bool _S_copy_assign = 314 _S_copy_ctor 315 && (is_copy_assignable_v<_Types> && ...); 316 static constexpr bool _S_move_assign = 317 _S_move_ctor 318 && (is_move_assignable_v<_Types> && ...); 319 320 static constexpr bool _S_trivial_dtor = 321 (is_trivially_destructible_v<_Types> && ...); 322 static constexpr bool _S_trivial_copy_ctor = 323 (is_trivially_copy_constructible_v<_Types> && ...); 324 static constexpr bool _S_trivial_move_ctor = 325 (is_trivially_move_constructible_v<_Types> && ...); 326 static constexpr bool _S_trivial_copy_assign = 327 _S_trivial_dtor && _S_trivial_copy_ctor 328 && (is_trivially_copy_assignable_v<_Types> && ...); 329 static constexpr bool _S_trivial_move_assign = 330 _S_trivial_dtor && _S_trivial_move_ctor 331 && (is_trivially_move_assignable_v<_Types> && ...); 332 333 // The following nothrow traits are for non-trivial SMFs. Trivial SMFs 334 // are always nothrow. 335 static constexpr bool _S_nothrow_default_ctor = 336 is_nothrow_default_constructible_v< 337 typename _Nth_type<0, _Types...>::type>; 338 static constexpr bool _S_nothrow_copy_ctor = false; 339 static constexpr bool _S_nothrow_move_ctor = 340 (is_nothrow_move_constructible_v<_Types> && ...); 341 static constexpr bool _S_nothrow_copy_assign = false; 342 static constexpr bool _S_nothrow_move_assign = 343 _S_nothrow_move_ctor 344 && (is_nothrow_move_assignable_v<_Types> && ...); 345 }; 346 347 // Defines members and ctors. 348 template
349 union _Variadic_union { }; 350 351 template
352 union _Variadic_union<_First, _Rest...> 353 { 354 constexpr _Variadic_union() : _M_rest() { } 355 356 template
357 constexpr _Variadic_union(in_place_index_t<0>, _Args&&... __args) 358 : _M_first(in_place_index<0>, std::forward<_Args>(__args)...) 359 { } 360 361 template
362 constexpr _Variadic_union(in_place_index_t<_Np>, _Args&&... __args) 363 : _M_rest(in_place_index<_Np-1>, std::forward<_Args>(__args)...) 364 { } 365 366 _Uninitialized<_First> _M_first; 367 _Variadic_union<_Rest...> _M_rest; 368 }; 369 370 // _Never_valueless_alt is true for variant alternatives that can 371 // always be placed in a variant without it becoming valueless. 372 373 // For suitably-small, trivially copyable types we can create temporaries 374 // on the stack and then memcpy them into place. 375 template
376 struct _Never_valueless_alt 377 : __and_
, is_trivially_copyable<_Tp>> 378 { }; 379 380 // Specialize _Never_valueless_alt for other types which have a 381 // non-throwing and cheap move construction and move assignment operator, 382 // so that emplacing the type will provide the strong exception-safety 383 // guarantee, by creating and moving a temporary. 384 // Whether _Never_valueless_alt
is true or not affects the ABI of a 385 // variant using that alternative, so we can't change the value later! 386 387 // True if every alternative in _Types... can be emplaced in a variant 388 // without it becoming valueless. If this is true, variant<_Types...> 389 // can never be valueless, which enables some minor optimizations. 390 template
391 constexpr bool __never_valueless() 392 { 393 return _Traits<_Types...>::_S_move_assign 394 && (_Never_valueless_alt<_Types>::value && ...); 395 } 396 397 // Defines index and the dtor, possibly trivial. 398 template
399 struct _Variant_storage; 400 401 template
402 using __select_index = 403 typename __select_int::_Select_int_base
::type::value_type; 406 407 template
408 struct _Variant_storage
409 { 410 constexpr 411 _Variant_storage() 412 : _M_index(static_cast<__index_type>(variant_npos)) 413 { } 414 415 template
416 constexpr 417 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) 418 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...), 419 _M_index{_Np} 420 { } 421 422 void _M_reset() 423 { 424 if (!_M_valid()) [[unlikely]] 425 return; 426 427 std::__do_visit
([](auto&& __this_mem) mutable 428 { 429 std::_Destroy(std::__addressof(__this_mem)); 430 }, __variant_cast<_Types...>(*this)); 431 432 _M_index = static_cast<__index_type>(variant_npos); 433 } 434 435 ~_Variant_storage() 436 { _M_reset(); } 437 438 constexpr bool 439 _M_valid() const noexcept 440 { 441 if constexpr (__variant::__never_valueless<_Types...>()) 442 return true; 443 return this->_M_index != __index_type(variant_npos); 444 } 445 446 _Variadic_union<_Types...> _M_u; 447 using __index_type = __select_index<_Types...>; 448 __index_type _M_index; 449 }; 450 451 template
452 struct _Variant_storage
453 { 454 constexpr 455 _Variant_storage() 456 : _M_index(static_cast<__index_type>(variant_npos)) 457 { } 458 459 template
460 constexpr 461 _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) 462 : _M_u(in_place_index<_Np>, std::forward<_Args>(__args)...), 463 _M_index{_Np} 464 { } 465 466 void _M_reset() noexcept 467 { _M_index = static_cast<__index_type>(variant_npos); } 468 469 constexpr bool 470 _M_valid() const noexcept 471 { 472 if constexpr (__variant::__never_valueless<_Types...>()) 473 return true; 474 return this->_M_index != static_cast<__index_type>(variant_npos); 475 } 476 477 _Variadic_union<_Types...> _M_u; 478 using __index_type = __select_index<_Types...>; 479 __index_type _M_index; 480 }; 481 482 template
483 using _Variant_storage_alias = 484 _Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>; 485 486 template
487 void __variant_construct_single(_Tp&& __lhs, _Up&& __rhs_mem) 488 { 489 void* __storage = std::addressof(__lhs._M_u); 490 using _Type = remove_reference_t
; 491 if constexpr (!is_same_v<_Type, __variant_cookie>) 492 ::new (__storage) 493 _Type(std::forward
(__rhs_mem)); 494 } 495 496 template
497 void __variant_construct(_Tp&& __lhs, _Up&& __rhs) 498 { 499 __lhs._M_index = __rhs._M_index; 500 __variant::__raw_visit([&__lhs](auto&& __rhs_mem) mutable 501 { 502 __variant_construct_single(std::forward<_Tp>(__lhs), 503 std::forward
(__rhs_mem)); 504 }, __variant_cast<_Types...>(std::forward<_Up>(__rhs))); 505 } 506 507 // The following are (Copy|Move) (ctor|assign) layers for forwarding 508 // triviality and handling non-trivial SMF behaviors. 509 510 template
511 struct _Copy_ctor_base : _Variant_storage_alias<_Types...> 512 { 513 using _Base = _Variant_storage_alias<_Types...>; 514 using _Base::_Base; 515 516 _Copy_ctor_base(const _Copy_ctor_base& __rhs) 517 noexcept(_Traits<_Types...>::_S_nothrow_copy_ctor) 518 { 519 __variant_construct<_Types...>(*this, __rhs); 520 } 521 522 _Copy_ctor_base(_Copy_ctor_base&&) = default; 523 _Copy_ctor_base& operator=(const _Copy_ctor_base&) = default; 524 _Copy_ctor_base& operator=(_Copy_ctor_base&&) = default; 525 }; 526 527 template
528 struct _Copy_ctor_base
: _Variant_storage_alias<_Types...> 529 { 530 using _Base = _Variant_storage_alias<_Types...>; 531 using _Base::_Base; 532 }; 533 534 template
535 using _Copy_ctor_alias = 536 _Copy_ctor_base<_Traits<_Types...>::_S_trivial_copy_ctor, _Types...>; 537 538 template
539 struct _Move_ctor_base : _Copy_ctor_alias<_Types...> 540 { 541 using _Base = _Copy_ctor_alias<_Types...>; 542 using _Base::_Base; 543 544 _Move_ctor_base(_Move_ctor_base&& __rhs) 545 noexcept(_Traits<_Types...>::_S_nothrow_move_ctor) 546 { 547 __variant_construct<_Types...>(*this, std::move(__rhs)); 548 } 549 550 template
551 void _M_destructive_move(unsigned short __rhs_index, _Up&& __rhs) 552 { 553 this->_M_reset(); 554 __variant_construct_single(*this, std::forward<_Up>(__rhs)); 555 this->_M_index = __rhs_index; 556 } 557 558 template
559 void _M_destructive_copy(unsigned short __rhs_index, const _Up& __rhs) 560 { 561 this->_M_reset(); 562 __variant_construct_single(*this, __rhs); 563 this->_M_index = __rhs_index; 564 } 565 566 _Move_ctor_base(const _Move_ctor_base&) = default; 567 _Move_ctor_base& operator=(const _Move_ctor_base&) = default; 568 _Move_ctor_base& operator=(_Move_ctor_base&&) = default; 569 }; 570 571 template
572 struct _Move_ctor_base
: _Copy_ctor_alias<_Types...> 573 { 574 using _Base = _Copy_ctor_alias<_Types...>; 575 using _Base::_Base; 576 577 template
578 void _M_destructive_move(unsigned short __rhs_index, _Up&& __rhs) 579 { 580 this->_M_reset(); 581 __variant_construct_single(*this, std::forward<_Up>(__rhs)); 582 this->_M_index = __rhs_index; 583 } 584 585 template
586 void _M_destructive_copy(unsigned short __rhs_index, const _Up& __rhs) 587 { 588 this->_M_reset(); 589 __variant_construct_single(*this, __rhs); 590 this->_M_index = __rhs_index; 591 } 592 }; 593 594 template
595 using _Move_ctor_alias = 596 _Move_ctor_base<_Traits<_Types...>::_S_trivial_move_ctor, _Types...>; 597 598 template
599 struct _Copy_assign_base : _Move_ctor_alias<_Types...> 600 { 601 using _Base = _Move_ctor_alias<_Types...>; 602 using _Base::_Base; 603 604 _Copy_assign_base& 605 operator=(const _Copy_assign_base& __rhs) 606 noexcept(_Traits<_Types...>::_S_nothrow_copy_assign) 607 { 608 __variant::__raw_idx_visit( 609 [this](auto&& __rhs_mem, auto __rhs_index) mutable 610 { 611 if constexpr (__rhs_index != variant_npos) 612 { 613 if (this->_M_index == __rhs_index) 614 __variant::__get<__rhs_index>(*this) = __rhs_mem; 615 else 616 { 617 using __rhs_type = __remove_cvref_t
; 618 if constexpr (is_nothrow_copy_constructible_v<__rhs_type> 619 || !is_nothrow_move_constructible_v<__rhs_type>) 620 // The standard says this->emplace<__rhs_type>(__rhs_mem) 621 // should be used here, but _M_destructive_copy is 622 // equivalent in this case. Either copy construction 623 // doesn't throw, so _M_destructive_copy gives strong 624 // exception safety guarantee, or both copy construction 625 // and move construction can throw, so emplace only gives 626 // basic exception safety anyway. 627 this->_M_destructive_copy(__rhs_index, __rhs_mem); 628 else 629 __variant_cast<_Types...>(*this) 630 = variant<_Types...>(std::in_place_index<__rhs_index>, 631 __rhs_mem); 632 } 633 } 634 else 635 this->_M_reset(); 636 }, __variant_cast<_Types...>(__rhs)); 637 return *this; 638 } 639 640 _Copy_assign_base(const _Copy_assign_base&) = default; 641 _Copy_assign_base(_Copy_assign_base&&) = default; 642 _Copy_assign_base& operator=(_Copy_assign_base&&) = default; 643 }; 644 645 template
646 struct _Copy_assign_base
: _Move_ctor_alias<_Types...> 647 { 648 using _Base = _Move_ctor_alias<_Types...>; 649 using _Base::_Base; 650 }; 651 652 template
653 using _Copy_assign_alias = 654 _Copy_assign_base<_Traits<_Types...>::_S_trivial_copy_assign, _Types...>; 655 656 template
657 struct _Move_assign_base : _Copy_assign_alias<_Types...> 658 { 659 using _Base = _Copy_assign_alias<_Types...>; 660 using _Base::_Base; 661 662 _Move_assign_base& 663 operator=(_Move_assign_base&& __rhs) 664 noexcept(_Traits<_Types...>::_S_nothrow_move_assign) 665 { 666 __variant::__raw_idx_visit( 667 [this](auto&& __rhs_mem, auto __rhs_index) mutable 668 { 669 if constexpr (__rhs_index != variant_npos) 670 { 671 if (this->_M_index == __rhs_index) 672 __variant::__get<__rhs_index>(*this) = std::move(__rhs_mem); 673 else 674 __variant_cast<_Types...>(*this) 675 .template emplace<__rhs_index>(std::move(__rhs_mem)); 676 } 677 else 678 this->_M_reset(); 679 }, __variant_cast<_Types...>(__rhs)); 680 return *this; 681 } 682 683 _Move_assign_base(const _Move_assign_base&) = default; 684 _Move_assign_base(_Move_assign_base&&) = default; 685 _Move_assign_base& operator=(const _Move_assign_base&) = default; 686 }; 687 688 template
689 struct _Move_assign_base
: _Copy_assign_alias<_Types...> 690 { 691 using _Base = _Copy_assign_alias<_Types...>; 692 using _Base::_Base; 693 }; 694 695 template
696 using _Move_assign_alias = 697 _Move_assign_base<_Traits<_Types...>::_S_trivial_move_assign, _Types...>; 698 699 template
700 struct _Variant_base : _Move_assign_alias<_Types...> 701 { 702 using _Base = _Move_assign_alias<_Types...>; 703 704 constexpr 705 _Variant_base() 706 noexcept(_Traits<_Types...>::_S_nothrow_default_ctor) 707 : _Variant_base(in_place_index<0>) { } 708 709 template
710 constexpr explicit 711 _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args) 712 : _Base(__i, std::forward<_Args>(__args)...) 713 { } 714 715 _Variant_base(const _Variant_base&) = default; 716 _Variant_base(_Variant_base&&) = default; 717 _Variant_base& operator=(const _Variant_base&) = default; 718 _Variant_base& operator=(_Variant_base&&) = default; 719 }; 720 721 // For how many times does _Tp appear in _Tuple? 722 template
723 struct __tuple_count; 724 725 template
726 inline constexpr size_t __tuple_count_v = 727 __tuple_count<_Tp, _Tuple>::value; 728 729 template
730 struct __tuple_count<_Tp, tuple<_Types...>> 731 : integral_constant
{ }; 732 733 template
734 struct __tuple_count<_Tp, tuple<_First, _Rest...>> 735 : integral_constant< 736 size_t, 737 __tuple_count_v<_Tp, tuple<_Rest...>> + is_same_v<_Tp, _First>> { }; 738 739 // TODO: Reuse this in
? 740 template
741 inline constexpr bool __exactly_once = 742 __tuple_count_v<_Tp, tuple<_Types...>> == 1; 743 744 // Helper used to check for valid conversions that don't involve narrowing. 745 template
struct _Arr { _Ti _M_x[1]; }; 746 747 // "Build an imaginary function FUN(Ti) for each alternative type Ti" 748 template
749 struct _Build_FUN 750 { 751 // This function means 'using _Build_FUN
::_S_fun;' is valid, 752 // but only static functions will be considered in the call below. 753 void _S_fun(); 754 }; 755 756 // "... for which Ti x[] = {std::forward
(t)}; is well-formed." 757 template
758 struct _Build_FUN<_Ind, _Tp, _Ti, 759 void_t
{{std::declval<_Tp>()}})>> 760 { 761 // This is the FUN function for type _Ti, with index _Ind 762 static integral_constant
_S_fun(_Ti); 763 }; 764 765 template
>> 767 struct _Build_FUNs; 768 769 template
770 struct _Build_FUNs<_Tp, variant<_Ti...>, index_sequence<_Ind...>> 771 : _Build_FUN<_Ind, _Tp, _Ti>... 772 { 773 using _Build_FUN<_Ind, _Tp, _Ti>::_S_fun...; 774 }; 775 776 // The index j of the overload FUN(Tj) selected by overload resolution 777 // for FUN(std::forward<_Tp>(t)) 778 template
779 using _FUN_type 780 = decltype(_Build_FUNs<_Tp, _Variant>::_S_fun(std::declval<_Tp>())); 781 782 // The index selected for FUN(std::forward
(t)), or variant_npos if none. 783 template
784 struct __accepted_index 785 : integral_constant
786 { }; 787 788 template
789 struct __accepted_index<_Tp, _Variant, void_t<_FUN_type<_Tp, _Variant>>> 790 : _FUN_type<_Tp, _Variant> 791 { }; 792 793 template
794 struct _Extra_visit_slot_needed 795 { 796 template
struct _Variant_never_valueless; 797 798 template
799 struct _Variant_never_valueless
> 800 : bool_constant<__variant::__never_valueless<_Types...>()> {}; 801 802 static constexpr bool value = 803 (is_same_v<_Maybe_variant_cookie, __variant_cookie> 804 || is_same_v<_Maybe_variant_cookie, __variant_idx_cookie>) 805 && !_Variant_never_valueless<__remove_cvref_t<_Variant>>::value; 806 }; 807 808 // Used for storing a multi-dimensional vtable. 809 template
810 struct _Multi_array; 811 812 // Partial specialization with rank zero, stores a single _Tp element. 813 template
814 struct _Multi_array<_Tp> 815 { 816 template
817 struct __untag_result 818 : false_type 819 { using element_type = _Tp; }; 820 821 template
822 struct __untag_result
823 : false_type 824 { using element_type = void(*)(_Args...); }; 825 826 template
827 struct __untag_result<__variant_cookie(*)(_Args...)> 828 : false_type 829 { using element_type = void(*)(_Args...); }; 830 831 template
832 struct __untag_result<__variant_idx_cookie(*)(_Args...)> 833 : false_type 834 { using element_type = void(*)(_Args...); }; 835 836 template
837 struct __untag_result<__deduce_visit_result<_Res>(*)(_Args...)> 838 : true_type 839 { using element_type = _Res(*)(_Args...); }; 840 841 using __result_is_deduced = __untag_result<_Tp>; 842 843 constexpr const typename __untag_result<_Tp>::element_type& 844 _M_access() const 845 { return _M_data; } 846 847 typename __untag_result<_Tp>::element_type _M_data; 848 }; 849 850 // Partial specialization with rank >= 1. 851 template
855 struct _Multi_array<_Ret(*)(_Visitor, _Variants...), __first, __rest...> 856 { 857 static constexpr size_t __index = 858 sizeof...(_Variants) - sizeof...(__rest) - 1; 859 860 using _Variant = typename _Nth_type<__index, _Variants...>::type; 861 862 static constexpr int __do_cookie = 863 _Extra_visit_slot_needed<_Ret, _Variant>::value ? 1 : 0; 864 865 using _Tp = _Ret(*)(_Visitor, _Variants...); 866 867 template
868 constexpr decltype(auto) 869 _M_access(size_t __first_index, _Args... __rest_indices) const 870 { 871 return _M_arr[__first_index + __do_cookie] 872 ._M_access(__rest_indices...); 873 } 874 875 _Multi_array<_Tp, __rest...> _M_arr[__first + __do_cookie]; 876 }; 877 878 // Creates a multi-dimensional vtable recursively. 879 // 880 // For example, 881 // visit([](auto, auto){}, 882 // variant
(), // typedef'ed as V1 883 // variant
()) // typedef'ed as V2 884 // will trigger instantiations of: 885 // __gen_vtable_impl<_Multi_array
, 886 // tuple
, std::index_sequence<>> 887 // __gen_vtable_impl<_Multi_array
, 888 // tuple
, std::index_sequence<0>> 889 // __gen_vtable_impl<_Multi_array
, 890 // tuple
, std::index_sequence<0, 0>> 891 // __gen_vtable_impl<_Multi_array
, 892 // tuple
, std::index_sequence<0, 1>> 893 // __gen_vtable_impl<_Multi_array
, 894 // tuple
, std::index_sequence<0, 2>> 895 // __gen_vtable_impl<_Multi_array
, 896 // tuple
, std::index_sequence<1>> 897 // __gen_vtable_impl<_Multi_array
, 898 // tuple
, std::index_sequence<1, 0>> 899 // __gen_vtable_impl<_Multi_array
, 900 // tuple
, std::index_sequence<1, 1>> 901 // __gen_vtable_impl<_Multi_array
, 902 // tuple
, std::index_sequence<1, 2>> 903 // The returned multi-dimensional vtable can be fast accessed by the visitor 904 // using index calculation. 905 template
906 struct __gen_vtable_impl; 907 908 // Defines the _S_apply() member that returns a _Multi_array populated 909 // with function pointers that perform the visitation expressions e(m) 910 // for each valid pack of indexes into the variant types _Variants. 911 // 912 // This partial specialization builds up the index sequences by recursively 913 // calling _S_apply() on the next specialization of __gen_vtable_impl. 914 // The base case of the recursion defines the actual function pointers. 915 template
917 struct __gen_vtable_impl< 918 _Multi_array<_Result_type (*)(_Visitor, _Variants...), __dimensions...>, 919 std::index_sequence<__indices...>> 920 { 921 using _Next = 922 remove_reference_t
::type>; 924 using _Array_type = 925 _Multi_array<_Result_type (*)(_Visitor, _Variants...), 926 __dimensions...>; 927 928 static constexpr _Array_type 929 _S_apply() 930 { 931 _Array_type __vtable{}; 932 _S_apply_all_alts( 933 __vtable, make_index_sequence
>()); 934 return __vtable; 935 } 936 937 template
938 static constexpr void 939 _S_apply_all_alts(_Array_type& __vtable, 940 std::index_sequence<__var_indices...>) 941 { 942 if constexpr (_Extra_visit_slot_needed<_Result_type, _Next>::value) 943 (_S_apply_single_alt
( 944 __vtable._M_arr[__var_indices + 1], 945 &(__vtable._M_arr[0])), ...); 946 else 947 (_S_apply_single_alt
( 948 __vtable._M_arr[__var_indices]), ...); 949 } 950 951 template
952 static constexpr void 953 _S_apply_single_alt(_Tp& __element, _Tp* __cookie_element = nullptr) 954 { 955 if constexpr (__do_cookie) 956 { 957 __element = __gen_vtable_impl< 958 _Tp, 959 std::index_sequence<__indices..., __index>>::_S_apply(); 960 *__cookie_element = __gen_vtable_impl< 961 _Tp, 962 std::index_sequence<__indices..., variant_npos>>::_S_apply(); 963 } 964 else 965 { 966 auto __tmp_element = __gen_vtable_impl< 967 remove_reference_t
, 968 std::index_sequence<__indices..., __index>>::_S_apply(); 969 static_assert(is_same_v<_Tp, decltype(__tmp_element)>, 970 "std::visit requires the visitor to have the same " 971 "return type for all alternatives of a variant"); 972 __element = __tmp_element; 973 } 974 } 975 }; 976 977 // This partial specialization is the base case for the recursion. 978 // It populates a _Multi_array element with the address of a function 979 // that invokes the visitor with the alternatives specified by __indices. 980 template
982 struct __gen_vtable_impl< 983 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>, 984 std::index_sequence<__indices...>> 985 { 986 using _Array_type = 987 _Multi_array<_Result_type (*)(_Visitor, _Variants...)>; 988 989 template
990 static constexpr decltype(auto) 991 __element_by_index_or_cookie(_Variant&& __var) noexcept 992 { 993 if constexpr (__index != variant_npos) 994 return __variant::__get<__index>(std::forward<_Variant>(__var)); 995 else 996 return __variant_cookie{}; 997 } 998 999 static constexpr decltype(auto) 1000 __visit_invoke(_Visitor&& __visitor, _Variants... __vars) 1001 { 1002 if constexpr (is_same_v<_Result_type, __variant_idx_cookie>) 1003 // For raw visitation using indices, pass the indices to the visitor 1004 // and discard the return value: 1005 std::__invoke(std::forward<_Visitor>(__visitor), 1006 __element_by_index_or_cookie<__indices>( 1007 std::forward<_Variants>(__vars))..., 1008 integral_constant
()...); 1009 else if constexpr (is_same_v<_Result_type, __variant_cookie>) 1010 // For raw visitation without indices, and discard the return value: 1011 std::__invoke(std::forward<_Visitor>(__visitor), 1012 __element_by_index_or_cookie<__indices>( 1013 std::forward<_Variants>(__vars))...); 1014 else if constexpr (_Array_type::__result_is_deduced::value) 1015 // For the usual std::visit case deduce the return value: 1016 return std::__invoke(std::forward<_Visitor>(__visitor), 1017 __element_by_index_or_cookie<__indices>( 1018 std::forward<_Variants>(__vars))...); 1019 else // for std::visit
use INVOKE
1020 return std::__invoke_r<_Result_type>( 1021 std::forward<_Visitor>(__visitor), 1022 __variant::__get<__indices>(std::forward<_Variants>(__vars))...); 1023 } 1024 1025 static constexpr auto 1026 _S_apply() 1027 { 1028 if constexpr (_Array_type::__result_is_deduced::value) 1029 { 1030 constexpr bool __visit_ret_type_mismatch = 1031 !is_same_v
(), 1033 std::declval<_Variants>()...))>; 1034 if constexpr (__visit_ret_type_mismatch) 1035 { 1036 struct __cannot_match {}; 1037 return __cannot_match{}; 1038 } 1039 else 1040 return _Array_type{&__visit_invoke}; 1041 } 1042 else 1043 return _Array_type{&__visit_invoke}; 1044 } 1045 }; 1046 1047 template
1048 struct __gen_vtable 1049 { 1050 using _Array_type = 1051 _Multi_array<_Result_type (*)(_Visitor, _Variants...), 1052 variant_size_v
>...>; 1053 1054 static constexpr _Array_type _S_vtable 1055 = __gen_vtable_impl<_Array_type, std::index_sequence<>>::_S_apply(); 1056 }; 1057 1058 template
1059 struct _Base_dedup : public _Tp { }; 1060 1061 template
1062 struct _Variant_hash_base; 1063 1064 template
1065 struct _Variant_hash_base
, 1066 std::index_sequence<__indices...>> 1067 : _Base_dedup<__indices, __poison_hash
>>... { }; 1068 1069 // Equivalent to decltype(get<_Np>(as-variant(declval<_Variant>()))) 1070 template
())), 1072 typename _Tp = variant_alternative_t<_Np, remove_reference_t<_AsV>>> 1073 using __get_t 1074 = conditional_t
, _Tp&, _Tp&&>; 1075 1076 // Return type of std::visit. 1077 template
1078 using __visit_result_t 1079 = invoke_result_t<_Visitor, __get_t<0, _Variants>...>; 1080 1081 template
1082 constexpr inline bool __same_types = (is_same_v<_Tp, _Types> && ...); 1083 1084 template
1085 constexpr bool __check_visitor_results(std::index_sequence<_Idxs...>) 1086 { 1087 return __same_types< 1088 invoke_result_t<_Visitor, __get_t<_Idxs, _Variant>>... 1089 >; 1090 } 1091 1092 template
1093 inline void 1094 __construct_by_index(_Variant& __v, _Args&&... __args) 1095 { 1096 auto&& __storage = __detail::__variant::__get<_Np>(__v); 1097 ::new ((void*)std::addressof(__storage)) 1098 remove_reference_t
1099 (std::forward<_Args>(__args)...); 1100 // Construction didn't throw, so can set the new index now: 1101 __v._M_index = _Np; 1102 } 1103 1104 } // namespace __variant 1105 } // namespace __detail 1106 1107 template
1108 constexpr bool 1109 holds_alternative(const variant<_Types...>& __v) noexcept 1110 { 1111 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1112 "T must occur exactly once in alternatives"); 1113 return __v.index() == __detail::__variant::__index_of_v<_Tp, _Types...>; 1114 } 1115 1116 template
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...>>(__v); 1123 } 1124 1125 template
1126 constexpr _Tp&& get(variant<_Types...>&& __v) 1127 { 1128 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1129 "T must occur exactly once in alternatives"); 1130 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1131 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( 1132 std::move(__v)); 1133 } 1134 1135 template
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...>>(__v); 1142 } 1143 1144 template
1145 constexpr const _Tp&& get(const variant<_Types...>&& __v) 1146 { 1147 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1148 "T must occur exactly once in alternatives"); 1149 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1150 return std::get<__detail::__variant::__index_of_v<_Tp, _Types...>>( 1151 std::move(__v)); 1152 } 1153 1154 template
1155 constexpr add_pointer_t
>> 1156 get_if(variant<_Types...>* __ptr) noexcept 1157 { 1158 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; 1159 static_assert(_Np < sizeof...(_Types), 1160 "The index must be in [0, number of alternatives)"); 1161 static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void"); 1162 if (__ptr && __ptr->index() == _Np) 1163 return std::addressof(__detail::__variant::__get<_Np>(*__ptr)); 1164 return nullptr; 1165 } 1166 1167 template
1168 constexpr 1169 add_pointer_t
>> 1170 get_if(const variant<_Types...>* __ptr) noexcept 1171 { 1172 using _Alternative_type = variant_alternative_t<_Np, variant<_Types...>>; 1173 static_assert(_Np < sizeof...(_Types), 1174 "The index must be in [0, number of alternatives)"); 1175 static_assert(!is_void_v<_Alternative_type>, "_Tp must not be void"); 1176 if (__ptr && __ptr->index() == _Np) 1177 return std::addressof(__detail::__variant::__get<_Np>(*__ptr)); 1178 return nullptr; 1179 } 1180 1181 template
1182 constexpr add_pointer_t<_Tp> 1183 get_if(variant<_Types...>* __ptr) noexcept 1184 { 1185 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1186 "T must occur exactly once in alternatives"); 1187 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1188 return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( 1189 __ptr); 1190 } 1191 1192 template
1193 constexpr add_pointer_t
1194 get_if(const variant<_Types...>* __ptr) noexcept 1195 { 1196 static_assert(__detail::__variant::__exactly_once<_Tp, _Types...>, 1197 "T must occur exactly once in alternatives"); 1198 static_assert(!is_void_v<_Tp>, "_Tp must not be void"); 1199 return std::get_if<__detail::__variant::__index_of_v<_Tp, _Types...>>( 1200 __ptr); 1201 } 1202 1203 struct monostate { }; 1204 1205 #define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \ 1206 template
\ 1207 constexpr bool operator __OP(const variant<_Types...>& __lhs, \ 1208 const variant<_Types...>& __rhs) \ 1209 { \ 1210 bool __ret = true; \ 1211 __detail::__variant::__raw_idx_visit( \ 1212 [&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \ 1213 { \ 1214 if constexpr (__rhs_index != variant_npos) \ 1215 { \ 1216 if (__lhs.index() == __rhs_index) \ 1217 { \ 1218 auto& __this_mem = std::get<__rhs_index>(__lhs); \ 1219 __ret = __this_mem __OP __rhs_mem; \ 1220 } \ 1221 else \ 1222 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \ 1223 } \ 1224 else \ 1225 __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \ 1226 }, __rhs); \ 1227 return __ret; \ 1228 } 1229 1230 _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less) 1231 _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal) 1232 _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal) 1233 _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal) 1234 _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal) 1235 _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater) 1236 1237 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE 1238 1239 constexpr bool operator==(monostate, monostate) noexcept { return true; } 1240 1241 #ifdef __cpp_lib_three_way_comparison 1242 template
1243 requires (three_way_comparable<_Types> && ...) 1244 constexpr 1245 common_comparison_category_t
...> 1246 operator<=>(const variant<_Types...>& __v, const variant<_Types...>& __w) 1247 { 1248 common_comparison_category_t
...> __ret 1249 = strong_ordering::equal; 1250 1251 __detail::__variant::__raw_idx_visit( 1252 [&__ret, &__v] (auto&& __w_mem, auto __w_index) mutable 1253 { 1254 if constexpr (__w_index != variant_npos) 1255 { 1256 if (__v.index() == __w_index) 1257 { 1258 auto& __this_mem = std::get<__w_index>(__v); 1259 __ret = __this_mem <=> __w_mem; 1260 return; 1261 } 1262 } 1263 __ret = (__v.index() + 1) <=> (__w_index + 1); 1264 }, __w); 1265 return __ret; 1266 } 1267 1268 constexpr strong_ordering 1269 operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; } 1270 #else 1271 constexpr bool operator!=(monostate, monostate) noexcept { return false; } 1272 constexpr bool operator<(monostate, monostate) noexcept { return false; } 1273 constexpr bool operator>(monostate, monostate) noexcept { return false; } 1274 constexpr bool operator<=(monostate, monostate) noexcept { return true; } 1275 constexpr bool operator>=(monostate, monostate) noexcept { return true; } 1276 #endif 1277 1278 template
1279 constexpr __detail::__variant::__visit_result_t<_Visitor, _Variants...> 1280 visit(_Visitor&&, _Variants&&...); 1281 1282 template
1283 inline enable_if_t<(is_move_constructible_v<_Types> && ...) 1284 && (is_swappable_v<_Types> && ...)> 1285 swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) 1286 noexcept(noexcept(__lhs.swap(__rhs))) 1287 { __lhs.swap(__rhs); } 1288 1289 template
1290 enable_if_t && ...) 1291 && (is_swappable_v<_Types> && ...))> 1292 swap(variant<_Types...>&, variant<_Types...>&) = delete; 1293 1294 class bad_variant_access : public exception 1295 { 1296 public: 1297 bad_variant_access() noexcept { } 1298 1299 const char* what() const noexcept override 1300 { return _M_reason; } 1301 1302 private: 1303 bad_variant_access(const char* __reason) noexcept : _M_reason(__reason) { } 1304 1305 // Must point to a string with static storage duration: 1306 const char* _M_reason = "bad variant access"; 1307 1308 friend void __throw_bad_variant_access(const char* __what); 1309 }; 1310 1311 // Must only be called with a string literal 1312 inline void 1313 __throw_bad_variant_access(const char* __what) 1314 { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); } 1315 1316 inline void 1317 __throw_bad_variant_access(bool __valueless) 1318 { 1319 if (__valueless) [[__unlikely__]] 1320 __throw_bad_variant_access("std::get: variant is valueless"); 1321 else 1322 __throw_bad_variant_access("std::get: wrong index for variant"); 1323 } 1324 1325 template
1326 class variant 1327 : private __detail::__variant::_Variant_base<_Types...>, 1328 private _Enable_default_constructor< 1329 __detail::__variant::_Traits<_Types...>::_S_default_ctor, 1330 variant<_Types...>>, 1331 private _Enable_copy_move< 1332 __detail::__variant::_Traits<_Types...>::_S_copy_ctor, 1333 __detail::__variant::_Traits<_Types...>::_S_copy_assign, 1334 __detail::__variant::_Traits<_Types...>::_S_move_ctor, 1335 __detail::__variant::_Traits<_Types...>::_S_move_assign, 1336 variant<_Types...>> 1337 { 1338 private: 1339 template
1340 friend decltype(auto) __variant_cast(_Tp&&); 1341 template
1342 friend void 1343 __detail::__variant::__construct_by_index(_Variant& __v, 1344 _Args&&... __args); 1345 1346 static_assert(sizeof...(_Types) > 0, 1347 "variant must have at least one alternative"); 1348 static_assert(!(std::is_reference_v<_Types> || ...), 1349 "variant must have no reference alternative"); 1350 static_assert(!(std::is_void_v<_Types> || ...), 1351 "variant must have no void alternative"); 1352 1353 using _Base = __detail::__variant::_Variant_base<_Types...>; 1354 using _Default_ctor_enabler = 1355 _Enable_default_constructor< 1356 __detail::__variant::_Traits<_Types...>::_S_default_ctor, 1357 variant<_Types...>>; 1358 1359 template
1360 static constexpr bool __not_self 1361 = !is_same_v<__remove_cvref_t<_Tp>, variant>; 1362 1363 template
1364 static constexpr bool 1365 __exactly_once = __detail::__variant::__exactly_once<_Tp, _Types...>; 1366 1367 template
1368 static constexpr size_t __accepted_index 1369 = __detail::__variant::__accepted_index<_Tp, variant>::value; 1370 1371 template
> 1372 using __to_type = variant_alternative_t<_Np, variant>; 1373 1374 template
>> 1375 using __accepted_type = __to_type<__accepted_index<_Tp>>; 1376 1377 template
1378 static constexpr size_t __index_of = 1379 __detail::__variant::__index_of_v<_Tp, _Types...>; 1380 1381 using _Traits = __detail::__variant::_Traits<_Types...>; 1382 1383 template
1384 struct __is_in_place_tag : false_type { }; 1385 template
1386 struct __is_in_place_tag
> : true_type { }; 1387 template
1388 struct __is_in_place_tag
> : true_type { }; 1389 1390 template
1391 static constexpr bool __not_in_place_tag 1392 = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value; 1393 1394 public: 1395 variant() = default; 1396 variant(const variant& __rhs) = default; 1397 variant(variant&&) = default; 1398 variant& operator=(const variant&) = default; 1399 variant& operator=(variant&&) = default; 1400 ~variant() = default; 1401 1402 template
, 1404 typename = enable_if_t<__not_in_place_tag<_Tp>>, 1405 typename _Tj = __accepted_type<_Tp&&>, 1406 typename = enable_if_t<__exactly_once<_Tj> 1407 && is_constructible_v<_Tj, _Tp>>> 1408 constexpr 1409 variant(_Tp&& __t) 1410 noexcept(is_nothrow_constructible_v<_Tj, _Tp>) 1411 : variant(in_place_index<__accepted_index<_Tp>>, 1412 std::forward<_Tp>(__t)) 1413 { } 1414 1415 template
1417 && is_constructible_v<_Tp, _Args...>>> 1418 constexpr explicit 1419 variant(in_place_type_t<_Tp>, _Args&&... __args) 1420 : variant(in_place_index<__index_of<_Tp>>, 1421 std::forward<_Args>(__args)...) 1422 { } 1423 1424 template
1426 && is_constructible_v<_Tp, 1427 initializer_list<_Up>&, _Args...>>> 1428 constexpr explicit 1429 variant(in_place_type_t<_Tp>, initializer_list<_Up> __il, 1430 _Args&&... __args) 1431 : variant(in_place_index<__index_of<_Tp>>, __il, 1432 std::forward<_Args>(__args)...) 1433 { } 1434 1435 template
, 1437 typename = enable_if_t
>> 1438 constexpr explicit 1439 variant(in_place_index_t<_Np>, _Args&&... __args) 1440 : _Base(in_place_index<_Np>, std::forward<_Args>(__args)...), 1441 _Default_ctor_enabler(_Enable_default_constructor_tag{}) 1442 { } 1443 1444 template
, 1446 typename = enable_if_t
&, 1448 _Args...>>> 1449 constexpr explicit 1450 variant(in_place_index_t<_Np>, initializer_list<_Up> __il, 1451 _Args&&... __args) 1452 : _Base(in_place_index<_Np>, __il, std::forward<_Args>(__args)...), 1453 _Default_ctor_enabler(_Enable_default_constructor_tag{}) 1454 { } 1455 1456 template
1457 enable_if_t<__exactly_once<__accepted_type<_Tp&&>> 1458 && is_constructible_v<__accepted_type<_Tp&&>, _Tp> 1459 && is_assignable_v<__accepted_type<_Tp&&>&, _Tp>, 1460 variant&> 1461 operator=(_Tp&& __rhs) 1462 noexcept(is_nothrow_assignable_v<__accepted_type<_Tp&&>&, _Tp> 1463 && is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp>) 1464 { 1465 constexpr auto __index = __accepted_index<_Tp>; 1466 if (index() == __index) 1467 std::get<__index>(*this) = std::forward<_Tp>(__rhs); 1468 else 1469 { 1470 using _Tj = __accepted_type<_Tp&&>; 1471 if constexpr (is_nothrow_constructible_v<_Tj, _Tp> 1472 || !is_nothrow_move_constructible_v<_Tj>) 1473 this->emplace<__index>(std::forward<_Tp>(__rhs)); 1474 else 1475 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1476 // 3585. converting assignment with immovable alternative 1477 this->emplace<__index>(_Tj(std::forward<_Tp>(__rhs))); 1478 } 1479 return *this; 1480 } 1481 1482 template
1483 enable_if_t
&& __exactly_once<_Tp>, 1484 _Tp&> 1485 emplace(_Args&&... __args) 1486 { 1487 constexpr size_t __index = __index_of<_Tp>; 1488 return this->emplace<__index>(std::forward<_Args>(__args)...); 1489 } 1490 1491 template
1492 enable_if_t
&, _Args...> 1493 && __exactly_once<_Tp>, 1494 _Tp&> 1495 emplace(initializer_list<_Up> __il, _Args&&... __args) 1496 { 1497 constexpr size_t __index = __index_of<_Tp>; 1498 return this->emplace<__index>(__il, std::forward<_Args>(__args)...); 1499 } 1500 1501 template
1502 enable_if_t
, 1503 _Args...>, 1504 variant_alternative_t<_Np, variant>&> 1505 emplace(_Args&&... __args) 1506 { 1507 static_assert(_Np < sizeof...(_Types), 1508 "The index must be in [0, number of alternatives)"); 1509 using type = variant_alternative_t<_Np, variant>; 1510 namespace __variant = std::__detail::__variant; 1511 // Provide the strong exception-safety guarantee when possible, 1512 // to avoid becoming valueless. 1513 if constexpr (is_nothrow_constructible_v