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_OPTIONAL 12#define _LIBCPP_OPTIONAL 13 14/* 15 optional synopsis 16 17// C++1y 18 19namespace 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 148class _LIBCPP_EXCEPTION_ABI bad_optional_access 149 : public std::logic_error 150{ 151public: 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 176struct in_place_t {}; 177constexpr in_place_t in_place{}; 178 179struct nullopt_t 180{ 181 explicit constexpr nullopt_t(int) noexcept {} 182}; 183 184constexpr nullopt_t nullopt{0}; 185 186template <class _Tp, bool = is_trivially_destructible<_Tp>::value> 187class __optional_storage 188{ 189protected: 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(_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(_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 244template <class _Tp> 245class __optional_storage<_Tp, true> 246{ 247protected: 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(_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(_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 295template <class _Tp> 296class optional 297 : private __optional_storage<_Tp> 298{ 299 typedef __optional_storage<_Tp> __base; 300public: 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(_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(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); 394 this->__engaged_ = __opt.__engaged_; 395 } 396 return *this; 397 } 398 399 template <class _Up, 400 class = typename enable_if 401 < 402 is_same<typename remove_reference<_Up>::type, value_type>::value && 403 is_constructible<value_type, _Up>::value && 404 is_assignable<value_type&, _Up>::value 405 >::type 406 > 407 _LIBCPP_INLINE_VISIBILITY 408 optional& 409 operator=(_Up&& __v) 410 { 411 if (this->__engaged_) 412 this->__val_ = _VSTD::forward<_Up>(__v); 413 else 414 { 415 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); 416 this->__engaged_ = true; 417 } 418 return *this; 419 } 420 421 template <class... _Args, 422 class = typename enable_if 423 < 424 is_constructible<value_type, _Args...>::value 425 >::type 426 > 427 _LIBCPP_INLINE_VISIBILITY 428 void 429 emplace(_Args&&... __args) 430 { 431 *this = nullopt; 432 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); 433 this->__engaged_ = true; 434 } 435 436 template <class _Up, class... _Args, 437 class = typename enable_if 438 < 439 is_constructible<value_type, initializer_list<_Up>&, _Args...>::value 440 >::type 441 > 442 _LIBCPP_INLINE_VISIBILITY 443 void 444 emplace(initializer_list<_Up> __il, _Args&&... __args) 445 { 446 *this = nullopt; 447 ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...); 448 this->__engaged_ = true; 449 } 450 451 _LIBCPP_INLINE_VISIBILITY 452 void 453 swap(optional& __opt) 454 noexcept(is_nothrow_move_constructible<value_type>::value && 455 __is_nothrow_swappable<value_type>::value) 456 { 457 using _VSTD::swap; 458 if (this->__engaged_ == __opt.__engaged_) 459 { 460 if (this->__engaged_) 461 swap(this->__val_, __opt.__val_); 462 } 463 else 464 { 465 if (this->__engaged_) 466 { 467 ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_)); 468 this->__val_.~value_type(); 469 } 470 else 471 { 472 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); 473 __opt.__val_.~value_type(); 474 } 475 swap(this->__engaged_, __opt.__engaged_); 476 } 477 } 478 479 _LIBCPP_INLINE_VISIBILITY 480 constexpr 481 value_type const* 482 operator->() const 483 { 484 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); 485 return __operator_arrow(__has_operator_addressof<value_type>{}); 486 } 487 488 _LIBCPP_INLINE_VISIBILITY 489 value_type* 490 operator->() 491 { 492 _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); 493 return _VSTD::addressof(this->__val_); 494 } 495 496 _LIBCPP_INLINE_VISIBILITY 497 constexpr 498 const value_type& 499 operator*() const 500 { 501 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); 502 return this->__val_; 503 } 504 505 _LIBCPP_INLINE_VISIBILITY 506 value_type& 507 operator*() 508 { 509 _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); 510 return this->__val_; 511 } 512 513 _LIBCPP_INLINE_VISIBILITY 514 constexpr explicit operator bool() const noexcept {return this->__engaged_;} 515 516 _LIBCPP_INLINE_VISIBILITY 517 constexpr value_type const& value() const 518 { 519 if (!this->__engaged_) 520#ifndef _LIBCPP_NO_EXCEPTIONS 521 throw bad_optional_access(); 522#else 523 assert(!"bad optional access"); 524#endif 525 return this->__val_; 526 } 527 528 _LIBCPP_INLINE_VISIBILITY 529 value_type& value() 530 { 531 if (!this->__engaged_) 532#ifndef _LIBCPP_NO_EXCEPTIONS 533 throw bad_optional_access(); 534#else 535 assert(!"bad optional access"); 536#endif 537 return this->__val_; 538 } 539 540 template <class _Up> 541 _LIBCPP_INLINE_VISIBILITY 542 constexpr value_type value_or(_Up&& __v) const& 543 { 544 static_assert(is_copy_constructible<value_type>::value, 545 "optional<T>::value_or: T must be copy constructible"); 546 static_assert(is_convertible<_Up, value_type>::value, 547 "optional<T>::value_or: U must be convertible to T"); 548 return this->__engaged_ ? this->__val_ : 549 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 550 } 551 552 template <class _Up> 553 _LIBCPP_INLINE_VISIBILITY 554 value_type value_or(_Up&& __v) && 555 { 556 static_assert(is_move_constructible<value_type>::value, 557 "optional<T>::value_or: T must be move constructible"); 558 static_assert(is_convertible<_Up, value_type>::value, 559 "optional<T>::value_or: U must be convertible to T"); 560 return this->__engaged_ ? _VSTD::move(this->__val_) : 561 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 562 } 563 564private: 565 _LIBCPP_INLINE_VISIBILITY 566 value_type const* 567 __operator_arrow(true_type) const 568 { 569 return _VSTD::addressof(this->__val_); 570 } 571 572 _LIBCPP_INLINE_VISIBILITY 573 constexpr 574 value_type const* 575 __operator_arrow(false_type) const 576 { 577 return &this->__val_; 578 } 579}; 580 581// Comparisons between optionals 582template <class _Tp> 583inline _LIBCPP_INLINE_VISIBILITY 584constexpr 585bool 586operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) 587{ 588 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 589 return false; 590 if (!static_cast<bool>(__x)) 591 return true; 592 return *__x == *__y; 593} 594 595template <class _Tp> 596inline _LIBCPP_INLINE_VISIBILITY 597constexpr 598bool 599operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) 600{ 601 return !(__x == __y); 602} 603 604template <class _Tp> 605inline _LIBCPP_INLINE_VISIBILITY 606constexpr 607bool 608operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) 609{ 610 if (!static_cast<bool>(__y)) 611 return false; 612 if (!static_cast<bool>(__x)) 613 return true; 614 return *__x < *__y; 615} 616 617template <class _Tp> 618inline _LIBCPP_INLINE_VISIBILITY 619constexpr 620bool 621operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) 622{ 623 return __y < __x; 624} 625 626template <class _Tp> 627inline _LIBCPP_INLINE_VISIBILITY 628constexpr 629bool 630operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) 631{ 632 return !(__y < __x); 633} 634 635template <class _Tp> 636inline _LIBCPP_INLINE_VISIBILITY 637constexpr 638bool 639operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) 640{ 641 return !(__x < __y); 642} 643 644 645// Comparisons with nullopt 646template <class _Tp> 647inline _LIBCPP_INLINE_VISIBILITY 648constexpr 649bool 650operator==(const optional<_Tp>& __x, nullopt_t) noexcept 651{ 652 return !static_cast<bool>(__x); 653} 654 655template <class _Tp> 656inline _LIBCPP_INLINE_VISIBILITY 657constexpr 658bool 659operator==(nullopt_t, const optional<_Tp>& __x) noexcept 660{ 661 return !static_cast<bool>(__x); 662} 663 664template <class _Tp> 665inline _LIBCPP_INLINE_VISIBILITY 666constexpr 667bool 668operator!=(const optional<_Tp>& __x, nullopt_t) noexcept 669{ 670 return static_cast<bool>(__x); 671} 672 673template <class _Tp> 674inline _LIBCPP_INLINE_VISIBILITY 675constexpr 676bool 677operator!=(nullopt_t, const optional<_Tp>& __x) noexcept 678{ 679 return static_cast<bool>(__x); 680} 681 682template <class _Tp> 683inline _LIBCPP_INLINE_VISIBILITY 684constexpr 685bool 686operator<(const optional<_Tp>&, nullopt_t) noexcept 687{ 688 return false; 689} 690 691template <class _Tp> 692inline _LIBCPP_INLINE_VISIBILITY 693constexpr 694bool 695operator<(nullopt_t, const optional<_Tp>& __x) noexcept 696{ 697 return static_cast<bool>(__x); 698} 699 700template <class _Tp> 701inline _LIBCPP_INLINE_VISIBILITY 702constexpr 703bool 704operator<=(const optional<_Tp>& __x, nullopt_t) noexcept 705{ 706 return !static_cast<bool>(__x); 707} 708 709template <class _Tp> 710inline _LIBCPP_INLINE_VISIBILITY 711constexpr 712bool 713operator<=(nullopt_t, const optional<_Tp>& __x) noexcept 714{ 715 return true; 716} 717 718template <class _Tp> 719inline _LIBCPP_INLINE_VISIBILITY 720constexpr 721bool 722operator>(const optional<_Tp>& __x, nullopt_t) noexcept 723{ 724 return static_cast<bool>(__x); 725} 726 727template <class _Tp> 728inline _LIBCPP_INLINE_VISIBILITY 729constexpr 730bool 731operator>(nullopt_t, const optional<_Tp>& __x) noexcept 732{ 733 return false; 734} 735 736template <class _Tp> 737inline _LIBCPP_INLINE_VISIBILITY 738constexpr 739bool 740operator>=(const optional<_Tp>&, nullopt_t) noexcept 741{ 742 return true; 743} 744 745template <class _Tp> 746inline _LIBCPP_INLINE_VISIBILITY 747constexpr 748bool 749operator>=(nullopt_t, const optional<_Tp>& __x) noexcept 750{ 751 return !static_cast<bool>(__x); 752} 753 754// Comparisons with T 755template <class _Tp> 756inline _LIBCPP_INLINE_VISIBILITY 757constexpr 758bool 759operator==(const optional<_Tp>& __x, const _Tp& __v) 760{ 761 return static_cast<bool>(__x) ? *__x == __v : false; 762} 763 764template <class _Tp> 765inline _LIBCPP_INLINE_VISIBILITY 766constexpr 767bool 768operator==(const _Tp& __v, const optional<_Tp>& __x) 769{ 770 return static_cast<bool>(__x) ? *__x == __v : false; 771} 772 773template <class _Tp> 774inline _LIBCPP_INLINE_VISIBILITY 775constexpr 776bool 777operator!=(const optional<_Tp>& __x, const _Tp& __v) 778{ 779 return static_cast<bool>(__x) ? !(*__x == __v) : true; 780} 781 782template <class _Tp> 783inline _LIBCPP_INLINE_VISIBILITY 784constexpr 785bool 786operator!=(const _Tp& __v, const optional<_Tp>& __x) 787{ 788 return static_cast<bool>(__x) ? !(*__x == __v) : true; 789} 790 791template <class _Tp> 792inline _LIBCPP_INLINE_VISIBILITY 793constexpr 794bool 795operator<(const optional<_Tp>& __x, const _Tp& __v) 796{ 797 return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true; 798} 799 800template <class _Tp> 801inline _LIBCPP_INLINE_VISIBILITY 802constexpr 803bool 804operator<(const _Tp& __v, const optional<_Tp>& __x) 805{ 806 return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false; 807} 808 809template <class _Tp> 810inline _LIBCPP_INLINE_VISIBILITY 811constexpr 812bool 813operator<=(const optional<_Tp>& __x, const _Tp& __v) 814{ 815 return !(__x > __v); 816} 817 818template <class _Tp> 819inline _LIBCPP_INLINE_VISIBILITY 820constexpr 821bool 822operator<=(const _Tp& __v, const optional<_Tp>& __x) 823{ 824 return !(__v > __x); 825} 826 827template <class _Tp> 828inline _LIBCPP_INLINE_VISIBILITY 829constexpr 830bool 831operator>(const optional<_Tp>& __x, const _Tp& __v) 832{ 833 return static_cast<bool>(__x) ? __v < __x : false; 834} 835 836template <class _Tp> 837inline _LIBCPP_INLINE_VISIBILITY 838constexpr 839bool 840operator>(const _Tp& __v, const optional<_Tp>& __x) 841{ 842 return static_cast<bool>(__x) ? __x < __v : true; 843} 844 845template <class _Tp> 846inline _LIBCPP_INLINE_VISIBILITY 847constexpr 848bool 849operator>=(const optional<_Tp>& __x, const _Tp& __v) 850{ 851 return !(__x < __v); 852} 853 854template <class _Tp> 855inline _LIBCPP_INLINE_VISIBILITY 856constexpr 857bool 858operator>=(const _Tp& __v, const optional<_Tp>& __x) 859{ 860 return !(__v < __x); 861} 862 863 864template <class _Tp> 865inline _LIBCPP_INLINE_VISIBILITY 866void 867swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 868{ 869 __x.swap(__y); 870} 871 872template <class _Tp> 873inline _LIBCPP_INLINE_VISIBILITY 874constexpr 875optional<typename decay<_Tp>::type> 876make_optional(_Tp&& __v) 877{ 878 return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v)); 879} 880 881_LIBCPP_END_NAMESPACE_LFTS 882 883_LIBCPP_BEGIN_NAMESPACE_STD 884 885template <class _Tp> 886struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> > 887{ 888 typedef std::experimental::optional<_Tp> argument_type; 889 typedef size_t result_type; 890 891 _LIBCPP_INLINE_VISIBILITY 892 result_type operator()(const argument_type& __opt) const _NOEXCEPT 893 { 894 return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0; 895 } 896}; 897 898_LIBCPP_END_NAMESPACE_STD 899 900#endif // _LIBCPP_STD_VER > 11 901 902#endif // _LIBCPP_OPTIONAL 903