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 // 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 159namespace std // purposefully not using versioning namespace 160{ 161 162class _LIBCPP_EXCEPTION_ABI bad_optional_access 163 : public logic_error 164{ 165public: 166 _LIBCPP_INLINE_VISIBILITY 167 bad_optional_access() : logic_error("bad optional access") {} 168 169 // Get the key function ~bad_optional_access() into the dylib 170 virtual ~bad_optional_access() _NOEXCEPT; 171}; 172 173} // 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<in_place_t, _Up> && 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 optional(const optional&) = default; 603 _LIBCPP_INLINE_VISIBILITY 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 void 735 emplace(_Args&&... __args) 736 { 737 reset(); 738 this->__construct(_VSTD::forward<_Args>(__args)...); 739 } 740 741 template <class _Up, class... _Args, 742 class = enable_if_t 743 < 744 is_constructible_v<value_type, initializer_list<_Up>&, _Args...> 745 > 746 > 747 _LIBCPP_INLINE_VISIBILITY 748 void 749 emplace(initializer_list<_Up> __il, _Args&&... __args) 750 { 751 reset(); 752 this->__construct(__il, _VSTD::forward<_Args>(__args)...); 753 } 754 755 _LIBCPP_INLINE_VISIBILITY 756 void swap(optional& __opt) 757 noexcept(is_nothrow_move_constructible_v<value_type> && 758 is_nothrow_swappable_v<value_type>) 759 { 760 if (this->has_value() == __opt.has_value()) 761 { 762 using _VSTD::swap; 763 if (this->has_value()) 764 swap(this->__get(), __opt.__get()); 765 } 766 else 767 { 768 if (this->has_value()) 769 { 770 __opt.__construct(_VSTD::move(this->__get())); 771 reset(); 772 } 773 else 774 { 775 this->__construct(_VSTD::move(__opt.__get())); 776 __opt.reset(); 777 } 778 } 779 } 780 781 _LIBCPP_INLINE_VISIBILITY 782 constexpr 783 add_pointer_t<value_type const> 784 operator->() const 785 { 786 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); 787#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 788 return _VSTD::addressof(this->__get()); 789#else 790 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); 791#endif 792 } 793 794 _LIBCPP_INLINE_VISIBILITY 795 constexpr 796 add_pointer_t<value_type> 797 operator->() 798 { 799 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); 800#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 801 return _VSTD::addressof(this->__get()); 802#else 803 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); 804#endif 805 } 806 807 _LIBCPP_INLINE_VISIBILITY 808 constexpr 809 const value_type& 810 operator*() const& 811 { 812 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 813 return this->__get(); 814 } 815 816 _LIBCPP_INLINE_VISIBILITY 817 constexpr 818 value_type& 819 operator*() & 820 { 821 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 822 return this->__get(); 823 } 824 825 _LIBCPP_INLINE_VISIBILITY 826 constexpr 827 value_type&& 828 operator*() && 829 { 830 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 831 return _VSTD::move(this->__get()); 832 } 833 834 _LIBCPP_INLINE_VISIBILITY 835 constexpr 836 const value_type&& 837 operator*() const&& 838 { 839 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 840 return _VSTD::move(this->__get()); 841 } 842 843 _LIBCPP_INLINE_VISIBILITY 844 constexpr explicit operator bool() const noexcept { return has_value(); } 845 846 using __base::has_value; 847 using __base::__get; 848 849 _LIBCPP_INLINE_VISIBILITY 850 constexpr value_type const& value() const& 851 { 852 if (!this->has_value()) 853 __throw_bad_optional_access(); 854 return this->__get(); 855 } 856 857 _LIBCPP_INLINE_VISIBILITY 858 constexpr value_type& value() & 859 { 860 if (!this->has_value()) 861 __throw_bad_optional_access(); 862 return this->__get(); 863 } 864 865 _LIBCPP_INLINE_VISIBILITY 866 constexpr value_type&& value() && 867 { 868 if (!this->has_value()) 869 __throw_bad_optional_access(); 870 return _VSTD::move(this->__get()); 871 } 872 873 _LIBCPP_INLINE_VISIBILITY 874 constexpr value_type const&& value() const&& 875 { 876 if (!this->has_value()) 877 __throw_bad_optional_access(); 878 return _VSTD::move(this->__get()); 879 } 880 881 template <class _Up> 882 _LIBCPP_INLINE_VISIBILITY 883 constexpr value_type value_or(_Up&& __v) const& 884 { 885 static_assert(is_copy_constructible_v<value_type>, 886 "optional<T>::value_or: T must be copy constructible"); 887 static_assert(is_convertible_v<_Up, value_type>, 888 "optional<T>::value_or: U must be convertible to T"); 889 return this->has_value() ? this->__get() : 890 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 891 } 892 893 template <class _Up> 894 _LIBCPP_INLINE_VISIBILITY 895 value_type value_or(_Up&& __v) && 896 { 897 static_assert(is_move_constructible_v<value_type>, 898 "optional<T>::value_or: T must be move constructible"); 899 static_assert(is_convertible_v<_Up, value_type>, 900 "optional<T>::value_or: U must be convertible to T"); 901 return this->has_value() ? _VSTD::move(this->__get()) : 902 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 903 } 904 905 using __base::reset; 906 907private: 908 template <class _Up> 909 _LIBCPP_INLINE_VISIBILITY 910 static _Up* 911 __operator_arrow(true_type, _Up& __x) 912 { 913 return _VSTD::addressof(__x); 914 } 915 916 template <class _Up> 917 _LIBCPP_INLINE_VISIBILITY 918 static constexpr _Up* 919 __operator_arrow(false_type, _Up& __x) 920 { 921 return &__x; 922 } 923}; 924 925// Comparisons between optionals 926template <class _Tp> 927_LIBCPP_INLINE_VISIBILITY constexpr 928enable_if_t< 929 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 930 _VSTD::declval<const _Tp&>()), bool>, 931 bool 932> 933operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) 934{ 935 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 936 return false; 937 if (!static_cast<bool>(__x)) 938 return true; 939 return *__x == *__y; 940} 941 942template <class _Tp> 943_LIBCPP_INLINE_VISIBILITY constexpr 944enable_if_t< 945 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 946 _VSTD::declval<const _Tp&>()), bool>, 947 bool 948> 949operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) 950{ 951 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 952 return true; 953 if (!static_cast<bool>(__x)) 954 return false; 955 return *__x != *__y; 956} 957 958template <class _Tp> 959_LIBCPP_INLINE_VISIBILITY constexpr 960enable_if_t< 961 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 962 _VSTD::declval<const _Tp&>()), bool>, 963 bool 964> 965operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) 966{ 967 if (!static_cast<bool>(__y)) 968 return false; 969 if (!static_cast<bool>(__x)) 970 return true; 971 return *__x < *__y; 972} 973 974template <class _Tp> 975_LIBCPP_INLINE_VISIBILITY constexpr 976enable_if_t< 977 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 978 _VSTD::declval<const _Tp&>()), bool>, 979 bool 980> 981operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) 982{ 983 if (!static_cast<bool>(__x)) 984 return false; 985 if (!static_cast<bool>(__y)) 986 return true; 987 return *__x > *__y; 988} 989 990template <class _Tp> 991_LIBCPP_INLINE_VISIBILITY constexpr 992enable_if_t< 993 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 994 _VSTD::declval<const _Tp&>()), bool>, 995 bool 996> 997operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) 998{ 999 if (!static_cast<bool>(__x)) 1000 return true; 1001 if (!static_cast<bool>(__y)) 1002 return false; 1003 return *__x <= *__y; 1004} 1005 1006template <class _Tp> 1007_LIBCPP_INLINE_VISIBILITY constexpr 1008enable_if_t< 1009 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1010 _VSTD::declval<const _Tp&>()), bool>, 1011 bool 1012> 1013operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) 1014{ 1015 if (!static_cast<bool>(__y)) 1016 return true; 1017 if (!static_cast<bool>(__x)) 1018 return false; 1019 return *__x >= *__y; 1020} 1021 1022// Comparisons with nullopt 1023template <class _Tp> 1024_LIBCPP_INLINE_VISIBILITY constexpr 1025bool 1026operator==(const optional<_Tp>& __x, nullopt_t) noexcept 1027{ 1028 return !static_cast<bool>(__x); 1029} 1030 1031template <class _Tp> 1032_LIBCPP_INLINE_VISIBILITY constexpr 1033bool 1034operator==(nullopt_t, const optional<_Tp>& __x) noexcept 1035{ 1036 return !static_cast<bool>(__x); 1037} 1038 1039template <class _Tp> 1040_LIBCPP_INLINE_VISIBILITY constexpr 1041bool 1042operator!=(const optional<_Tp>& __x, nullopt_t) noexcept 1043{ 1044 return static_cast<bool>(__x); 1045} 1046 1047template <class _Tp> 1048_LIBCPP_INLINE_VISIBILITY constexpr 1049bool 1050operator!=(nullopt_t, const optional<_Tp>& __x) noexcept 1051{ 1052 return static_cast<bool>(__x); 1053} 1054 1055template <class _Tp> 1056_LIBCPP_INLINE_VISIBILITY constexpr 1057bool 1058operator<(const optional<_Tp>&, nullopt_t) noexcept 1059{ 1060 return false; 1061} 1062 1063template <class _Tp> 1064_LIBCPP_INLINE_VISIBILITY constexpr 1065bool 1066operator<(nullopt_t, const optional<_Tp>& __x) noexcept 1067{ 1068 return static_cast<bool>(__x); 1069} 1070 1071template <class _Tp> 1072_LIBCPP_INLINE_VISIBILITY constexpr 1073bool 1074operator<=(const optional<_Tp>& __x, nullopt_t) noexcept 1075{ 1076 return !static_cast<bool>(__x); 1077} 1078 1079template <class _Tp> 1080_LIBCPP_INLINE_VISIBILITY constexpr 1081bool 1082operator<=(nullopt_t, const optional<_Tp>&) noexcept 1083{ 1084 return true; 1085} 1086 1087template <class _Tp> 1088_LIBCPP_INLINE_VISIBILITY constexpr 1089bool 1090operator>(const optional<_Tp>& __x, nullopt_t) noexcept 1091{ 1092 return static_cast<bool>(__x); 1093} 1094 1095template <class _Tp> 1096_LIBCPP_INLINE_VISIBILITY constexpr 1097bool 1098operator>(nullopt_t, const optional<_Tp>&) noexcept 1099{ 1100 return false; 1101} 1102 1103template <class _Tp> 1104_LIBCPP_INLINE_VISIBILITY constexpr 1105bool 1106operator>=(const optional<_Tp>&, nullopt_t) noexcept 1107{ 1108 return true; 1109} 1110 1111template <class _Tp> 1112_LIBCPP_INLINE_VISIBILITY constexpr 1113bool 1114operator>=(nullopt_t, const optional<_Tp>& __x) noexcept 1115{ 1116 return !static_cast<bool>(__x); 1117} 1118 1119// Comparisons with T 1120template <class _Tp> 1121_LIBCPP_INLINE_VISIBILITY constexpr 1122enable_if_t< 1123 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1124 _VSTD::declval<const _Tp&>()), bool>, 1125 bool 1126> 1127operator==(const optional<_Tp>& __x, const _Tp& __v) 1128{ 1129 return static_cast<bool>(__x) ? *__x == __v : false; 1130} 1131 1132template <class _Tp> 1133_LIBCPP_INLINE_VISIBILITY constexpr 1134enable_if_t< 1135 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1136 _VSTD::declval<const _Tp&>()), bool>, 1137 bool 1138> 1139operator==(const _Tp& __v, const optional<_Tp>& __x) 1140{ 1141 return static_cast<bool>(__x) ? __v == *__x : false; 1142} 1143 1144template <class _Tp> 1145_LIBCPP_INLINE_VISIBILITY constexpr 1146enable_if_t< 1147 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1148 _VSTD::declval<const _Tp&>()), bool>, 1149 bool 1150> 1151operator!=(const optional<_Tp>& __x, const _Tp& __v) 1152{ 1153 return static_cast<bool>(__x) ? *__x != __v : true; 1154} 1155 1156template <class _Tp> 1157_LIBCPP_INLINE_VISIBILITY constexpr 1158enable_if_t< 1159 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1160 _VSTD::declval<const _Tp&>()), bool>, 1161 bool 1162> 1163operator!=(const _Tp& __v, const optional<_Tp>& __x) 1164{ 1165 return static_cast<bool>(__x) ? __v != *__x : true; 1166} 1167 1168template <class _Tp> 1169_LIBCPP_INLINE_VISIBILITY constexpr 1170enable_if_t< 1171 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1172 _VSTD::declval<const _Tp&>()), bool>, 1173 bool 1174> 1175operator<(const optional<_Tp>& __x, const _Tp& __v) 1176{ 1177 return static_cast<bool>(__x) ? *__x < __v : true; 1178} 1179 1180template <class _Tp> 1181_LIBCPP_INLINE_VISIBILITY constexpr 1182enable_if_t< 1183 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1184 _VSTD::declval<const _Tp&>()), bool>, 1185 bool 1186> 1187operator<(const _Tp& __v, const optional<_Tp>& __x) 1188{ 1189 return static_cast<bool>(__x) ? __v < *__x : false; 1190} 1191 1192template <class _Tp> 1193_LIBCPP_INLINE_VISIBILITY constexpr 1194enable_if_t< 1195 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1196 _VSTD::declval<const _Tp&>()), bool>, 1197 bool 1198> 1199operator<=(const optional<_Tp>& __x, const _Tp& __v) 1200{ 1201 return static_cast<bool>(__x) ? *__x <= __v : true; 1202} 1203 1204template <class _Tp> 1205_LIBCPP_INLINE_VISIBILITY constexpr 1206enable_if_t< 1207 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1208 _VSTD::declval<const _Tp&>()), bool>, 1209 bool 1210> 1211operator<=(const _Tp& __v, const optional<_Tp>& __x) 1212{ 1213 return static_cast<bool>(__x) ? __v <= *__x : false; 1214} 1215 1216template <class _Tp> 1217_LIBCPP_INLINE_VISIBILITY constexpr 1218enable_if_t< 1219 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1220 _VSTD::declval<const _Tp&>()), bool>, 1221 bool 1222> 1223operator>(const optional<_Tp>& __x, const _Tp& __v) 1224{ 1225 return static_cast<bool>(__x) ? *__x > __v : false; 1226} 1227 1228template <class _Tp> 1229_LIBCPP_INLINE_VISIBILITY constexpr 1230enable_if_t< 1231 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1232 _VSTD::declval<const _Tp&>()), bool>, 1233 bool 1234> 1235operator>(const _Tp& __v, const optional<_Tp>& __x) 1236{ 1237 return static_cast<bool>(__x) ? __v > *__x : true; 1238} 1239 1240template <class _Tp> 1241_LIBCPP_INLINE_VISIBILITY constexpr 1242enable_if_t< 1243 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1244 _VSTD::declval<const _Tp&>()), bool>, 1245 bool 1246> 1247operator>=(const optional<_Tp>& __x, const _Tp& __v) 1248{ 1249 return static_cast<bool>(__x) ? *__x >= __v : false; 1250} 1251 1252template <class _Tp> 1253_LIBCPP_INLINE_VISIBILITY constexpr 1254enable_if_t< 1255 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1256 _VSTD::declval<const _Tp&>()), bool>, 1257 bool 1258> 1259operator>=(const _Tp& __v, const optional<_Tp>& __x) 1260{ 1261 return static_cast<bool>(__x) ? __v >= *__x : true; 1262} 1263 1264 1265template <class _Tp> 1266inline _LIBCPP_INLINE_VISIBILITY 1267enable_if_t< 1268 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, 1269 void 1270> 1271swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 1272{ 1273 __x.swap(__y); 1274} 1275 1276template <class _Tp> 1277_LIBCPP_INLINE_VISIBILITY constexpr 1278optional<decay_t<_Tp>> make_optional(_Tp&& __v) 1279{ 1280 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v)); 1281} 1282 1283template <class _Tp, class... _Args> 1284_LIBCPP_INLINE_VISIBILITY constexpr 1285optional<_Tp> make_optional(_Args&&... __args) 1286{ 1287 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); 1288} 1289 1290template <class _Tp, class _Up, class... _Args> 1291_LIBCPP_INLINE_VISIBILITY constexpr 1292optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) 1293{ 1294 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...); 1295} 1296 1297template <class _Tp> 1298struct _LIBCPP_TEMPLATE_VIS hash<optional<_Tp> > 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<_Tp>()(*__opt) : 0; 1307 } 1308}; 1309 1310_LIBCPP_END_NAMESPACE_STD 1311 1312#endif // _LIBCPP_STD_VER > 14 1313 1314#endif // _LIBCPP_OPTIONAL 1315