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