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