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