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++1z 18 19 namespace std { 20 // 23.6.3, optional for object types 21 template <class T> class optional; 22 23 // 23.6.4, no-value state indicator 24 struct nullopt_t{see below }; 25 constexpr nullopt_t nullopt(unspecified ); 26 27 // 23.6.5, class bad_optional_access 28 class bad_optional_access; 29 30 // 23.6.6, relational operators 31 template <class T, class U> 32 constexpr bool operator==(const optional<T>&, const optional<U>&); 33 template <class T, class U> 34 constexpr bool operator!=(const optional<T>&, const optional<U>&); 35 template <class T, class U> 36 constexpr bool operator<(const optional<T>&, const optional<U>&); 37 template <class T, class U> 38 constexpr bool operator>(const optional<T>&, const optional<U>&); 39 template <class T, class U> 40 constexpr bool operator<=(const optional<T>&, const optional<U>&); 41 template <class T, class U> 42 constexpr bool operator>=(const optional<T>&, const optional<U>&); 43 44 // 23.6.7 comparison with nullopt 45 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; 46 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; 47 template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; 48 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; 49 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; 50 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; 51 template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; 52 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; 53 template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; 54 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; 55 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; 56 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; 57 58 // 23.6.8, comparison with T 59 template <class T, class U> constexpr bool operator==(const optional<T>&, const U&); 60 template <class T, class U> constexpr bool operator==(const U&, const optional<T>&); 61 template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&); 62 template <class T, class U> constexpr bool operator!=(const U&, const optional<T>&); 63 template <class T, class U> constexpr bool operator<(const optional<T>&, const U&); 64 template <class T, class U> constexpr bool operator<(const U&, const optional<T>&); 65 template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&); 66 template <class T, class U> constexpr bool operator<=(const U&, const optional<T>&); 67 template <class T, class U> constexpr bool operator>(const optional<T>&, const U&); 68 template <class T, class U> constexpr bool operator>(const U&, const optional<T>&); 69 template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&); 70 template <class T, class U> constexpr bool operator>=(const U&, const optional<T>&); 71 72 // 23.6.9, specialized algorithms 73 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); 74 template <class T> constexpr optional<see below > make_optional(T&&); 75 template <class T, class... Args> 76 constexpr optional<T> make_optional(Args&&... args); 77 template <class T, class U, class... Args> 78 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); 79 80 // 23.6.10, hash support 81 template <class T> struct hash; 82 template <class T> struct hash<optional<T>>; 83 84 template <class T> class optional { 85 public: 86 using value_type = T; 87 88 // 23.6.3.1, constructors 89 constexpr optional() noexcept; 90 constexpr optional(nullopt_t) noexcept; 91 optional(const optional &); 92 optional(optional &&) noexcept(see below); 93 template <class... Args> constexpr explicit optional(in_place_t, Args &&...); 94 template <class U, class... Args> 95 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...); 96 template <class U = T> 97 constexpr EXPLICIT optional(U &&); 98 template <class U> 99 constexpr EXPLICIT optional(const optional<U> &); 100 template <class U> 101 constexpr EXPLICIT optional(optional<U> &&); 102 103 // 23.6.3.2, destructor 104 ~optional(); 105 106 // 23.6.3.3, assignment 107 optional &operator=(nullopt_t) noexcept; 108 optional &operator=(const optional &); 109 optional &operator=(optional &&) noexcept(see below ); 110 template <class U = T> optional &operator=(U &&); 111 template <class U> optional &operator=(const optional<U> &); 112 template <class U> optional &operator=(optional<U> &&); 113 template <class... Args> T& emplace(Args &&...); 114 template <class U, class... Args> 115 T& emplace(initializer_list<U>, Args &&...); 116 117 // 23.6.3.4, swap 118 void swap(optional &) noexcept(see below ); 119 120 // 23.6.3.5, observers 121 constexpr T const *operator->() const; 122 constexpr T *operator->(); 123 constexpr T const &operator*() const &; 124 constexpr T &operator*() &; 125 constexpr T &&operator*() &&; 126 constexpr const T &&operator*() const &&; 127 constexpr explicit operator bool() const noexcept; 128 constexpr bool has_value() const noexcept; 129 constexpr T const &value() const &; 130 constexpr T &value() &; 131 constexpr T &&value() &&; 132 constexpr const T &&value() const &&; 133 template <class U> constexpr T value_or(U &&) const &; 134 template <class U> constexpr T value_or(U &&) &&; 135 136 // 23.6.3.6, modifiers 137 void reset() noexcept; 138 139 private: 140 T *val; // exposition only 141 }; 142 } // namespace std 143 144 */ 145 146 #include <__config> 147 #include <__debug> 148 #include <__functional_base> 149 #include <functional> 150 #include <initializer_list> 151 #include <new> 152 #include <stdexcept> 153 #include <type_traits> 154 #include <utility> 155 156 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 157 #pragma GCC system_header 158 #endif 159 160 _LIBCPP_PUSH_MACROS 161 #include <__undef_macros> 162 163 164 namespace std // purposefully not using versioning namespace 165 { 166 167 class _LIBCPP_EXCEPTION_ABI bad_optional_access 168 : public exception 169 { 170 public: 171 // Get the key function ~bad_optional_access() into the dylib 172 virtual ~bad_optional_access() _NOEXCEPT; 173 virtual const char* what() const _NOEXCEPT; 174 }; 175 176 } // std 177 178 #if _LIBCPP_STD_VER > 14 179 180 _LIBCPP_BEGIN_NAMESPACE_STD 181 182 _LIBCPP_NORETURN 183 inline _LIBCPP_INLINE_VISIBILITY 184 void __throw_bad_optional_access() { 185 #ifndef _LIBCPP_NO_EXCEPTIONS 186 throw bad_optional_access(); 187 #else 188 _VSTD::abort(); 189 #endif 190 } 191 192 struct nullopt_t 193 { 194 struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; }; 195 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {} 196 }; 197 198 /* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}}; 199 200 template <class _Tp, bool = is_trivially_destructible<_Tp>::value> 201 struct __optional_destruct_base; 202 203 template <class _Tp> 204 struct __optional_destruct_base<_Tp, false> 205 { 206 typedef _Tp value_type; 207 static_assert(is_object_v<value_type>, 208 "instantiation of optional with a non-object type is undefined behavior"); 209 union 210 { 211 char __null_state_; 212 value_type __val_; 213 }; 214 bool __engaged_; 215 216 _LIBCPP_INLINE_VISIBILITY 217 ~__optional_destruct_base() 218 { 219 if (__engaged_) 220 __val_.~value_type(); 221 } 222 223 _LIBCPP_INLINE_VISIBILITY 224 constexpr __optional_destruct_base() noexcept 225 : __null_state_(), 226 __engaged_(false) {} 227 228 template <class... _Args> 229 _LIBCPP_INLINE_VISIBILITY 230 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) 231 : __val_(_VSTD::forward<_Args>(__args)...), 232 __engaged_(true) {} 233 234 _LIBCPP_INLINE_VISIBILITY 235 void reset() noexcept 236 { 237 if (__engaged_) 238 { 239 __val_.~value_type(); 240 __engaged_ = false; 241 } 242 } 243 }; 244 245 template <class _Tp> 246 struct __optional_destruct_base<_Tp, true> 247 { 248 typedef _Tp value_type; 249 static_assert(is_object_v<value_type>, 250 "instantiation of optional with a non-object type is undefined behavior"); 251 union 252 { 253 char __null_state_; 254 value_type __val_; 255 }; 256 bool __engaged_; 257 258 _LIBCPP_INLINE_VISIBILITY 259 constexpr __optional_destruct_base() noexcept 260 : __null_state_(), 261 __engaged_(false) {} 262 263 template <class... _Args> 264 _LIBCPP_INLINE_VISIBILITY 265 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) 266 : __val_(_VSTD::forward<_Args>(__args)...), 267 __engaged_(true) {} 268 269 _LIBCPP_INLINE_VISIBILITY 270 void reset() noexcept 271 { 272 if (__engaged_) 273 { 274 __engaged_ = false; 275 } 276 } 277 }; 278 279 template <class _Tp, bool = is_reference<_Tp>::value> 280 struct __optional_storage_base : __optional_destruct_base<_Tp> 281 { 282 using __base = __optional_destruct_base<_Tp>; 283 using value_type = _Tp; 284 using __base::__base; 285 286 _LIBCPP_INLINE_VISIBILITY 287 constexpr bool has_value() const noexcept 288 { 289 return this->__engaged_; 290 } 291 292 _LIBCPP_INLINE_VISIBILITY 293 constexpr value_type& __get() & noexcept 294 { 295 return this->__val_; 296 } 297 _LIBCPP_INLINE_VISIBILITY 298 constexpr const value_type& __get() const& noexcept 299 { 300 return this->__val_; 301 } 302 _LIBCPP_INLINE_VISIBILITY 303 constexpr value_type&& __get() && noexcept 304 { 305 return _VSTD::move(this->__val_); 306 } 307 _LIBCPP_INLINE_VISIBILITY 308 constexpr const value_type&& __get() const&& noexcept 309 { 310 return _VSTD::move(this->__val_); 311 } 312 313 template <class... _Args> 314 _LIBCPP_INLINE_VISIBILITY 315 void __construct(_Args&&... __args) 316 { 317 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); 318 ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); 319 this->__engaged_ = true; 320 } 321 322 template <class _That> 323 _LIBCPP_INLINE_VISIBILITY 324 void __construct_from(_That&& __opt) 325 { 326 if (__opt.has_value()) 327 __construct(_VSTD::forward<_That>(__opt).__get()); 328 } 329 330 template <class _That> 331 _LIBCPP_INLINE_VISIBILITY 332 void __assign_from(_That&& __opt) 333 { 334 if (this->__engaged_ == __opt.has_value()) 335 { 336 if (this->__engaged_) 337 this->__val_ = _VSTD::forward<_That>(__opt).__get(); 338 } 339 else 340 { 341 if (this->__engaged_) 342 this->reset(); 343 else 344 __construct(_VSTD::forward<_That>(__opt).__get()); 345 } 346 } 347 }; 348 349 // optional<T&> is currently required ill-formed, however it may to be in the 350 // future. For this reason it has already been implemented to ensure we can 351 // make the change in an ABI compatible manner. 352 template <class _Tp> 353 struct __optional_storage_base<_Tp, true> 354 { 355 using value_type = _Tp; 356 using __raw_type = remove_reference_t<_Tp>; 357 __raw_type* __value_; 358 359 template <class _Up> 360 static constexpr bool __can_bind_reference() { 361 using _RawUp = typename remove_reference<_Up>::type; 362 using _UpPtr = _RawUp*; 363 using _RawTp = typename remove_reference<_Tp>::type; 364 using _TpPtr = _RawTp*; 365 using _CheckLValueArg = integral_constant<bool, 366 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) 367 || is_same<_RawUp, reference_wrapper<_RawTp>>::value 368 || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value 369 >; 370 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) 371 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value && 372 is_convertible<_UpPtr, _TpPtr>::value); 373 } 374 375 _LIBCPP_INLINE_VISIBILITY 376 constexpr __optional_storage_base() noexcept 377 : __value_(nullptr) {} 378 379 template <class _UArg> 380 _LIBCPP_INLINE_VISIBILITY 381 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) 382 : __value_(_VSTD::addressof(__uarg)) 383 { 384 static_assert(__can_bind_reference<_UArg>(), 385 "Attempted to construct a reference element in tuple from a " 386 "possible temporary"); 387 } 388 389 _LIBCPP_INLINE_VISIBILITY 390 void reset() noexcept { __value_ = nullptr; } 391 392 _LIBCPP_INLINE_VISIBILITY 393 constexpr bool has_value() const noexcept 394 { return __value_ != nullptr; } 395 396 _LIBCPP_INLINE_VISIBILITY 397 constexpr value_type& __get() const& noexcept 398 { return *__value_; } 399 400 _LIBCPP_INLINE_VISIBILITY 401 constexpr value_type&& __get() const&& noexcept 402 { return _VSTD::forward<value_type>(*__value_); } 403 404 template <class _UArg> 405 _LIBCPP_INLINE_VISIBILITY 406 void __construct(_UArg&& __val) 407 { 408 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); 409 static_assert(__can_bind_reference<_UArg>(), 410 "Attempted to construct a reference element in tuple from a " 411 "possible temporary"); 412 __value_ = _VSTD::addressof(__val); 413 } 414 415 template <class _That> 416 _LIBCPP_INLINE_VISIBILITY 417 void __construct_from(_That&& __opt) 418 { 419 if (__opt.has_value()) 420 __construct(_VSTD::forward<_That>(__opt).__get()); 421 } 422 423 template <class _That> 424 _LIBCPP_INLINE_VISIBILITY 425 void __assign_from(_That&& __opt) 426 { 427 if (has_value() == __opt.has_value()) 428 { 429 if (has_value()) 430 *__value_ = _VSTD::forward<_That>(__opt).__get(); 431 } 432 else 433 { 434 if (has_value()) 435 reset(); 436 else 437 __construct(_VSTD::forward<_That>(__opt).__get()); 438 } 439 } 440 }; 441 442 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value> 443 struct __optional_copy_base : __optional_storage_base<_Tp> 444 { 445 using __optional_storage_base<_Tp>::__optional_storage_base; 446 }; 447 448 template <class _Tp> 449 struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> 450 { 451 using __optional_storage_base<_Tp>::__optional_storage_base; 452 453 _LIBCPP_INLINE_VISIBILITY 454 __optional_copy_base() = default; 455 456 _LIBCPP_INLINE_VISIBILITY 457 __optional_copy_base(const __optional_copy_base& __opt) 458 { 459 this->__construct_from(__opt); 460 } 461 462 _LIBCPP_INLINE_VISIBILITY 463 __optional_copy_base(__optional_copy_base&&) = default; 464 _LIBCPP_INLINE_VISIBILITY 465 __optional_copy_base& operator=(const __optional_copy_base&) = default; 466 _LIBCPP_INLINE_VISIBILITY 467 __optional_copy_base& operator=(__optional_copy_base&&) = default; 468 }; 469 470 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value> 471 struct __optional_move_base : __optional_copy_base<_Tp> 472 { 473 using __optional_copy_base<_Tp>::__optional_copy_base; 474 }; 475 476 template <class _Tp> 477 struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> 478 { 479 using value_type = _Tp; 480 using __optional_copy_base<_Tp>::__optional_copy_base; 481 482 _LIBCPP_INLINE_VISIBILITY 483 __optional_move_base() = default; 484 _LIBCPP_INLINE_VISIBILITY 485 __optional_move_base(const __optional_move_base&) = default; 486 487 _LIBCPP_INLINE_VISIBILITY 488 __optional_move_base(__optional_move_base&& __opt) 489 noexcept(is_nothrow_move_constructible_v<value_type>) 490 { 491 this->__construct_from(_VSTD::move(__opt)); 492 } 493 494 _LIBCPP_INLINE_VISIBILITY 495 __optional_move_base& operator=(const __optional_move_base&) = default; 496 _LIBCPP_INLINE_VISIBILITY 497 __optional_move_base& operator=(__optional_move_base&&) = default; 498 }; 499 500 template <class _Tp, bool = 501 is_trivially_destructible<_Tp>::value && 502 is_trivially_copy_constructible<_Tp>::value && 503 is_trivially_copy_assignable<_Tp>::value> 504 struct __optional_copy_assign_base : __optional_move_base<_Tp> 505 { 506 using __optional_move_base<_Tp>::__optional_move_base; 507 }; 508 509 template <class _Tp> 510 struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> 511 { 512 using __optional_move_base<_Tp>::__optional_move_base; 513 514 _LIBCPP_INLINE_VISIBILITY 515 __optional_copy_assign_base() = default; 516 _LIBCPP_INLINE_VISIBILITY 517 __optional_copy_assign_base(const __optional_copy_assign_base&) = default; 518 _LIBCPP_INLINE_VISIBILITY 519 __optional_copy_assign_base(__optional_copy_assign_base&&) = default; 520 521 _LIBCPP_INLINE_VISIBILITY 522 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt) 523 { 524 this->__assign_from(__opt); 525 return *this; 526 } 527 528 _LIBCPP_INLINE_VISIBILITY 529 __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default; 530 }; 531 532 template <class _Tp, bool = 533 is_trivially_destructible<_Tp>::value && 534 is_trivially_move_constructible<_Tp>::value && 535 is_trivially_move_assignable<_Tp>::value> 536 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> 537 { 538 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; 539 }; 540 541 template <class _Tp> 542 struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> 543 { 544 using value_type = _Tp; 545 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; 546 547 _LIBCPP_INLINE_VISIBILITY 548 __optional_move_assign_base() = default; 549 _LIBCPP_INLINE_VISIBILITY 550 __optional_move_assign_base(const __optional_move_assign_base& __opt) = default; 551 _LIBCPP_INLINE_VISIBILITY 552 __optional_move_assign_base(__optional_move_assign_base&&) = default; 553 _LIBCPP_INLINE_VISIBILITY 554 __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default; 555 556 _LIBCPP_INLINE_VISIBILITY 557 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt) 558 noexcept(is_nothrow_move_assignable_v<value_type> && 559 is_nothrow_move_constructible_v<value_type>) 560 { 561 this->__assign_from(_VSTD::move(__opt)); 562 return *this; 563 } 564 }; 565 566 template <class _Tp> 567 using __optional_sfinae_ctor_base_t = __sfinae_ctor_base< 568 is_copy_constructible<_Tp>::value, 569 is_move_constructible<_Tp>::value 570 >; 571 572 template <class _Tp> 573 using __optional_sfinae_assign_base_t = __sfinae_assign_base< 574 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value), 575 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) 576 >; 577 578 template <class _Tp> 579 class optional 580 : private __optional_move_assign_base<_Tp> 581 , private __optional_sfinae_ctor_base_t<_Tp> 582 , private __optional_sfinae_assign_base_t<_Tp> 583 { 584 using __base = __optional_move_assign_base<_Tp>; 585 public: 586 using value_type = _Tp; 587 588 private: 589 // Disable the reference extension using this static assert. 590 static_assert(!is_same_v<value_type, in_place_t>, 591 "instantiation of optional with in_place_t is ill-formed"); 592 static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>, 593 "instantiation of optional with nullopt_t is ill-formed"); 594 static_assert(!is_reference_v<value_type>, 595 "instantiation of optional with a reference type is ill-formed"); 596 static_assert(is_destructible_v<value_type>, 597 "instantiation of optional with a non-destructible type is ill-formed"); 598 599 // LWG2756: conditionally explicit conversion from _Up 600 struct _CheckOptionalArgsConstructor { 601 template <class _Up> 602 static constexpr bool __enable_implicit() { 603 return is_constructible_v<_Tp, _Up&&> && 604 is_convertible_v<_Up&&, _Tp>; 605 } 606 607 template <class _Up> 608 static constexpr bool __enable_explicit() { 609 return is_constructible_v<_Tp, _Up&&> && 610 !is_convertible_v<_Up&&, _Tp>; 611 } 612 }; 613 template <class _Up> 614 using _CheckOptionalArgsCtor = conditional_t< 615 !is_same_v<decay_t<_Up>, in_place_t> && 616 !is_same_v<decay_t<_Up>, optional>, 617 _CheckOptionalArgsConstructor, 618 __check_tuple_constructor_fail 619 >; 620 template <class _QualUp> 621 struct _CheckOptionalLikeConstructor { 622 template <class _Up, class _Opt = optional<_Up>> 623 using __check_constructible_from_opt = __lazy_or< 624 is_constructible<_Tp, _Opt&>, 625 is_constructible<_Tp, _Opt const&>, 626 is_constructible<_Tp, _Opt&&>, 627 is_constructible<_Tp, _Opt const&&>, 628 is_convertible<_Opt&, _Tp>, 629 is_convertible<_Opt const&, _Tp>, 630 is_convertible<_Opt&&, _Tp>, 631 is_convertible<_Opt const&&, _Tp> 632 >; 633 template <class _Up, class _Opt = optional<_Up>> 634 using __check_assignable_from_opt = __lazy_or< 635 is_assignable<_Tp&, _Opt&>, 636 is_assignable<_Tp&, _Opt const&>, 637 is_assignable<_Tp&, _Opt&&>, 638 is_assignable<_Tp&, _Opt const&&> 639 >; 640 template <class _Up, class _QUp = _QualUp> 641 static constexpr bool __enable_implicit() { 642 return is_convertible<_QUp, _Tp>::value && 643 !__check_constructible_from_opt<_Up>::value; 644 } 645 template <class _Up, class _QUp = _QualUp> 646 static constexpr bool __enable_explicit() { 647 return !is_convertible<_QUp, _Tp>::value && 648 !__check_constructible_from_opt<_Up>::value; 649 } 650 template <class _Up, class _QUp = _QualUp> 651 static constexpr bool __enable_assign() { 652 // Construction and assignability of _Qup to _Tp has already been 653 // checked. 654 return !__check_constructible_from_opt<_Up>::value && 655 !__check_assignable_from_opt<_Up>::value; 656 } 657 }; 658 659 template <class _Up, class _QualUp> 660 using _CheckOptionalLikeCtor = conditional_t< 661 __lazy_and< 662 __lazy_not<is_same<_Up, _Tp>>, 663 is_constructible<_Tp, _QualUp> 664 >::value, 665 _CheckOptionalLikeConstructor<_QualUp>, 666 __check_tuple_constructor_fail 667 >; 668 template <class _Up, class _QualUp> 669 using _CheckOptionalLikeAssign = conditional_t< 670 __lazy_and< 671 __lazy_not<is_same<_Up, _Tp>>, 672 is_constructible<_Tp, _QualUp>, 673 is_assignable<_Tp&, _QualUp> 674 >::value, 675 _CheckOptionalLikeConstructor<_QualUp>, 676 __check_tuple_constructor_fail 677 >; 678 public: 679 680 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} 681 _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default; 682 _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default; 683 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} 684 685 template <class... _Args, class = enable_if_t< 686 is_constructible_v<value_type, _Args...>> 687 > 688 _LIBCPP_INLINE_VISIBILITY 689 constexpr explicit optional(in_place_t, _Args&&... __args) 690 : __base(in_place, _VSTD::forward<_Args>(__args)...) {} 691 692 template <class _Up, class... _Args, class = enable_if_t< 693 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> 694 > 695 _LIBCPP_INLINE_VISIBILITY 696 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 697 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} 698 699 template <class _Up = value_type, enable_if_t< 700 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>() 701 , int> = 0> 702 _LIBCPP_INLINE_VISIBILITY 703 constexpr optional(_Up&& __v) 704 : __base(in_place, _VSTD::forward<_Up>(__v)) {} 705 706 template <class _Up, enable_if_t< 707 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>() 708 , int> = 0> 709 _LIBCPP_INLINE_VISIBILITY 710 constexpr explicit optional(_Up&& __v) 711 : __base(in_place, _VSTD::forward<_Up>(__v)) {} 712 713 // LWG2756: conditionally explicit conversion from const optional<_Up>& 714 template <class _Up, enable_if_t< 715 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>() 716 , int> = 0> 717 _LIBCPP_INLINE_VISIBILITY 718 optional(const optional<_Up>& __v) 719 { 720 this->__construct_from(__v); 721 } 722 template <class _Up, enable_if_t< 723 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>() 724 , int> = 0> 725 _LIBCPP_INLINE_VISIBILITY 726 explicit optional(const optional<_Up>& __v) 727 { 728 this->__construct_from(__v); 729 } 730 731 // LWG2756: conditionally explicit conversion from optional<_Up>&& 732 template <class _Up, enable_if_t< 733 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>() 734 , int> = 0> 735 _LIBCPP_INLINE_VISIBILITY 736 optional(optional<_Up>&& __v) 737 { 738 this->__construct_from(_VSTD::move(__v)); 739 } 740 template <class _Up, enable_if_t< 741 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>() 742 , int> = 0> 743 _LIBCPP_INLINE_VISIBILITY 744 explicit optional(optional<_Up>&& __v) 745 { 746 this->__construct_from(_VSTD::move(__v)); 747 } 748 749 _LIBCPP_INLINE_VISIBILITY 750 optional& operator=(nullopt_t) noexcept 751 { 752 reset(); 753 return *this; 754 } 755 756 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default; 757 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default; 758 759 // LWG2756 760 template <class _Up = value_type, 761 class = enable_if_t 762 <__lazy_and< 763 integral_constant<bool, 764 !is_same_v<decay_t<_Up>, optional> && 765 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>) 766 >, 767 is_constructible<value_type, _Up>, 768 is_assignable<value_type&, _Up> 769 >::value> 770 > 771 _LIBCPP_INLINE_VISIBILITY 772 optional& 773 operator=(_Up&& __v) 774 { 775 if (this->has_value()) 776 this->__get() = _VSTD::forward<_Up>(__v); 777 else 778 this->__construct(_VSTD::forward<_Up>(__v)); 779 return *this; 780 } 781 782 // LWG2756 783 template <class _Up, enable_if_t< 784 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>() 785 , int> = 0> 786 _LIBCPP_INLINE_VISIBILITY 787 optional& 788 operator=(const optional<_Up>& __v) 789 { 790 this->__assign_from(__v); 791 return *this; 792 } 793 794 // LWG2756 795 template <class _Up, enable_if_t< 796 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>() 797 , int> = 0> 798 _LIBCPP_INLINE_VISIBILITY 799 optional& 800 operator=(optional<_Up>&& __v) 801 { 802 this->__assign_from(_VSTD::move(__v)); 803 return *this; 804 } 805 806 template <class... _Args, 807 class = enable_if_t 808 < 809 is_constructible_v<value_type, _Args...> 810 > 811 > 812 _LIBCPP_INLINE_VISIBILITY 813 _Tp & 814 emplace(_Args&&... __args) 815 { 816 reset(); 817 this->__construct(_VSTD::forward<_Args>(__args)...); 818 return this->__get(); 819 } 820 821 template <class _Up, class... _Args, 822 class = enable_if_t 823 < 824 is_constructible_v<value_type, initializer_list<_Up>&, _Args...> 825 > 826 > 827 _LIBCPP_INLINE_VISIBILITY 828 _Tp & 829 emplace(initializer_list<_Up> __il, _Args&&... __args) 830 { 831 reset(); 832 this->__construct(__il, _VSTD::forward<_Args>(__args)...); 833 return this->__get(); 834 } 835 836 _LIBCPP_INLINE_VISIBILITY 837 void swap(optional& __opt) 838 noexcept(is_nothrow_move_constructible_v<value_type> && 839 is_nothrow_swappable_v<value_type>) 840 { 841 if (this->has_value() == __opt.has_value()) 842 { 843 using _VSTD::swap; 844 if (this->has_value()) 845 swap(this->__get(), __opt.__get()); 846 } 847 else 848 { 849 if (this->has_value()) 850 { 851 __opt.__construct(_VSTD::move(this->__get())); 852 reset(); 853 } 854 else 855 { 856 this->__construct(_VSTD::move(__opt.__get())); 857 __opt.reset(); 858 } 859 } 860 } 861 862 _LIBCPP_INLINE_VISIBILITY 863 constexpr 864 add_pointer_t<value_type const> 865 operator->() const 866 { 867 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); 868 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 869 return _VSTD::addressof(this->__get()); 870 #else 871 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); 872 #endif 873 } 874 875 _LIBCPP_INLINE_VISIBILITY 876 constexpr 877 add_pointer_t<value_type> 878 operator->() 879 { 880 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); 881 #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 882 return _VSTD::addressof(this->__get()); 883 #else 884 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); 885 #endif 886 } 887 888 _LIBCPP_INLINE_VISIBILITY 889 constexpr 890 const value_type& 891 operator*() const& 892 { 893 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 894 return this->__get(); 895 } 896 897 _LIBCPP_INLINE_VISIBILITY 898 constexpr 899 value_type& 900 operator*() & 901 { 902 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 903 return this->__get(); 904 } 905 906 _LIBCPP_INLINE_VISIBILITY 907 constexpr 908 value_type&& 909 operator*() && 910 { 911 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 912 return _VSTD::move(this->__get()); 913 } 914 915 _LIBCPP_INLINE_VISIBILITY 916 constexpr 917 const value_type&& 918 operator*() const&& 919 { 920 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 921 return _VSTD::move(this->__get()); 922 } 923 924 _LIBCPP_INLINE_VISIBILITY 925 constexpr explicit operator bool() const noexcept { return has_value(); } 926 927 using __base::has_value; 928 using __base::__get; 929 930 _LIBCPP_INLINE_VISIBILITY 931 constexpr value_type const& value() const& 932 { 933 if (!this->has_value()) 934 __throw_bad_optional_access(); 935 return this->__get(); 936 } 937 938 _LIBCPP_INLINE_VISIBILITY 939 constexpr value_type& value() & 940 { 941 if (!this->has_value()) 942 __throw_bad_optional_access(); 943 return this->__get(); 944 } 945 946 _LIBCPP_INLINE_VISIBILITY 947 constexpr value_type&& value() && 948 { 949 if (!this->has_value()) 950 __throw_bad_optional_access(); 951 return _VSTD::move(this->__get()); 952 } 953 954 _LIBCPP_INLINE_VISIBILITY 955 constexpr value_type const&& value() const&& 956 { 957 if (!this->has_value()) 958 __throw_bad_optional_access(); 959 return _VSTD::move(this->__get()); 960 } 961 962 template <class _Up> 963 _LIBCPP_INLINE_VISIBILITY 964 constexpr value_type value_or(_Up&& __v) const& 965 { 966 static_assert(is_copy_constructible_v<value_type>, 967 "optional<T>::value_or: T must be copy constructible"); 968 static_assert(is_convertible_v<_Up, value_type>, 969 "optional<T>::value_or: U must be convertible to T"); 970 return this->has_value() ? this->__get() : 971 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 972 } 973 974 template <class _Up> 975 _LIBCPP_INLINE_VISIBILITY 976 constexpr value_type value_or(_Up&& __v) && 977 { 978 static_assert(is_move_constructible_v<value_type>, 979 "optional<T>::value_or: T must be move constructible"); 980 static_assert(is_convertible_v<_Up, value_type>, 981 "optional<T>::value_or: U must be convertible to T"); 982 return this->has_value() ? _VSTD::move(this->__get()) : 983 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 984 } 985 986 using __base::reset; 987 988 private: 989 template <class _Up> 990 _LIBCPP_INLINE_VISIBILITY 991 static _Up* 992 __operator_arrow(true_type, _Up& __x) 993 { 994 return _VSTD::addressof(__x); 995 } 996 997 template <class _Up> 998 _LIBCPP_INLINE_VISIBILITY 999 static constexpr _Up* 1000 __operator_arrow(false_type, _Up& __x) 1001 { 1002 return &__x; 1003 } 1004 }; 1005 1006 // Comparisons between optionals 1007 template <class _Tp, class _Up> 1008 _LIBCPP_INLINE_VISIBILITY constexpr 1009 enable_if_t< 1010 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1011 _VSTD::declval<const _Up&>()), bool>, 1012 bool 1013 > 1014 operator==(const optional<_Tp>& __x, const optional<_Up>& __y) 1015 { 1016 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 1017 return false; 1018 if (!static_cast<bool>(__x)) 1019 return true; 1020 return *__x == *__y; 1021 } 1022 1023 template <class _Tp, class _Up> 1024 _LIBCPP_INLINE_VISIBILITY constexpr 1025 enable_if_t< 1026 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1027 _VSTD::declval<const _Up&>()), bool>, 1028 bool 1029 > 1030 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) 1031 { 1032 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 1033 return true; 1034 if (!static_cast<bool>(__x)) 1035 return false; 1036 return *__x != *__y; 1037 } 1038 1039 template <class _Tp, class _Up> 1040 _LIBCPP_INLINE_VISIBILITY constexpr 1041 enable_if_t< 1042 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1043 _VSTD::declval<const _Up&>()), bool>, 1044 bool 1045 > 1046 operator<(const optional<_Tp>& __x, const optional<_Up>& __y) 1047 { 1048 if (!static_cast<bool>(__y)) 1049 return false; 1050 if (!static_cast<bool>(__x)) 1051 return true; 1052 return *__x < *__y; 1053 } 1054 1055 template <class _Tp, class _Up> 1056 _LIBCPP_INLINE_VISIBILITY constexpr 1057 enable_if_t< 1058 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1059 _VSTD::declval<const _Up&>()), bool>, 1060 bool 1061 > 1062 operator>(const optional<_Tp>& __x, const optional<_Up>& __y) 1063 { 1064 if (!static_cast<bool>(__x)) 1065 return false; 1066 if (!static_cast<bool>(__y)) 1067 return true; 1068 return *__x > *__y; 1069 } 1070 1071 template <class _Tp, class _Up> 1072 _LIBCPP_INLINE_VISIBILITY constexpr 1073 enable_if_t< 1074 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1075 _VSTD::declval<const _Up&>()), bool>, 1076 bool 1077 > 1078 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) 1079 { 1080 if (!static_cast<bool>(__x)) 1081 return true; 1082 if (!static_cast<bool>(__y)) 1083 return false; 1084 return *__x <= *__y; 1085 } 1086 1087 template <class _Tp, class _Up> 1088 _LIBCPP_INLINE_VISIBILITY constexpr 1089 enable_if_t< 1090 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1091 _VSTD::declval<const _Up&>()), bool>, 1092 bool 1093 > 1094 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) 1095 { 1096 if (!static_cast<bool>(__y)) 1097 return true; 1098 if (!static_cast<bool>(__x)) 1099 return false; 1100 return *__x >= *__y; 1101 } 1102 1103 // Comparisons with nullopt 1104 template <class _Tp> 1105 _LIBCPP_INLINE_VISIBILITY constexpr 1106 bool 1107 operator==(const optional<_Tp>& __x, nullopt_t) noexcept 1108 { 1109 return !static_cast<bool>(__x); 1110 } 1111 1112 template <class _Tp> 1113 _LIBCPP_INLINE_VISIBILITY constexpr 1114 bool 1115 operator==(nullopt_t, const optional<_Tp>& __x) noexcept 1116 { 1117 return !static_cast<bool>(__x); 1118 } 1119 1120 template <class _Tp> 1121 _LIBCPP_INLINE_VISIBILITY constexpr 1122 bool 1123 operator!=(const optional<_Tp>& __x, nullopt_t) noexcept 1124 { 1125 return static_cast<bool>(__x); 1126 } 1127 1128 template <class _Tp> 1129 _LIBCPP_INLINE_VISIBILITY constexpr 1130 bool 1131 operator!=(nullopt_t, const optional<_Tp>& __x) noexcept 1132 { 1133 return static_cast<bool>(__x); 1134 } 1135 1136 template <class _Tp> 1137 _LIBCPP_INLINE_VISIBILITY constexpr 1138 bool 1139 operator<(const optional<_Tp>&, nullopt_t) noexcept 1140 { 1141 return false; 1142 } 1143 1144 template <class _Tp> 1145 _LIBCPP_INLINE_VISIBILITY constexpr 1146 bool 1147 operator<(nullopt_t, const optional<_Tp>& __x) noexcept 1148 { 1149 return static_cast<bool>(__x); 1150 } 1151 1152 template <class _Tp> 1153 _LIBCPP_INLINE_VISIBILITY constexpr 1154 bool 1155 operator<=(const optional<_Tp>& __x, nullopt_t) noexcept 1156 { 1157 return !static_cast<bool>(__x); 1158 } 1159 1160 template <class _Tp> 1161 _LIBCPP_INLINE_VISIBILITY constexpr 1162 bool 1163 operator<=(nullopt_t, const optional<_Tp>&) noexcept 1164 { 1165 return true; 1166 } 1167 1168 template <class _Tp> 1169 _LIBCPP_INLINE_VISIBILITY constexpr 1170 bool 1171 operator>(const optional<_Tp>& __x, nullopt_t) noexcept 1172 { 1173 return static_cast<bool>(__x); 1174 } 1175 1176 template <class _Tp> 1177 _LIBCPP_INLINE_VISIBILITY constexpr 1178 bool 1179 operator>(nullopt_t, const optional<_Tp>&) noexcept 1180 { 1181 return false; 1182 } 1183 1184 template <class _Tp> 1185 _LIBCPP_INLINE_VISIBILITY constexpr 1186 bool 1187 operator>=(const optional<_Tp>&, nullopt_t) noexcept 1188 { 1189 return true; 1190 } 1191 1192 template <class _Tp> 1193 _LIBCPP_INLINE_VISIBILITY constexpr 1194 bool 1195 operator>=(nullopt_t, const optional<_Tp>& __x) noexcept 1196 { 1197 return !static_cast<bool>(__x); 1198 } 1199 1200 // Comparisons with T 1201 template <class _Tp, class _Up> 1202 _LIBCPP_INLINE_VISIBILITY constexpr 1203 enable_if_t< 1204 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1205 _VSTD::declval<const _Up&>()), bool>, 1206 bool 1207 > 1208 operator==(const optional<_Tp>& __x, const _Up& __v) 1209 { 1210 return static_cast<bool>(__x) ? *__x == __v : false; 1211 } 1212 1213 template <class _Tp, class _Up> 1214 _LIBCPP_INLINE_VISIBILITY constexpr 1215 enable_if_t< 1216 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1217 _VSTD::declval<const _Up&>()), bool>, 1218 bool 1219 > 1220 operator==(const _Tp& __v, const optional<_Up>& __x) 1221 { 1222 return static_cast<bool>(__x) ? __v == *__x : false; 1223 } 1224 1225 template <class _Tp, class _Up> 1226 _LIBCPP_INLINE_VISIBILITY constexpr 1227 enable_if_t< 1228 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1229 _VSTD::declval<const _Up&>()), bool>, 1230 bool 1231 > 1232 operator!=(const optional<_Tp>& __x, const _Up& __v) 1233 { 1234 return static_cast<bool>(__x) ? *__x != __v : true; 1235 } 1236 1237 template <class _Tp, class _Up> 1238 _LIBCPP_INLINE_VISIBILITY constexpr 1239 enable_if_t< 1240 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1241 _VSTD::declval<const _Up&>()), bool>, 1242 bool 1243 > 1244 operator!=(const _Tp& __v, const optional<_Up>& __x) 1245 { 1246 return static_cast<bool>(__x) ? __v != *__x : true; 1247 } 1248 1249 template <class _Tp, class _Up> 1250 _LIBCPP_INLINE_VISIBILITY constexpr 1251 enable_if_t< 1252 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1253 _VSTD::declval<const _Up&>()), bool>, 1254 bool 1255 > 1256 operator<(const optional<_Tp>& __x, const _Up& __v) 1257 { 1258 return static_cast<bool>(__x) ? *__x < __v : true; 1259 } 1260 1261 template <class _Tp, class _Up> 1262 _LIBCPP_INLINE_VISIBILITY constexpr 1263 enable_if_t< 1264 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1265 _VSTD::declval<const _Up&>()), bool>, 1266 bool 1267 > 1268 operator<(const _Tp& __v, const optional<_Up>& __x) 1269 { 1270 return static_cast<bool>(__x) ? __v < *__x : false; 1271 } 1272 1273 template <class _Tp, class _Up> 1274 _LIBCPP_INLINE_VISIBILITY constexpr 1275 enable_if_t< 1276 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1277 _VSTD::declval<const _Up&>()), bool>, 1278 bool 1279 > 1280 operator<=(const optional<_Tp>& __x, const _Up& __v) 1281 { 1282 return static_cast<bool>(__x) ? *__x <= __v : true; 1283 } 1284 1285 template <class _Tp, class _Up> 1286 _LIBCPP_INLINE_VISIBILITY constexpr 1287 enable_if_t< 1288 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1289 _VSTD::declval<const _Up&>()), bool>, 1290 bool 1291 > 1292 operator<=(const _Tp& __v, const optional<_Up>& __x) 1293 { 1294 return static_cast<bool>(__x) ? __v <= *__x : false; 1295 } 1296 1297 template <class _Tp, class _Up> 1298 _LIBCPP_INLINE_VISIBILITY constexpr 1299 enable_if_t< 1300 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1301 _VSTD::declval<const _Up&>()), bool>, 1302 bool 1303 > 1304 operator>(const optional<_Tp>& __x, const _Up& __v) 1305 { 1306 return static_cast<bool>(__x) ? *__x > __v : false; 1307 } 1308 1309 template <class _Tp, class _Up> 1310 _LIBCPP_INLINE_VISIBILITY constexpr 1311 enable_if_t< 1312 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1313 _VSTD::declval<const _Up&>()), bool>, 1314 bool 1315 > 1316 operator>(const _Tp& __v, const optional<_Up>& __x) 1317 { 1318 return static_cast<bool>(__x) ? __v > *__x : true; 1319 } 1320 1321 template <class _Tp, class _Up> 1322 _LIBCPP_INLINE_VISIBILITY constexpr 1323 enable_if_t< 1324 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1325 _VSTD::declval<const _Up&>()), bool>, 1326 bool 1327 > 1328 operator>=(const optional<_Tp>& __x, const _Up& __v) 1329 { 1330 return static_cast<bool>(__x) ? *__x >= __v : false; 1331 } 1332 1333 template <class _Tp, class _Up> 1334 _LIBCPP_INLINE_VISIBILITY constexpr 1335 enable_if_t< 1336 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1337 _VSTD::declval<const _Up&>()), bool>, 1338 bool 1339 > 1340 operator>=(const _Tp& __v, const optional<_Up>& __x) 1341 { 1342 return static_cast<bool>(__x) ? __v >= *__x : true; 1343 } 1344 1345 1346 template <class _Tp> 1347 inline _LIBCPP_INLINE_VISIBILITY 1348 enable_if_t< 1349 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, 1350 void 1351 > 1352 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 1353 { 1354 __x.swap(__y); 1355 } 1356 1357 template <class _Tp> 1358 _LIBCPP_INLINE_VISIBILITY constexpr 1359 optional<decay_t<_Tp>> make_optional(_Tp&& __v) 1360 { 1361 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v)); 1362 } 1363 1364 template <class _Tp, class... _Args> 1365 _LIBCPP_INLINE_VISIBILITY constexpr 1366 optional<_Tp> make_optional(_Args&&... __args) 1367 { 1368 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); 1369 } 1370 1371 template <class _Tp, class _Up, class... _Args> 1372 _LIBCPP_INLINE_VISIBILITY constexpr 1373 optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) 1374 { 1375 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...); 1376 } 1377 1378 template <class _Tp> 1379 struct _LIBCPP_TEMPLATE_VIS hash< 1380 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> 1381 > 1382 { 1383 typedef optional<_Tp> argument_type; 1384 typedef size_t result_type; 1385 1386 _LIBCPP_INLINE_VISIBILITY 1387 result_type operator()(const argument_type& __opt) const 1388 { 1389 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0; 1390 } 1391 }; 1392 1393 _LIBCPP_END_NAMESPACE_STD 1394 1395 #endif // _LIBCPP_STD_VER > 14 1396 1397 _LIBCPP_POP_MACROS 1398 1399 #endif // _LIBCPP_OPTIONAL 1400