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