1 // -*- C++ -*- 2 //===-------------------------- optional ----------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef _LIBCPP_EXPERIMENTAL_OPTIONAL 12 #define _LIBCPP_EXPERIMENTAL_OPTIONAL 13 14 /* 15 optional synopsis 16 17 // C++1y 18 19 namespace std { namespace experimental { inline namespace fundamentals_v1 { 20 21 // 5.3, optional for object types 22 template <class T> class optional; 23 24 // 5.4, In-place construction 25 struct in_place_t{}; 26 constexpr in_place_t in_place{}; 27 28 // 5.5, No-value state indicator 29 struct nullopt_t{see below}; 30 constexpr nullopt_t nullopt(unspecified); 31 32 // 5.6, Class bad_optional_access 33 class bad_optional_access; 34 35 // 5.7, Relational operators 36 template <class T> 37 constexpr bool operator==(const optional<T>&, const optional<T>&); 38 template <class T> 39 constexpr bool operator!=(const optional<T>&, const optional<T>&); 40 template <class T> 41 constexpr bool operator<(const optional<T>&, const optional<T>&); 42 template <class T> 43 constexpr bool operator>(const optional<T>&, const optional<T>&); 44 template <class T> 45 constexpr bool operator<=(const optional<T>&, const optional<T>&); 46 template <class T> 47 constexpr bool operator>=(const optional<T>&, const optional<T>&); 48 49 // 5.8, Comparison with nullopt 50 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; 51 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; 52 template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; 53 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; 54 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; 55 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; 56 template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; 57 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; 58 template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; 59 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; 60 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; 61 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; 62 63 // 5.9, Comparison with T 64 template <class T> constexpr bool operator==(const optional<T>&, const T&); 65 template <class T> constexpr bool operator==(const T&, const optional<T>&); 66 template <class T> constexpr bool operator!=(const optional<T>&, const T&); 67 template <class T> constexpr bool operator!=(const T&, const optional<T>&); 68 template <class T> constexpr bool operator<(const optional<T>&, const T&); 69 template <class T> constexpr bool operator<(const T&, const optional<T>&); 70 template <class T> constexpr bool operator<=(const optional<T>&, const T&); 71 template <class T> constexpr bool operator<=(const T&, const optional<T>&); 72 template <class T> constexpr bool operator>(const optional<T>&, const T&); 73 template <class T> constexpr bool operator>(const T&, const optional<T>&); 74 template <class T> constexpr bool operator>=(const optional<T>&, const T&); 75 template <class T> constexpr bool operator>=(const T&, const optional<T>&); 76 77 // 5.10, Specialized algorithms 78 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below); 79 template <class T> constexpr optional<see below> make_optional(T&&); 80 81 template <class T> 82 class optional 83 { 84 public: 85 typedef T value_type; 86 87 // 5.3.1, Constructors 88 constexpr optional() noexcept; 89 constexpr optional(nullopt_t) noexcept; 90 optional(const optional&); 91 optional(optional&&) noexcept(see below); 92 constexpr optional(const T&); 93 constexpr optional(T&&); 94 template <class... Args> constexpr explicit optional(in_place_t, Args&&...); 95 template <class U, class... Args> 96 constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...); 97 98 // 5.3.2, Destructor 99 ~optional(); 100 101 // 5.3.3, Assignment 102 optional& operator=(nullopt_t) noexcept; 103 optional& operator=(const optional&); 104 optional& operator=(optional&&) noexcept(see below); 105 template <class U> optional& operator=(U&&); 106 template <class... Args> void emplace(Args&&...); 107 template <class U, class... Args> 108 void emplace(initializer_list<U>, Args&&...); 109 110 // 5.3.4, Swap 111 void swap(optional&) noexcept(see below); 112 113 // 5.3.5, Observers 114 constexpr T const* operator ->() const; 115 constexpr T* operator ->(); 116 constexpr T const& operator *() const &; 117 constexpr T& operator *() &; 118 constexpr T&& operator *() &&; 119 constexpr const T&& operator *() const &&; 120 constexpr explicit operator bool() const noexcept; 121 constexpr T const& value() const &; 122 constexpr T& value() &; 123 constexpr T&& value() &&; 124 constexpr const T&& value() const &&; 125 template <class U> constexpr T value_or(U&&) const &; 126 template <class U> constexpr T value_or(U&&) &&; 127 128 private: 129 T* val; // exposition only 130 }; 131 132 } // namespace fundamentals_v1 133 } // namespace experimental 134 135 // 5.11, Hash support 136 template <class T> struct hash; 137 template <class T> struct hash<experimental::optional<T>>; 138 139 } // namespace std 140 141 */ 142 143 #include <experimental/__config> 144 #include <functional> 145 #include <stdexcept> 146 147 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL 148 class _LIBCPP_EXCEPTION_ABI bad_optional_access 149 : public std::logic_error 150 { 151 public: 152 bad_optional_access() : std::logic_error("Bad optional Access") {} 153 154 // Get the key function ~bad_optional_access() into the dylib 155 virtual ~bad_optional_access() _NOEXCEPT; 156 }; 157 158 _LIBCPP_END_NAMESPACE_EXPERIMENTAL 159 160 161 #if _LIBCPP_STD_VER > 11 162 163 #include <initializer_list> 164 #include <type_traits> 165 #include <new> 166 #include <__functional_base> 167 #include <__undef_min_max> 168 #include <__debug> 169 170 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 171 #pragma GCC system_header 172 #endif 173 174 _LIBCPP_BEGIN_NAMESPACE_LFTS 175 176 struct in_place_t {}; 177 constexpr in_place_t in_place{}; 178 179 struct nullopt_t 180 { 181 explicit constexpr nullopt_t(int) noexcept {} 182 }; 183 184 constexpr nullopt_t nullopt{0}; 185 186 template <class _Tp, bool = is_trivially_destructible<_Tp>::value> 187 class __optional_storage 188 { 189 protected: 190 typedef _Tp value_type; 191 union 192 { 193 char __null_state_; 194 value_type __val_; 195 }; 196 bool __engaged_ = false; 197 198 _LIBCPP_INLINE_VISIBILITY 199 ~__optional_storage() 200 { 201 if (__engaged_) 202 __val_.~value_type(); 203 } 204 205 _LIBCPP_INLINE_VISIBILITY 206 constexpr __optional_storage() noexcept 207 : __null_state_('\0') {} 208 209 _LIBCPP_INLINE_VISIBILITY 210 __optional_storage(const __optional_storage& __x) 211 : __engaged_(__x.__engaged_) 212 { 213 if (__engaged_) 214 ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_); 215 } 216 217 _LIBCPP_INLINE_VISIBILITY 218 __optional_storage(__optional_storage&& __x) 219 noexcept(is_nothrow_move_constructible<value_type>::value) 220 : __engaged_(__x.__engaged_) 221 { 222 if (__engaged_) 223 ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); 224 } 225 226 _LIBCPP_INLINE_VISIBILITY 227 constexpr __optional_storage(const value_type& __v) 228 : __val_(__v), 229 __engaged_(true) {} 230 231 _LIBCPP_INLINE_VISIBILITY 232 constexpr __optional_storage(value_type&& __v) 233 : __val_(_VSTD::move(__v)), 234 __engaged_(true) {} 235 236 template <class... _Args> 237 _LIBCPP_INLINE_VISIBILITY 238 constexpr 239 explicit __optional_storage(in_place_t, _Args&&... __args) 240 : __val_(_VSTD::forward<_Args>(__args)...), 241 __engaged_(true) {} 242 }; 243 244 template <class _Tp> 245 class __optional_storage<_Tp, true> 246 { 247 protected: 248 typedef _Tp value_type; 249 union 250 { 251 char __null_state_; 252 value_type __val_; 253 }; 254 bool __engaged_ = false; 255 256 _LIBCPP_INLINE_VISIBILITY 257 constexpr __optional_storage() noexcept 258 : __null_state_('\0') {} 259 260 _LIBCPP_INLINE_VISIBILITY 261 __optional_storage(const __optional_storage& __x) 262 : __engaged_(__x.__engaged_) 263 { 264 if (__engaged_) 265 ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_); 266 } 267 268 _LIBCPP_INLINE_VISIBILITY 269 __optional_storage(__optional_storage&& __x) 270 noexcept(is_nothrow_move_constructible<value_type>::value) 271 : __engaged_(__x.__engaged_) 272 { 273 if (__engaged_) 274 ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); 275 } 276 277 _LIBCPP_INLINE_VISIBILITY 278 constexpr __optional_storage(const value_type& __v) 279 : __val_(__v), 280 __engaged_(true) {} 281 282 _LIBCPP_INLINE_VISIBILITY 283 constexpr __optional_storage(value_type&& __v) 284 : __val_(_VSTD::move(__v)), 285 __engaged_(true) {} 286 287 template <class... _Args> 288 _LIBCPP_INLINE_VISIBILITY 289 constexpr 290 explicit __optional_storage(in_place_t, _Args&&... __args) 291 : __val_(_VSTD::forward<_Args>(__args)...), 292 __engaged_(true) {} 293 }; 294 295 template <class _Tp> 296 class optional 297 : private __optional_storage<_Tp> 298 { 299 typedef __optional_storage<_Tp> __base; 300 public: 301 typedef _Tp value_type; 302 303 static_assert(!is_reference<value_type>::value, 304 "Instantiation of optional with a reference type is ill-formed."); 305 static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value, 306 "Instantiation of optional with a in_place_t type is ill-formed."); 307 static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value, 308 "Instantiation of optional with a nullopt_t type is ill-formed."); 309 static_assert(is_object<value_type>::value, 310 "Instantiation of optional with a non-object type is undefined behavior."); 311 static_assert(is_nothrow_destructible<value_type>::value, 312 "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior."); 313 314 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} 315 _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; 316 _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; 317 _LIBCPP_INLINE_VISIBILITY ~optional() = default; 318 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} 319 _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v) 320 : __base(__v) {} 321 _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v) 322 : __base(_VSTD::move(__v)) {} 323 324 template <class... _Args, 325 class = typename enable_if 326 < 327 is_constructible<value_type, _Args...>::value 328 >::type 329 > 330 _LIBCPP_INLINE_VISIBILITY 331 constexpr 332 explicit optional(in_place_t, _Args&&... __args) 333 : __base(in_place, _VSTD::forward<_Args>(__args)...) {} 334 335 template <class _Up, class... _Args, 336 class = typename enable_if 337 < 338 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value 339 >::type 340 > 341 _LIBCPP_INLINE_VISIBILITY 342 constexpr 343 explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 344 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} 345 346 _LIBCPP_INLINE_VISIBILITY 347 optional& operator=(nullopt_t) noexcept 348 { 349 if (this->__engaged_) 350 { 351 this->__val_.~value_type(); 352 this->__engaged_ = false; 353 } 354 return *this; 355 } 356 357 _LIBCPP_INLINE_VISIBILITY 358 optional& 359 operator=(const optional& __opt) 360 { 361 if (this->__engaged_ == __opt.__engaged_) 362 { 363 if (this->__engaged_) 364 this->__val_ = __opt.__val_; 365 } 366 else 367 { 368 if (this->__engaged_) 369 this->__val_.~value_type(); 370 else 371 ::new((void*)_VSTD::addressof(this->__val_)) value_type(__opt.__val_); 372 this->__engaged_ = __opt.__engaged_; 373 } 374 return *this; 375 } 376 377 _LIBCPP_INLINE_VISIBILITY 378 optional& 379 operator=(optional&& __opt) 380 noexcept(is_nothrow_move_assignable<value_type>::value && 381 is_nothrow_move_constructible<value_type>::value) 382 { 383 if (this->__engaged_ == __opt.__engaged_) 384 { 385 if (this->__engaged_) 386 this->__val_ = _VSTD::move(__opt.__val_); 387 } 388 else 389 { 390 if (this->__engaged_) 391 this->__val_.~value_type(); 392 else 393 ::new((void*)_VSTD::addressof(this->__val_)) 394 value_type(_VSTD::move(__opt.__val_)); 395 this->__engaged_ = __opt.__engaged_; 396 } 397 return *this; 398 } 399 400 template <class _Up, 401 class = typename enable_if 402 < 403 is_same<typename remove_reference<_Up>::type, value_type>::value && 404 is_constructible<value_type, _Up>::value && 405 is_assignable<value_type&, _Up>::value 406 >::type 407 > 408 _LIBCPP_INLINE_VISIBILITY 409 optional& 410 operator=(_Up&& __v) 411 { 412 if (this->__engaged_) 413 this->__val_ = _VSTD::forward<_Up>(__v); 414 else 415 { 416 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); 417 this->__engaged_ = true; 418 } 419 return *this; 420 } 421 422 template <class... _Args, 423 class = typename enable_if 424 < 425 is_constructible<value_type, _Args...>::value 426 >::type 427 > 428 _LIBCPP_INLINE_VISIBILITY 429 void 430 emplace(_Args&&... __args) 431 { 432 *this = nullopt; 433 ::new((void*)_VSTD::addressof(this->__val_)) 434 value_type(_VSTD::forward<_Args>(__args)...); 435 this->__engaged_ = true; 436 } 437 438 template <class _Up, class... _Args, 439 class = typename enable_if 440 < 441 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value 442 >::type 443 > 444 _LIBCPP_INLINE_VISIBILITY 445 void 446 emplace(initializer_list<_Up> __il, _Args&&... __args) 447 { 448 *this = nullopt; 449 ::new((void*)_VSTD::addressof(this->__val_)) 450 value_type(__il, _VSTD::forward<_Args>(__args)...); 451 this->__engaged_ = true; 452 } 453 454 _LIBCPP_INLINE_VISIBILITY 455 void 456 swap(optional& __opt) 457 noexcept(is_nothrow_move_constructible<value_type>::value && 458 __is_nothrow_swappable<value_type>::value) 459 { 460 using _VSTD::swap; 461 if (this->__engaged_ == __opt.__engaged_) 462 { 463 if (this->__engaged_) 464 swap(this->__val_, __opt.__val_); 465 } 466 else 467 { 468 if (this->__engaged_) 469 { 470 ::new((void*)_VSTD::addressof(__opt.__val_)) 471 value_type(_VSTD::move(this->__val_)); 472 this->__val_.~value_type(); 473 } 474 else 475 { 476 ::new((void*)_VSTD::addressof(this->__val_)) 477 value_type(_VSTD::move(__opt.__val_)); 478 __opt.__val_.~value_type(); 479 } 480 swap(this->__engaged_, __opt.__engaged_); 481 } 482 } 483 484 _LIBCPP_INLINE_VISIBILITY 485 constexpr 486 value_type const* 487 operator->() const 488 { 489 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); 490 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 491 return __builtin_addressof(this->__val_); 492 #else 493 return __operator_arrow(__has_operator_addressof<value_type>{}); 494 #endif 495 } 496 497 _LIBCPP_INLINE_VISIBILITY 498 value_type* 499 operator->() 500 { 501 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); 502 return _VSTD::addressof(this->__val_); 503 } 504 505 _LIBCPP_INLINE_VISIBILITY 506 constexpr 507 const value_type& 508 operator*() const 509 { 510 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); 511 return this->__val_; 512 } 513 514 _LIBCPP_INLINE_VISIBILITY 515 value_type& 516 operator*() 517 { 518 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); 519 return this->__val_; 520 } 521 522 _LIBCPP_INLINE_VISIBILITY 523 constexpr explicit operator bool() const noexcept {return this->__engaged_;} 524 525 _LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY 526 constexpr void __throw_bad_optional_access() const 527 { 528 #ifndef _LIBCPP_NO_EXCEPTIONS 529 throw bad_optional_access(); 530 #else 531 _VSTD::abort(); 532 #endif 533 } 534 535 _LIBCPP_INLINE_VISIBILITY 536 constexpr value_type const& value() const 537 { 538 if (!this->__engaged_) 539 __throw_bad_optional_access(); 540 return this->__val_; 541 } 542 543 _LIBCPP_INLINE_VISIBILITY 544 value_type& value() 545 { 546 if (!this->__engaged_) 547 __throw_bad_optional_access(); 548 return this->__val_; 549 } 550 551 template <class _Up> 552 _LIBCPP_INLINE_VISIBILITY 553 constexpr value_type value_or(_Up&& __v) const& 554 { 555 static_assert(is_copy_constructible<value_type>::value, 556 "optional<T>::value_or: T must be copy constructible"); 557 static_assert(is_convertible<_Up, value_type>::value, 558 "optional<T>::value_or: U must be convertible to T"); 559 return this->__engaged_ ? this->__val_ : 560 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 561 } 562 563 template <class _Up> 564 _LIBCPP_INLINE_VISIBILITY 565 value_type value_or(_Up&& __v) && 566 { 567 static_assert(is_move_constructible<value_type>::value, 568 "optional<T>::value_or: T must be move constructible"); 569 static_assert(is_convertible<_Up, value_type>::value, 570 "optional<T>::value_or: U must be convertible to T"); 571 return this->__engaged_ ? _VSTD::move(this->__val_) : 572 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 573 } 574 575 private: 576 _LIBCPP_INLINE_VISIBILITY 577 value_type const* 578 __operator_arrow(true_type) const 579 { 580 return _VSTD::addressof(this->__val_); 581 } 582 583 _LIBCPP_INLINE_VISIBILITY 584 constexpr 585 value_type const* 586 __operator_arrow(false_type) const 587 { 588 return &this->__val_; 589 } 590 }; 591 592 // Comparisons between optionals 593 template <class _Tp> 594 inline _LIBCPP_INLINE_VISIBILITY 595 constexpr 596 bool 597 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) 598 { 599 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 600 return false; 601 if (!static_cast<bool>(__x)) 602 return true; 603 return *__x == *__y; 604 } 605 606 template <class _Tp> 607 inline _LIBCPP_INLINE_VISIBILITY 608 constexpr 609 bool 610 operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) 611 { 612 return !(__x == __y); 613 } 614 615 template <class _Tp> 616 inline _LIBCPP_INLINE_VISIBILITY 617 constexpr 618 bool 619 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) 620 { 621 if (!static_cast<bool>(__y)) 622 return false; 623 if (!static_cast<bool>(__x)) 624 return true; 625 return *__x < *__y; 626 } 627 628 template <class _Tp> 629 inline _LIBCPP_INLINE_VISIBILITY 630 constexpr 631 bool 632 operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) 633 { 634 return __y < __x; 635 } 636 637 template <class _Tp> 638 inline _LIBCPP_INLINE_VISIBILITY 639 constexpr 640 bool 641 operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) 642 { 643 return !(__y < __x); 644 } 645 646 template <class _Tp> 647 inline _LIBCPP_INLINE_VISIBILITY 648 constexpr 649 bool 650 operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) 651 { 652 return !(__x < __y); 653 } 654 655 656 // Comparisons with nullopt 657 template <class _Tp> 658 inline _LIBCPP_INLINE_VISIBILITY 659 constexpr 660 bool 661 operator==(const optional<_Tp>& __x, nullopt_t) noexcept 662 { 663 return !static_cast<bool>(__x); 664 } 665 666 template <class _Tp> 667 inline _LIBCPP_INLINE_VISIBILITY 668 constexpr 669 bool 670 operator==(nullopt_t, const optional<_Tp>& __x) noexcept 671 { 672 return !static_cast<bool>(__x); 673 } 674 675 template <class _Tp> 676 inline _LIBCPP_INLINE_VISIBILITY 677 constexpr 678 bool 679 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept 680 { 681 return static_cast<bool>(__x); 682 } 683 684 template <class _Tp> 685 inline _LIBCPP_INLINE_VISIBILITY 686 constexpr 687 bool 688 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept 689 { 690 return static_cast<bool>(__x); 691 } 692 693 template <class _Tp> 694 inline _LIBCPP_INLINE_VISIBILITY 695 constexpr 696 bool 697 operator<(const optional<_Tp>&, nullopt_t) noexcept 698 { 699 return false; 700 } 701 702 template <class _Tp> 703 inline _LIBCPP_INLINE_VISIBILITY 704 constexpr 705 bool 706 operator<(nullopt_t, const optional<_Tp>& __x) noexcept 707 { 708 return static_cast<bool>(__x); 709 } 710 711 template <class _Tp> 712 inline _LIBCPP_INLINE_VISIBILITY 713 constexpr 714 bool 715 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept 716 { 717 return !static_cast<bool>(__x); 718 } 719 720 template <class _Tp> 721 inline _LIBCPP_INLINE_VISIBILITY 722 constexpr 723 bool 724 operator<=(nullopt_t, const optional<_Tp>&) noexcept 725 { 726 return true; 727 } 728 729 template <class _Tp> 730 inline _LIBCPP_INLINE_VISIBILITY 731 constexpr 732 bool 733 operator>(const optional<_Tp>& __x, nullopt_t) noexcept 734 { 735 return static_cast<bool>(__x); 736 } 737 738 template <class _Tp> 739 inline _LIBCPP_INLINE_VISIBILITY 740 constexpr 741 bool 742 operator>(nullopt_t, const optional<_Tp>&) noexcept 743 { 744 return false; 745 } 746 747 template <class _Tp> 748 inline _LIBCPP_INLINE_VISIBILITY 749 constexpr 750 bool 751 operator>=(const optional<_Tp>&, nullopt_t) noexcept 752 { 753 return true; 754 } 755 756 template <class _Tp> 757 inline _LIBCPP_INLINE_VISIBILITY 758 constexpr 759 bool 760 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept 761 { 762 return !static_cast<bool>(__x); 763 } 764 765 // Comparisons with T 766 template <class _Tp> 767 inline _LIBCPP_INLINE_VISIBILITY 768 constexpr 769 bool 770 operator==(const optional<_Tp>& __x, const _Tp& __v) 771 { 772 return static_cast<bool>(__x) ? *__x == __v : false; 773 } 774 775 template <class _Tp> 776 inline _LIBCPP_INLINE_VISIBILITY 777 constexpr 778 bool 779 operator==(const _Tp& __v, const optional<_Tp>& __x) 780 { 781 return static_cast<bool>(__x) ? *__x == __v : false; 782 } 783 784 template <class _Tp> 785 inline _LIBCPP_INLINE_VISIBILITY 786 constexpr 787 bool 788 operator!=(const optional<_Tp>& __x, const _Tp& __v) 789 { 790 return static_cast<bool>(__x) ? !(*__x == __v) : true; 791 } 792 793 template <class _Tp> 794 inline _LIBCPP_INLINE_VISIBILITY 795 constexpr 796 bool 797 operator!=(const _Tp& __v, const optional<_Tp>& __x) 798 { 799 return static_cast<bool>(__x) ? !(*__x == __v) : true; 800 } 801 802 template <class _Tp> 803 inline _LIBCPP_INLINE_VISIBILITY 804 constexpr 805 bool 806 operator<(const optional<_Tp>& __x, const _Tp& __v) 807 { 808 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true; 809 } 810 811 template <class _Tp> 812 inline _LIBCPP_INLINE_VISIBILITY 813 constexpr 814 bool 815 operator<(const _Tp& __v, const optional<_Tp>& __x) 816 { 817 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false; 818 } 819 820 template <class _Tp> 821 inline _LIBCPP_INLINE_VISIBILITY 822 constexpr 823 bool 824 operator<=(const optional<_Tp>& __x, const _Tp& __v) 825 { 826 return !(__x > __v); 827 } 828 829 template <class _Tp> 830 inline _LIBCPP_INLINE_VISIBILITY 831 constexpr 832 bool 833 operator<=(const _Tp& __v, const optional<_Tp>& __x) 834 { 835 return !(__v > __x); 836 } 837 838 template <class _Tp> 839 inline _LIBCPP_INLINE_VISIBILITY 840 constexpr 841 bool 842 operator>(const optional<_Tp>& __x, const _Tp& __v) 843 { 844 return static_cast<bool>(__x) ? __v < __x : false; 845 } 846 847 template <class _Tp> 848 inline _LIBCPP_INLINE_VISIBILITY 849 constexpr 850 bool 851 operator>(const _Tp& __v, const optional<_Tp>& __x) 852 { 853 return static_cast<bool>(__x) ? __x < __v : true; 854 } 855 856 template <class _Tp> 857 inline _LIBCPP_INLINE_VISIBILITY 858 constexpr 859 bool 860 operator>=(const optional<_Tp>& __x, const _Tp& __v) 861 { 862 return !(__x < __v); 863 } 864 865 template <class _Tp> 866 inline _LIBCPP_INLINE_VISIBILITY 867 constexpr 868 bool 869 operator>=(const _Tp& __v, const optional<_Tp>& __x) 870 { 871 return !(__v < __x); 872 } 873 874 875 template <class _Tp> 876 inline _LIBCPP_INLINE_VISIBILITY 877 void 878 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 879 { 880 __x.swap(__y); 881 } 882 883 template <class _Tp> 884 inline _LIBCPP_INLINE_VISIBILITY 885 constexpr 886 optional<typename decay<_Tp>::type> 887 make_optional(_Tp&& __v) 888 { 889 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v)); 890 } 891 892 _LIBCPP_END_NAMESPACE_LFTS 893 894 _LIBCPP_BEGIN_NAMESPACE_STD 895 896 template <class _Tp> 897 struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::optional<_Tp> > 898 { 899 typedef std::experimental::optional<_Tp> argument_type; 900 typedef size_t result_type; 901 902 _LIBCPP_INLINE_VISIBILITY 903 result_type operator()(const argument_type& __opt) const _NOEXCEPT 904 { 905 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0; 906 } 907 }; 908 909 _LIBCPP_END_NAMESPACE_STD 910 911 #endif // _LIBCPP_STD_VER > 11 912 913 #endif // _LIBCPP_EXPERIMENTAL_OPTIONAL 914