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