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