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