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