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