Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/experimental/optional
$ cat -n /usr/include/c++/13/experimental/optional 1 //
-*- C++ -*- 2 3 // Copyright (C) 2013-2023 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 experimental/optional 26 * This is a TS C++ Library header. 27 * @ingroup libfund-ts 28 */ 29 30 #ifndef _GLIBCXX_EXPERIMENTAL_OPTIONAL 31 #define _GLIBCXX_EXPERIMENTAL_OPTIONAL 1 32 33 #include
// experimental is currently omitted 34 35 #if __cplusplus >= 201402L 36 37 #include
38 #include
39 #include
40 #include
41 #include
42 #include
43 #include
44 #include
45 #include
46 47 namespace std _GLIBCXX_VISIBILITY(default) 48 { 49 _GLIBCXX_BEGIN_NAMESPACE_VERSION 50 51 namespace experimental 52 { 53 inline namespace fundamentals_v1 54 { 55 /** 56 * @defgroup optional Optional values 57 * @ingroup libfund-ts 58 * 59 * Class template for optional values and surrounding facilities, as 60 * described in n3793 "A proposal to add a utility class to represent 61 * optional objects (Revision 5)". 62 * 63 * @{ 64 */ 65 66 #define __cpp_lib_experimental_optional 201411 67 68 // All subsequent [X.Y.n] references are against n3793. 69 70 // [X.Y.4] 71 template
72 class optional; 73 74 // [X.Y.5] 75 /// Tag type for in-place construction. 76 struct in_place_t { }; 77 78 /// Tag for in-place construction. 79 constexpr in_place_t in_place { }; 80 81 // [X.Y.6] 82 /// Tag type to disengage optional objects. 83 struct nullopt_t 84 { 85 // Do not user-declare default constructor at all for 86 // optional_value = {} syntax to work. 87 // nullopt_t() = delete; 88 89 // Used for constructing nullopt. 90 enum class _Construct { _Token }; 91 92 // Must be constexpr for nullopt_t to be literal. 93 explicit constexpr nullopt_t(_Construct) { } 94 }; 95 96 // [X.Y.6] 97 /// Tag to disengage optional objects. 98 constexpr nullopt_t nullopt { nullopt_t::_Construct::_Token }; 99 100 // [X.Y.7] 101 /** 102 * @brief Exception class thrown when a disengaged optional object is 103 * dereferenced. 104 * @ingroup exceptions 105 */ 106 class bad_optional_access : public logic_error 107 { 108 public: 109 bad_optional_access() : logic_error("bad optional access") { } 110 111 // XXX This constructor is non-standard. Should not be inline 112 explicit bad_optional_access(const char* __arg) : logic_error(__arg) { } 113 114 virtual ~bad_optional_access() noexcept = default; 115 }; 116 117 /// @cond undocumented 118 119 // XXX Does not belong here. 120 [[noreturn]] inline void 121 __throw_bad_optional_access(const char* __s) 122 { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); } 123 124 /** 125 * @brief Class template that holds the necessary state for @ref optional 126 * and that has the responsibility for construction and the special members. 127 * 128 * Such a separate base class template is necessary in order to 129 * conditionally enable the special members (e.g. copy/move constructors). 130 * Note that this means that @ref _Optional_base implements the 131 * functionality for copy and move assignment, but not for converting 132 * assignment. 133 * 134 * @see optional, _Enable_special_members 135 */ 136 template
::value> 138 class _Optional_base 139 { 140 private: 141 // Remove const to avoid prohibition of reusing object storage for 142 // const-qualified types in [3.8/9]. This is strictly internal 143 // and even optional itself is oblivious to it. 144 using _Stored_type = remove_const_t<_Tp>; 145 146 public: 147 // [X.Y.4.1] Constructors. 148 149 // Constructors for disengaged optionals. 150 constexpr _Optional_base() noexcept 151 : _M_empty{} { } 152 153 constexpr _Optional_base(nullopt_t) noexcept 154 : _Optional_base{} { } 155 156 // Constructors for engaged optionals. 157 template
158 constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 159 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } 160 161 template
&, 164 _Args&&...>::value, 165 int>...> 166 constexpr explicit _Optional_base(in_place_t, 167 initializer_list<_Up> __il, 168 _Args&&... __args) 169 : _M_payload(__il, std::forward<_Args>(__args)...), 170 _M_engaged(true) { } 171 172 // Copy and move constructors. 173 _Optional_base(const _Optional_base& __other) 174 { 175 if (__other._M_engaged) 176 this->_M_construct(__other._M_get()); 177 } 178 179 _Optional_base(_Optional_base&& __other) 180 noexcept(is_nothrow_move_constructible<_Tp>()) 181 { 182 if (__other._M_engaged) 183 this->_M_construct(std::move(__other._M_get())); 184 } 185 186 // [X.Y.4.3] (partly) Assignment. 187 _Optional_base& 188 operator=(const _Optional_base& __other) 189 { 190 if (this->_M_engaged && __other._M_engaged) 191 this->_M_get() = __other._M_get(); 192 else 193 { 194 if (__other._M_engaged) 195 this->_M_construct(__other._M_get()); 196 else 197 this->_M_reset(); 198 } 199 200 return *this; 201 } 202 203 _Optional_base& 204 operator=(_Optional_base&& __other) 205 noexcept(__and_
, 206 is_nothrow_move_assignable<_Tp>>()) 207 { 208 if (this->_M_engaged && __other._M_engaged) 209 this->_M_get() = std::move(__other._M_get()); 210 else 211 { 212 if (__other._M_engaged) 213 this->_M_construct(std::move(__other._M_get())); 214 else 215 this->_M_reset(); 216 } 217 return *this; 218 } 219 220 // [X.Y.4.2] Destructor. 221 ~_Optional_base() 222 { 223 if (this->_M_engaged) 224 this->_M_payload.~_Stored_type(); 225 } 226 227 // The following functionality is also needed by optional, hence the 228 // protected accessibility. 229 protected: 230 constexpr bool _M_is_engaged() const noexcept 231 { return this->_M_engaged; } 232 233 // The _M_get operations have _M_engaged as a precondition. 234 constexpr _Tp& 235 _M_get() noexcept 236 { return _M_payload; } 237 238 constexpr const _Tp& 239 _M_get() const noexcept 240 { return _M_payload; } 241 242 // The _M_construct operation has !_M_engaged as a precondition 243 // while _M_destruct has _M_engaged as a precondition. 244 template
245 void 246 _M_construct(_Args&&... __args) 247 noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) 248 { 249 ::new (std::__addressof(this->_M_payload)) 250 _Stored_type(std::forward<_Args>(__args)...); 251 this->_M_engaged = true; 252 } 253 254 void 255 _M_destruct() 256 { 257 this->_M_engaged = false; 258 this->_M_payload.~_Stored_type(); 259 } 260 261 // _M_reset is a 'safe' operation with no precondition. 262 void 263 _M_reset() 264 { 265 if (this->_M_engaged) 266 this->_M_destruct(); 267 } 268 269 private: 270 struct _Empty_byte { }; 271 union { 272 _Empty_byte _M_empty; 273 _Stored_type _M_payload; 274 }; 275 bool _M_engaged = false; 276 }; 277 278 /// Partial specialization that is exactly identical to the primary template 279 /// save for not providing a destructor, to fulfill triviality requirements. 280 template
281 class _Optional_base<_Tp, false> 282 { 283 private: 284 using _Stored_type = remove_const_t<_Tp>; 285 286 public: 287 constexpr _Optional_base() noexcept 288 : _M_empty{} { } 289 290 constexpr _Optional_base(nullopt_t) noexcept 291 : _Optional_base{} { } 292 293 template
294 constexpr explicit _Optional_base(in_place_t, _Args&&... __args) 295 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { } 296 297 template
&, 300 _Args&&...>::value, 301 int>...> 302 constexpr explicit _Optional_base(in_place_t, 303 initializer_list<_Up> __il, 304 _Args&&... __args) 305 : _M_payload(__il, std::forward<_Args>(__args)...), 306 _M_engaged(true) { } 307 308 _Optional_base(const _Optional_base& __other) 309 { 310 if (__other._M_engaged) 311 this->_M_construct(__other._M_get()); 312 } 313 314 _Optional_base(_Optional_base&& __other) 315 noexcept(is_nothrow_move_constructible<_Tp>()) 316 { 317 if (__other._M_engaged) 318 this->_M_construct(std::move(__other._M_get())); 319 } 320 321 _Optional_base& 322 operator=(const _Optional_base& __other) 323 { 324 if (this->_M_engaged && __other._M_engaged) 325 this->_M_get() = __other._M_get(); 326 else 327 { 328 if (__other._M_engaged) 329 this->_M_construct(__other._M_get()); 330 else 331 this->_M_reset(); 332 } 333 return *this; 334 } 335 336 _Optional_base& 337 operator=(_Optional_base&& __other) 338 noexcept(__and_
, 339 is_nothrow_move_assignable<_Tp>>()) 340 { 341 if (this->_M_engaged && __other._M_engaged) 342 this->_M_get() = std::move(__other._M_get()); 343 else 344 { 345 if (__other._M_engaged) 346 this->_M_construct(std::move(__other._M_get())); 347 else 348 this->_M_reset(); 349 } 350 return *this; 351 } 352 353 // Sole difference 354 // ~_Optional_base() noexcept = default; 355 356 protected: 357 constexpr bool _M_is_engaged() const noexcept 358 { return this->_M_engaged; } 359 360 _Tp& 361 _M_get() noexcept 362 { return _M_payload; } 363 364 constexpr const _Tp& 365 _M_get() const noexcept 366 { return _M_payload; } 367 368 template
369 void 370 _M_construct(_Args&&... __args) 371 noexcept(is_nothrow_constructible<_Stored_type, _Args...>()) 372 { 373 ::new (std::__addressof(this->_M_payload)) 374 _Stored_type(std::forward<_Args>(__args)...); 375 this->_M_engaged = true; 376 } 377 378 void 379 _M_destruct() 380 { 381 this->_M_engaged = false; 382 this->_M_payload.~_Stored_type(); 383 } 384 385 void 386 _M_reset() 387 { 388 if (this->_M_engaged) 389 this->_M_destruct(); 390 } 391 392 private: 393 struct _Empty_byte { }; 394 union 395 { 396 _Empty_byte _M_empty; 397 _Stored_type _M_payload; 398 }; 399 bool _M_engaged = false; 400 }; 401 402 template
403 using __converts_from_optional = 404 __or_
&>, 405 is_constructible<_Tp, optional<_Up>&>, 406 is_constructible<_Tp, const optional<_Up>&&>, 407 is_constructible<_Tp, optional<_Up>&&>, 408 is_convertible
&, _Tp>, 409 is_convertible
&, _Tp>, 410 is_convertible
&&, _Tp>, 411 is_convertible
&&, _Tp>>; 412 413 template
414 using __assigns_from_optional = 415 __or_
&>, 416 is_assignable<_Tp&, optional<_Up>&>, 417 is_assignable<_Tp&, const optional<_Up>&&>, 418 is_assignable<_Tp&, optional<_Up>&&>>; 419 420 /// @endcond 421 422 /** 423 * @brief Class template for optional values. 424 */ 425 template
426 class optional 427 : private _Optional_base<_Tp>, 428 private _Enable_copy_move< 429 // Copy constructor. 430 is_copy_constructible<_Tp>::value, 431 // Copy assignment. 432 __and_
, is_copy_assignable<_Tp>>::value, 433 // Move constructor. 434 is_move_constructible<_Tp>::value, 435 // Move assignment. 436 __and_
, is_move_assignable<_Tp>>::value, 437 // Unique tag type. 438 optional<_Tp>> 439 { 440 static_assert(__and_<__not_
, nullopt_t>>, 441 __not_
, in_place_t>>, 442 __not_
>>(), 443 "Invalid instantiation of optional
"); 444 445 private: 446 using _Base = _Optional_base<_Tp>; 447 448 public: 449 using value_type = _Tp; 450 451 // _Optional_base has the responsibility for construction. 452 using _Base::_Base; 453 454 constexpr optional() = default; 455 // Converting constructors for engaged optionals. 456 template
, decay_t<_Up>>>, 459 is_constructible<_Tp, _Up&&>, 460 is_convertible<_Up&&, _Tp> 461 >::value, bool> = true> 462 constexpr optional(_Up&& __t) 463 : _Base(in_place, std::forward<_Up>(__t)) { } 464 465 template
, decay_t<_Up>>>, 468 is_constructible<_Tp, _Up&&>, 469 __not_
> 470 >::value, bool> = false> 471 explicit constexpr optional(_Up&& __t) 472 : _Base(in_place, std::forward<_Up>(__t)) { } 473 474 template
>, 477 is_constructible<_Tp, const _Up&>, 478 is_convertible
, 479 __not_<__converts_from_optional<_Tp, _Up>> 480 >::value, bool> = true> 481 constexpr optional(const optional<_Up>& __t) 482 { 483 if (__t) 484 emplace(*__t); 485 } 486 487 template
>, 490 is_constructible<_Tp, const _Up&>, 491 __not_
>, 492 __not_<__converts_from_optional<_Tp, _Up>> 493 >::value, bool> = false> 494 explicit constexpr optional(const optional<_Up>& __t) 495 { 496 if (__t) 497 emplace(*__t); 498 } 499 500 template
>, 503 is_constructible<_Tp, _Up&&>, 504 is_convertible<_Up&&, _Tp>, 505 __not_<__converts_from_optional<_Tp, _Up>> 506 >::value, bool> = true> 507 constexpr optional(optional<_Up>&& __t) 508 { 509 if (__t) 510 emplace(std::move(*__t)); 511 } 512 513 template
>, 516 is_constructible<_Tp, _Up&&>, 517 __not_
>, 518 __not_<__converts_from_optional<_Tp, _Up>> 519 >::value, bool> = false> 520 explicit constexpr optional(optional<_Up>&& __t) 521 { 522 if (__t) 523 emplace(std::move(*__t)); 524 } 525 526 // [X.Y.4.3] (partly) Assignment. 527 optional& 528 operator=(nullopt_t) noexcept 529 { 530 this->_M_reset(); 531 return *this; 532 } 533 534 template
535 enable_if_t<__and_< 536 __not_
, decay_t<_Up>>>, 537 is_constructible<_Tp, _Up>, 538 __not_<__and_
, 539 is_same<_Tp, decay_t<_Up>>>>, 540 is_assignable<_Tp&, _Up>>::value, 541 optional&> 542 operator=(_Up&& __u) 543 { 544 if (this->_M_is_engaged()) 545 this->_M_get() = std::forward<_Up>(__u); 546 else 547 this->_M_construct(std::forward<_Up>(__u)); 548 549 return *this; 550 } 551 552 template
553 enable_if_t<__and_< 554 __not_
>, 555 is_constructible<_Tp, const _Up&>, 556 is_assignable<_Tp&, _Up>, 557 __not_<__converts_from_optional<_Tp, _Up>>, 558 __not_<__assigns_from_optional<_Tp, _Up>> 559 >::value, 560 optional&> 561 operator=(const optional<_Up>& __u) 562 { 563 if (__u) 564 { 565 if (this->_M_is_engaged()) 566 this->_M_get() = *__u; 567 else 568 this->_M_construct(*__u); 569 } 570 else 571 { 572 this->_M_reset(); 573 } 574 return *this; 575 } 576 577 template
578 enable_if_t<__and_< 579 __not_
>, 580 is_constructible<_Tp, _Up>, 581 is_assignable<_Tp&, _Up>, 582 __not_<__converts_from_optional<_Tp, _Up>>, 583 __not_<__assigns_from_optional<_Tp, _Up>> 584 >::value, 585 optional&> 586 operator=(optional<_Up>&& __u) 587 { 588 if (__u) 589 { 590 if (this->_M_is_engaged()) 591 this->_M_get() = std::move(*__u); 592 else 593 this->_M_construct(std::move(*__u)); 594 } 595 else 596 { 597 this->_M_reset(); 598 } 599 600 return *this; 601 } 602 603 template
604 enable_if_t
::value> 605 emplace(_Args&&... __args) 606 { 607 this->_M_reset(); 608 this->_M_construct(std::forward<_Args>(__args)...); 609 } 610 611 template
612 enable_if_t
&, 613 _Args&&...>::value> 614 emplace(initializer_list<_Up> __il, _Args&&... __args) 615 { 616 this->_M_reset(); 617 this->_M_construct(__il, std::forward<_Args>(__args)...); 618 } 619 620 // [X.Y.4.2] Destructor is implicit, implemented in _Optional_base. 621 622 // [X.Y.4.4] Swap. 623 void 624 swap(optional& __other) 625 noexcept(is_nothrow_move_constructible<_Tp>() 626 && __is_nothrow_swappable<_Tp>::value) 627 { 628 using std::swap; 629 630 if (this->_M_is_engaged() && __other._M_is_engaged()) 631 swap(this->_M_get(), __other._M_get()); 632 else if (this->_M_is_engaged()) 633 { 634 __other._M_construct(std::move(this->_M_get())); 635 this->_M_destruct(); 636 } 637 else if (__other._M_is_engaged()) 638 { 639 this->_M_construct(std::move(__other._M_get())); 640 __other._M_destruct(); 641 } 642 } 643 644 // [X.Y.4.5] Observers. 645 constexpr const _Tp* 646 operator->() const 647 { return std::__addressof(this->_M_get()); } 648 649 _Tp* 650 operator->() 651 { return std::__addressof(this->_M_get()); } 652 653 constexpr const _Tp& 654 operator*() const& 655 { return this->_M_get(); } 656 657 constexpr _Tp& 658 operator*()& 659 { return this->_M_get(); } 660 661 constexpr _Tp&& 662 operator*()&& 663 { return std::move(this->_M_get()); } 664 665 constexpr const _Tp&& 666 operator*() const&& 667 { return std::move(this->_M_get()); } 668 669 constexpr explicit operator bool() const noexcept 670 { return this->_M_is_engaged(); } 671 672 constexpr const _Tp& 673 value() const& 674 { 675 if (this->_M_is_engaged()) 676 return this->_M_get(); 677 __throw_bad_optional_access("Attempt to access value of a " 678 "disengaged optional object"); 679 } 680 681 constexpr _Tp& 682 value()& 683 { 684 if (this->_M_is_engaged()) 685 return this->_M_get(); 686 __throw_bad_optional_access("Attempt to access value of a " 687 "disengaged optional object"); 688 } 689 690 constexpr _Tp&& 691 value()&& 692 { 693 if (this->_M_is_engaged()) 694 return std::move(this->_M_get()); 695 __throw_bad_optional_access("Attempt to access value of a " 696 "disengaged optional object"); 697 } 698 699 constexpr const _Tp&& 700 value() const&& 701 { 702 if (this->_M_is_engaged()) 703 return std::move(this->_M_get()); 704 __throw_bad_optional_access("Attempt to access value of a " 705 "disengaged optional object"); 706 } 707 708 template
709 constexpr _Tp 710 value_or(_Up&& __u) const& 711 { 712 static_assert(__and_
, 713 is_convertible<_Up&&, _Tp>>(), 714 "Cannot return value"); 715 716 if (this->_M_is_engaged()) 717 return this->_M_get(); 718 else 719 return static_cast<_Tp>(std::forward<_Up>(__u)); 720 } 721 722 template
723 _Tp 724 value_or(_Up&& __u) && 725 { 726 static_assert(__and_
, 727 is_convertible<_Up&&, _Tp>>(), 728 "Cannot return value" ); 729 730 if (this->_M_is_engaged()) 731 return std::move(this->_M_get()); 732 else 733 return static_cast<_Tp>(std::forward<_Up>(__u)); 734 } 735 }; 736 737 /// @relates experimental::optional @{ 738 739 // [X.Y.8] Comparisons between optional values. 740 template
741 constexpr bool 742 operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 743 { 744 return static_cast
(__lhs) == static_cast
(__rhs) 745 && (!__lhs || *__lhs == *__rhs); 746 } 747 748 template
749 constexpr bool 750 operator!=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 751 { return !(__lhs == __rhs); } 752 753 template
754 constexpr bool 755 operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 756 { 757 return static_cast
(__rhs) && (!__lhs || *__lhs < *__rhs); 758 } 759 760 template
761 constexpr bool 762 operator>(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 763 { return __rhs < __lhs; } 764 765 template
766 constexpr bool 767 operator<=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 768 { return !(__rhs < __lhs); } 769 770 template
771 constexpr bool 772 operator>=(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) 773 { return !(__lhs < __rhs); } 774 775 // [X.Y.9] Comparisons with nullopt. 776 template
777 constexpr bool 778 operator==(const optional<_Tp>& __lhs, nullopt_t) noexcept 779 { return !__lhs; } 780 781 template
782 constexpr bool 783 operator==(nullopt_t, const optional<_Tp>& __rhs) noexcept 784 { return !__rhs; } 785 786 template
787 constexpr bool 788 operator!=(const optional<_Tp>& __lhs, nullopt_t) noexcept 789 { return static_cast
(__lhs); } 790 791 template
792 constexpr bool 793 operator!=(nullopt_t, const optional<_Tp>& __rhs) noexcept 794 { return static_cast
(__rhs); } 795 796 template
797 constexpr bool 798 operator<(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 799 { return false; } 800 801 template
802 constexpr bool 803 operator<(nullopt_t, const optional<_Tp>& __rhs) noexcept 804 { return static_cast
(__rhs); } 805 806 template
807 constexpr bool 808 operator>(const optional<_Tp>& __lhs, nullopt_t) noexcept 809 { return static_cast
(__lhs); } 810 811 template
812 constexpr bool 813 operator>(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 814 { return false; } 815 816 template
817 constexpr bool 818 operator<=(const optional<_Tp>& __lhs, nullopt_t) noexcept 819 { return !__lhs; } 820 821 template
822 constexpr bool 823 operator<=(nullopt_t, const optional<_Tp>& /* __rhs */) noexcept 824 { return true; } 825 826 template
827 constexpr bool 828 operator>=(const optional<_Tp>& /* __lhs */, nullopt_t) noexcept 829 { return true; } 830 831 template
832 constexpr bool 833 operator>=(nullopt_t, const optional<_Tp>& __rhs) noexcept 834 { return !__rhs; } 835 836 // [X.Y.10] Comparisons with value type. 837 template
838 constexpr bool 839 operator==(const optional<_Tp>& __lhs, const _Tp& __rhs) 840 { return __lhs && *__lhs == __rhs; } 841 842 template
843 constexpr bool 844 operator==(const _Tp& __lhs, const optional<_Tp>& __rhs) 845 { return __rhs && __lhs == *__rhs; } 846 847 template
848 constexpr bool 849 operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs) 850 { return !__lhs || !(*__lhs == __rhs); } 851 852 template
853 constexpr bool 854 operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs) 855 { return !__rhs || !(__lhs == *__rhs); } 856 857 template
858 constexpr bool 859 operator<(const optional<_Tp>& __lhs, const _Tp& __rhs) 860 { return !__lhs || *__lhs < __rhs; } 861 862 template
863 constexpr bool 864 operator<(const _Tp& __lhs, const optional<_Tp>& __rhs) 865 { return __rhs && __lhs < *__rhs; } 866 867 template
868 constexpr bool 869 operator>(const optional<_Tp>& __lhs, const _Tp& __rhs) 870 { return __lhs && __rhs < *__lhs; } 871 872 template
873 constexpr bool 874 operator>(const _Tp& __lhs, const optional<_Tp>& __rhs) 875 { return !__rhs || *__rhs < __lhs; } 876 877 template
878 constexpr bool 879 operator<=(const optional<_Tp>& __lhs, const _Tp& __rhs) 880 { return !__lhs || !(__rhs < *__lhs); } 881 882 template
883 constexpr bool 884 operator<=(const _Tp& __lhs, const optional<_Tp>& __rhs) 885 { return __rhs && !(*__rhs < __lhs); } 886 887 template
888 constexpr bool 889 operator>=(const optional<_Tp>& __lhs, const _Tp& __rhs) 890 { return __lhs && !(*__lhs < __rhs); } 891 892 template
893 constexpr bool 894 operator>=(const _Tp& __lhs, const optional<_Tp>& __rhs) 895 { return !__rhs || !(__lhs < *__rhs); } 896 897 // [X.Y.11] 898 template
899 inline void 900 swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) 901 noexcept(noexcept(__lhs.swap(__rhs))) 902 { __lhs.swap(__rhs); } 903 904 template
905 constexpr optional
> 906 make_optional(_Tp&& __t) 907 { return optional
> { std::forward<_Tp>(__t) }; } 908 909 /// @} relates experimental::optional 910 /// @} group optional 911 } // namespace fundamentals_v1 912 } // namespace experimental 913 914 // [X.Y.12] 915 /// std::hash partial specialization for experimental::optional 916 /// @relates experimental::optional 917 template
918 struct hash
> 919 { 920 using result_type = size_t; 921 using argument_type = experimental::optional<_Tp>; 922 923 size_t 924 operator()(const experimental::optional<_Tp>& __t) const 925 noexcept(noexcept(hash<_Tp> {}(*__t))) 926 { 927 // We pick an arbitrary hash for disengaged optionals which hopefully 928 // usual values of _Tp won't typically hash to. 929 constexpr size_t __magic_disengaged_hash = static_cast
(-3333); 930 return __t ? hash<_Tp> {}(*__t) : __magic_disengaged_hash; 931 } 932 }; 933 934 _GLIBCXX_END_NAMESPACE_VERSION 935 } // namespace std 936 937 #endif // C++14 938 939 #endif // _GLIBCXX_EXPERIMENTAL_OPTIONAL
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™