1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_OPTIONAL 11#define _LIBCPP_OPTIONAL 12 13/* 14 optional synopsis 15 16// C++1z 17 18namespace std { 19 // 23.6.3, optional for object types 20 template <class T> class optional; 21 22 // 23.6.4, no-value state indicator 23 struct nullopt_t{see below }; 24 inline constexpr nullopt_t nullopt(unspecified ); 25 26 // 23.6.5, class bad_optional_access 27 class bad_optional_access; 28 29 // 23.6.6, relational operators 30 template <class T, class U> 31 constexpr bool operator==(const optional<T>&, const optional<U>&); 32 template <class T, class U> 33 constexpr bool operator!=(const optional<T>&, const optional<U>&); 34 template <class T, class U> 35 constexpr bool operator<(const optional<T>&, const optional<U>&); 36 template <class T, class U> 37 constexpr bool operator>(const optional<T>&, const optional<U>&); 38 template <class T, class U> 39 constexpr bool operator<=(const optional<T>&, const optional<U>&); 40 template <class T, class U> 41 constexpr bool operator>=(const optional<T>&, const optional<U>&); 42 43 // 23.6.7 comparison with nullopt 44 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; 45 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; 46 template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; 47 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; 48 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; 49 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; 50 template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; 51 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; 52 template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; 53 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; 54 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; 55 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; 56 57 // 23.6.8, comparison with T 58 template <class T, class U> constexpr bool operator==(const optional<T>&, const U&); 59 template <class T, class U> constexpr bool operator==(const T&, const optional<U>&); 60 template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&); 61 template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&); 62 template <class T, class U> constexpr bool operator<(const optional<T>&, const U&); 63 template <class T, class U> constexpr bool operator<(const T&, const optional<U>&); 64 template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&); 65 template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&); 66 template <class T, class U> constexpr bool operator>(const optional<T>&, const U&); 67 template <class T, class U> constexpr bool operator>(const T&, const optional<U>&); 68 template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&); 69 template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&); 70 71 // 23.6.9, specialized algorithms 72 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20 73 template <class T> constexpr optional<see below > make_optional(T&&); 74 template <class T, class... Args> 75 constexpr optional<T> make_optional(Args&&... args); 76 template <class T, class U, class... Args> 77 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); 78 79 // 23.6.10, hash support 80 template <class T> struct hash; 81 template <class T> struct hash<optional<T>>; 82 83 template <class T> class optional { 84 public: 85 using value_type = T; 86 87 // 23.6.3.1, constructors 88 constexpr optional() noexcept; 89 constexpr optional(nullopt_t) noexcept; 90 constexpr optional(const optional &); 91 constexpr optional(optional &&) noexcept(see below); 92 template <class... Args> constexpr explicit optional(in_place_t, Args &&...); 93 template <class U, class... Args> 94 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...); 95 template <class U = T> 96 constexpr explicit(see-below) optional(U &&); 97 template <class U> 98 explicit(see-below) optional(const optional<U> &); // constexpr in C++20 99 template <class U> 100 explicit(see-below) optional(optional<U> &&); // constexpr in C++20 101 102 // 23.6.3.2, destructor 103 ~optional(); // constexpr in C++20 104 105 // 23.6.3.3, assignment 106 optional &operator=(nullopt_t) noexcept; // constexpr in C++20 107 constexpr optional &operator=(const optional &); 108 constexpr optional &operator=(optional &&) noexcept(see below); 109 template <class U = T> optional &operator=(U &&); // constexpr in C++20 110 template <class U> optional &operator=(const optional<U> &); // constexpr in C++20 111 template <class U> optional &operator=(optional<U> &&); // constexpr in C++20 112 template <class... Args> T& emplace(Args &&...); // constexpr in C++20 113 template <class U, class... Args> 114 T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20 115 116 // 23.6.3.4, swap 117 void swap(optional &) noexcept(see below ); // constexpr in C++20 118 119 // 23.6.3.5, observers 120 constexpr T const *operator->() const; 121 constexpr T *operator->(); 122 constexpr T const &operator*() const &; 123 constexpr T &operator*() &; 124 constexpr T &&operator*() &&; 125 constexpr const T &&operator*() const &&; 126 constexpr explicit operator bool() const noexcept; 127 constexpr bool has_value() const noexcept; 128 constexpr T const &value() const &; 129 constexpr T &value() &; 130 constexpr T &&value() &&; 131 constexpr const T &&value() const &&; 132 template <class U> constexpr T value_or(U &&) const &; 133 template <class U> constexpr T value_or(U &&) &&; 134 135 // [optional.monadic], monadic operations 136 template<class F> constexpr auto and_then(F&& f) &; // since C++23 137 template<class F> constexpr auto and_then(F&& f) &&; // since C++23 138 template<class F> constexpr auto and_then(F&& f) const&; // since C++23 139 template<class F> constexpr auto and_then(F&& f) const&&; // since C++23 140 template<class F> constexpr auto transform(F&& f) &; // since C++23 141 template<class F> constexpr auto transform(F&& f) &&; // since C++23 142 template<class F> constexpr auto transform(F&& f) const&; // since C++23 143 template<class F> constexpr auto transform(F&& f) const&&; // since C++23 144 template<class F> constexpr optional or_else(F&& f) &&; // since C++23 145 template<class F> constexpr optional or_else(F&& f) const&; // since C++23 146 147 // 23.6.3.6, modifiers 148 void reset() noexcept; // constexpr in C++20 149 150 private: 151 T *val; // exposition only 152 }; 153 154template<class T> 155 optional(T) -> optional<T>; 156 157} // namespace std 158 159*/ 160 161#include <__assert> // all public C++ headers provide the assertion handler 162#include <__availability> 163#include <__concepts/invocable.h> 164#include <__config> 165#include <__functional/hash.h> 166#include <__functional/invoke.h> 167#include <__functional/unary_function.h> 168#include <__memory/addressof.h> 169#include <__memory/construct_at.h> 170#include <__tuple/sfinae_helpers.h> 171#include <__type_traits/conjunction.h> 172#include <__type_traits/disjunction.h> 173#include <__type_traits/is_trivially_copy_assignable.h> 174#include <__type_traits/is_trivially_copy_constructible.h> 175#include <__type_traits/is_trivially_destructible.h> 176#include <__type_traits/is_trivially_move_assignable.h> 177#include <__type_traits/is_trivially_move_constructible.h> 178#include <__type_traits/negation.h> 179#include <__utility/declval.h> 180#include <__utility/forward.h> 181#include <__utility/in_place.h> 182#include <__utility/move.h> 183#include <__utility/swap.h> 184#include <__verbose_abort> 185#include <initializer_list> 186#include <new> 187#include <stdexcept> 188#include <version> 189 190// standard-mandated includes 191 192// [optional.syn] 193#include <compare> 194 195#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 196# pragma GCC system_header 197#endif 198 199namespace std // purposefully not using versioning namespace 200{ 201 202class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access 203 : public exception 204{ 205public: 206 // Get the key function ~bad_optional_access() into the dylib 207 ~bad_optional_access() _NOEXCEPT override; 208 const char* what() const _NOEXCEPT override; 209}; 210 211} // namespace std 212 213#if _LIBCPP_STD_VER >= 17 214 215_LIBCPP_BEGIN_NAMESPACE_STD 216 217_LIBCPP_NORETURN 218inline _LIBCPP_INLINE_VISIBILITY 219_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 220void __throw_bad_optional_access() { 221#ifndef _LIBCPP_HAS_NO_EXCEPTIONS 222 throw bad_optional_access(); 223#else 224 _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode"); 225#endif 226} 227 228struct nullopt_t 229{ 230 struct __secret_tag { explicit __secret_tag() = default; }; 231 _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {} 232}; 233 234inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}}; 235 236struct __optional_construct_from_invoke_tag {}; 237 238template <class _Tp, bool = is_trivially_destructible<_Tp>::value> 239struct __optional_destruct_base; 240 241template <class _Tp> 242struct __optional_destruct_base<_Tp, false> 243{ 244 typedef _Tp value_type; 245 static_assert(is_object_v<value_type>, 246 "instantiation of optional with a non-object type is undefined behavior"); 247 union 248 { 249 char __null_state_; 250 value_type __val_; 251 }; 252 bool __engaged_; 253 254 _LIBCPP_INLINE_VISIBILITY 255 _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base() 256 { 257 if (__engaged_) 258 __val_.~value_type(); 259 } 260 261 _LIBCPP_INLINE_VISIBILITY 262 constexpr __optional_destruct_base() noexcept 263 : __null_state_(), 264 __engaged_(false) {} 265 266 template <class... _Args> 267 _LIBCPP_INLINE_VISIBILITY 268 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) 269 : __val_(_VSTD::forward<_Args>(__args)...), 270 __engaged_(true) {} 271 272#if _LIBCPP_STD_VER >= 23 273 template <class _Fp, class... _Args> 274 _LIBCPP_HIDE_FROM_ABI 275 constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) 276 : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {} 277#endif 278 279 _LIBCPP_INLINE_VISIBILITY 280 _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept 281 { 282 if (__engaged_) 283 { 284 __val_.~value_type(); 285 __engaged_ = false; 286 } 287 } 288}; 289 290template <class _Tp> 291struct __optional_destruct_base<_Tp, true> 292{ 293 typedef _Tp value_type; 294 static_assert(is_object_v<value_type>, 295 "instantiation of optional with a non-object type is undefined behavior"); 296 union 297 { 298 char __null_state_; 299 value_type __val_; 300 }; 301 bool __engaged_; 302 303 _LIBCPP_INLINE_VISIBILITY 304 constexpr __optional_destruct_base() noexcept 305 : __null_state_(), 306 __engaged_(false) {} 307 308 template <class... _Args> 309 _LIBCPP_INLINE_VISIBILITY 310 constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) 311 : __val_(_VSTD::forward<_Args>(__args)...), 312 __engaged_(true) {} 313 314#if _LIBCPP_STD_VER >= 23 315 template <class _Fp, class... _Args> 316 _LIBCPP_HIDE_FROM_ABI 317 constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) 318 : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {} 319#endif 320 321 _LIBCPP_INLINE_VISIBILITY 322 _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept 323 { 324 if (__engaged_) 325 { 326 __engaged_ = false; 327 } 328 } 329}; 330 331template <class _Tp, bool = is_reference<_Tp>::value> 332struct __optional_storage_base : __optional_destruct_base<_Tp> 333{ 334 using __base = __optional_destruct_base<_Tp>; 335 using value_type = _Tp; 336 using __base::__base; 337 338 _LIBCPP_INLINE_VISIBILITY 339 constexpr bool has_value() const noexcept 340 { 341 return this->__engaged_; 342 } 343 344 _LIBCPP_INLINE_VISIBILITY 345 constexpr value_type& __get() & noexcept 346 { 347 return this->__val_; 348 } 349 _LIBCPP_INLINE_VISIBILITY 350 constexpr const value_type& __get() const& noexcept 351 { 352 return this->__val_; 353 } 354 _LIBCPP_INLINE_VISIBILITY 355 constexpr value_type&& __get() && noexcept 356 { 357 return _VSTD::move(this->__val_); 358 } 359 _LIBCPP_INLINE_VISIBILITY 360 constexpr const value_type&& __get() const&& noexcept 361 { 362 return _VSTD::move(this->__val_); 363 } 364 365 template <class... _Args> 366 _LIBCPP_INLINE_VISIBILITY 367 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) 368 { 369 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); 370#if _LIBCPP_STD_VER >= 20 371 _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...); 372#else 373 ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); 374#endif 375 this->__engaged_ = true; 376 } 377 378 template <class _That> 379 _LIBCPP_INLINE_VISIBILITY 380 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) 381 { 382 if (__opt.has_value()) 383 __construct(_VSTD::forward<_That>(__opt).__get()); 384 } 385 386 template <class _That> 387 _LIBCPP_INLINE_VISIBILITY 388 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) 389 { 390 if (this->__engaged_ == __opt.has_value()) 391 { 392 if (this->__engaged_) 393 this->__val_ = _VSTD::forward<_That>(__opt).__get(); 394 } 395 else 396 { 397 if (this->__engaged_) 398 this->reset(); 399 else 400 __construct(_VSTD::forward<_That>(__opt).__get()); 401 } 402 } 403}; 404 405// optional<T&> is currently required to be ill-formed. However, it may 406// be allowed in the future. For this reason, it has already been implemented 407// to ensure we can make the change in an ABI-compatible manner. 408template <class _Tp> 409struct __optional_storage_base<_Tp, true> 410{ 411 using value_type = _Tp; 412 using __raw_type = remove_reference_t<_Tp>; 413 __raw_type* __value_; 414 415 template <class _Up> 416 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() { 417 using _RawUp = __libcpp_remove_reference_t<_Up>; 418 using _UpPtr = _RawUp*; 419 using _RawTp = __libcpp_remove_reference_t<_Tp>; 420 using _TpPtr = _RawTp*; 421 using _CheckLValueArg = integral_constant<bool, 422 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) 423 || is_same<_RawUp, reference_wrapper<_RawTp>>::value 424 || is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value 425 >; 426 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) 427 || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value && 428 is_convertible<_UpPtr, _TpPtr>::value); 429 } 430 431 _LIBCPP_INLINE_VISIBILITY 432 constexpr __optional_storage_base() noexcept 433 : __value_(nullptr) {} 434 435 template <class _UArg> 436 _LIBCPP_INLINE_VISIBILITY 437 constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) 438 : __value_(_VSTD::addressof(__uarg)) 439 { 440 static_assert(__can_bind_reference<_UArg>(), 441 "Attempted to construct a reference element in tuple from a " 442 "possible temporary"); 443 } 444 445 _LIBCPP_INLINE_VISIBILITY 446 _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; } 447 448 _LIBCPP_INLINE_VISIBILITY 449 constexpr bool has_value() const noexcept 450 { return __value_ != nullptr; } 451 452 _LIBCPP_INLINE_VISIBILITY 453 constexpr value_type& __get() const& noexcept 454 { return *__value_; } 455 456 _LIBCPP_INLINE_VISIBILITY 457 constexpr value_type&& __get() const&& noexcept 458 { return _VSTD::forward<value_type>(*__value_); } 459 460 template <class _UArg> 461 _LIBCPP_INLINE_VISIBILITY 462 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) 463 { 464 _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); 465 static_assert(__can_bind_reference<_UArg>(), 466 "Attempted to construct a reference element in tuple from a " 467 "possible temporary"); 468 __value_ = _VSTD::addressof(__val); 469 } 470 471 template <class _That> 472 _LIBCPP_INLINE_VISIBILITY 473 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) 474 { 475 if (__opt.has_value()) 476 __construct(_VSTD::forward<_That>(__opt).__get()); 477 } 478 479 template <class _That> 480 _LIBCPP_INLINE_VISIBILITY 481 _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) 482 { 483 if (has_value() == __opt.has_value()) 484 { 485 if (has_value()) 486 *__value_ = _VSTD::forward<_That>(__opt).__get(); 487 } 488 else 489 { 490 if (has_value()) 491 reset(); 492 else 493 __construct(_VSTD::forward<_That>(__opt).__get()); 494 } 495 } 496}; 497 498template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value> 499struct __optional_copy_base : __optional_storage_base<_Tp> 500{ 501 using __optional_storage_base<_Tp>::__optional_storage_base; 502}; 503 504template <class _Tp> 505struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> 506{ 507 using __optional_storage_base<_Tp>::__optional_storage_base; 508 509 _LIBCPP_INLINE_VISIBILITY 510 __optional_copy_base() = default; 511 512 _LIBCPP_INLINE_VISIBILITY 513 _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt) 514 { 515 this->__construct_from(__opt); 516 } 517 518 _LIBCPP_INLINE_VISIBILITY 519 __optional_copy_base(__optional_copy_base&&) = default; 520 _LIBCPP_INLINE_VISIBILITY 521 __optional_copy_base& operator=(const __optional_copy_base&) = default; 522 _LIBCPP_INLINE_VISIBILITY 523 __optional_copy_base& operator=(__optional_copy_base&&) = default; 524}; 525 526template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value> 527struct __optional_move_base : __optional_copy_base<_Tp> 528{ 529 using __optional_copy_base<_Tp>::__optional_copy_base; 530}; 531 532template <class _Tp> 533struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> 534{ 535 using value_type = _Tp; 536 using __optional_copy_base<_Tp>::__optional_copy_base; 537 538 _LIBCPP_INLINE_VISIBILITY 539 __optional_move_base() = default; 540 _LIBCPP_INLINE_VISIBILITY 541 __optional_move_base(const __optional_move_base&) = default; 542 543 _LIBCPP_INLINE_VISIBILITY 544 _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_base(__optional_move_base&& __opt) 545 noexcept(is_nothrow_move_constructible_v<value_type>) 546 { 547 this->__construct_from(_VSTD::move(__opt)); 548 } 549 550 _LIBCPP_INLINE_VISIBILITY 551 __optional_move_base& operator=(const __optional_move_base&) = default; 552 _LIBCPP_INLINE_VISIBILITY 553 __optional_move_base& operator=(__optional_move_base&&) = default; 554}; 555 556template <class _Tp, bool = 557 is_trivially_destructible<_Tp>::value && 558 is_trivially_copy_constructible<_Tp>::value && 559 is_trivially_copy_assignable<_Tp>::value> 560struct __optional_copy_assign_base : __optional_move_base<_Tp> 561{ 562 using __optional_move_base<_Tp>::__optional_move_base; 563}; 564 565template <class _Tp> 566struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> 567{ 568 using __optional_move_base<_Tp>::__optional_move_base; 569 570 _LIBCPP_INLINE_VISIBILITY 571 __optional_copy_assign_base() = default; 572 _LIBCPP_INLINE_VISIBILITY 573 __optional_copy_assign_base(const __optional_copy_assign_base&) = default; 574 _LIBCPP_INLINE_VISIBILITY 575 __optional_copy_assign_base(__optional_copy_assign_base&&) = default; 576 577 _LIBCPP_INLINE_VISIBILITY 578 _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt) 579 { 580 this->__assign_from(__opt); 581 return *this; 582 } 583 584 _LIBCPP_INLINE_VISIBILITY 585 __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default; 586}; 587 588template <class _Tp, bool = 589 is_trivially_destructible<_Tp>::value && 590 is_trivially_move_constructible<_Tp>::value && 591 is_trivially_move_assignable<_Tp>::value> 592struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> 593{ 594 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; 595}; 596 597template <class _Tp> 598struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> 599{ 600 using value_type = _Tp; 601 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; 602 603 _LIBCPP_INLINE_VISIBILITY 604 __optional_move_assign_base() = default; 605 _LIBCPP_INLINE_VISIBILITY 606 __optional_move_assign_base(const __optional_move_assign_base& __opt) = default; 607 _LIBCPP_INLINE_VISIBILITY 608 __optional_move_assign_base(__optional_move_assign_base&&) = default; 609 _LIBCPP_INLINE_VISIBILITY 610 __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default; 611 612 _LIBCPP_INLINE_VISIBILITY 613 _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt) 614 noexcept(is_nothrow_move_assignable_v<value_type> && 615 is_nothrow_move_constructible_v<value_type>) 616 { 617 this->__assign_from(_VSTD::move(__opt)); 618 return *this; 619 } 620}; 621 622template <class _Tp> 623using __optional_sfinae_ctor_base_t = __sfinae_ctor_base< 624 is_copy_constructible<_Tp>::value, 625 is_move_constructible<_Tp>::value 626>; 627 628template <class _Tp> 629using __optional_sfinae_assign_base_t = __sfinae_assign_base< 630 (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value), 631 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) 632>; 633 634template<class _Tp> 635class optional; 636template <class _Tp> 637struct __is_std_optional : false_type {}; 638template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {}; 639 640template <class _Tp> 641class optional 642 : private __optional_move_assign_base<_Tp> 643 , private __optional_sfinae_ctor_base_t<_Tp> 644 , private __optional_sfinae_assign_base_t<_Tp> 645{ 646 using __base = __optional_move_assign_base<_Tp>; 647public: 648 using value_type = _Tp; 649 650private: 651 // Disable the reference extension using this static assert. 652 static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>, 653 "instantiation of optional with in_place_t is ill-formed"); 654 static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>, 655 "instantiation of optional with nullopt_t is ill-formed"); 656 static_assert(!is_reference_v<value_type>, 657 "instantiation of optional with a reference type is ill-formed"); 658 static_assert(is_destructible_v<value_type>, 659 "instantiation of optional with a non-destructible type is ill-formed"); 660 static_assert(!is_array_v<value_type>, 661 "instantiation of optional with an array type is ill-formed"); 662 663 // LWG2756: conditionally explicit conversion from _Up 664 struct _CheckOptionalArgsConstructor { 665 template <class _Up> 666 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() { 667 return is_constructible_v<_Tp, _Up&&> && 668 is_convertible_v<_Up&&, _Tp>; 669 } 670 671 template <class _Up> 672 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() { 673 return is_constructible_v<_Tp, _Up&&> && 674 !is_convertible_v<_Up&&, _Tp>; 675 } 676 }; 677 template <class _Up> 678 using _CheckOptionalArgsCtor = _If< 679 _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && 680 _IsNotSame<__remove_cvref_t<_Up>, optional>::value, 681 _CheckOptionalArgsConstructor, 682 __check_tuple_constructor_fail 683 >; 684 template <class _QualUp> 685 struct _CheckOptionalLikeConstructor { 686 template <class _Up, class _Opt = optional<_Up>> 687 using __check_constructible_from_opt = _Or< 688 is_constructible<_Tp, _Opt&>, 689 is_constructible<_Tp, _Opt const&>, 690 is_constructible<_Tp, _Opt&&>, 691 is_constructible<_Tp, _Opt const&&>, 692 is_convertible<_Opt&, _Tp>, 693 is_convertible<_Opt const&, _Tp>, 694 is_convertible<_Opt&&, _Tp>, 695 is_convertible<_Opt const&&, _Tp> 696 >; 697 template <class _Up, class _Opt = optional<_Up>> 698 using __check_assignable_from_opt = _Or< 699 is_assignable<_Tp&, _Opt&>, 700 is_assignable<_Tp&, _Opt const&>, 701 is_assignable<_Tp&, _Opt&&>, 702 is_assignable<_Tp&, _Opt const&&> 703 >; 704 template <class _Up, class _QUp = _QualUp> 705 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() { 706 return is_convertible<_QUp, _Tp>::value && 707 !__check_constructible_from_opt<_Up>::value; 708 } 709 template <class _Up, class _QUp = _QualUp> 710 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() { 711 return !is_convertible<_QUp, _Tp>::value && 712 !__check_constructible_from_opt<_Up>::value; 713 } 714 template <class _Up, class _QUp = _QualUp> 715 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() { 716 // Construction and assignability of _QUp to _Tp has already been 717 // checked. 718 return !__check_constructible_from_opt<_Up>::value && 719 !__check_assignable_from_opt<_Up>::value; 720 } 721 }; 722 723 template <class _Up, class _QualUp> 724 using _CheckOptionalLikeCtor = _If< 725 _And< 726 _IsNotSame<_Up, _Tp>, 727 is_constructible<_Tp, _QualUp> 728 >::value, 729 _CheckOptionalLikeConstructor<_QualUp>, 730 __check_tuple_constructor_fail 731 >; 732 template <class _Up, class _QualUp> 733 using _CheckOptionalLikeAssign = _If< 734 _And< 735 _IsNotSame<_Up, _Tp>, 736 is_constructible<_Tp, _QualUp>, 737 is_assignable<_Tp&, _QualUp> 738 >::value, 739 _CheckOptionalLikeConstructor<_QualUp>, 740 __check_tuple_constructor_fail 741 >; 742 743public: 744 745 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} 746 _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default; 747 _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default; 748 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} 749 750 template <class _InPlaceT, class... _Args, class = enable_if_t< 751 _And< 752 _IsSame<_InPlaceT, in_place_t>, 753 is_constructible<value_type, _Args...> 754 >::value 755 > 756 > 757 _LIBCPP_INLINE_VISIBILITY 758 constexpr explicit optional(_InPlaceT, _Args&&... __args) 759 : __base(in_place, _VSTD::forward<_Args>(__args)...) {} 760 761 template <class _Up, class... _Args, class = enable_if_t< 762 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> 763 > 764 _LIBCPP_INLINE_VISIBILITY 765 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 766 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} 767 768 template <class _Up = value_type, enable_if_t< 769 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>() 770 , int> = 0> 771 _LIBCPP_INLINE_VISIBILITY 772 constexpr optional(_Up&& __v) 773 : __base(in_place, _VSTD::forward<_Up>(__v)) {} 774 775 template <class _Up, enable_if_t< 776 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>() 777 , int> = 0> 778 _LIBCPP_INLINE_VISIBILITY 779 constexpr explicit optional(_Up&& __v) 780 : __base(in_place, _VSTD::forward<_Up>(__v)) {} 781 782 // LWG2756: conditionally explicit conversion from const optional<_Up>& 783 template <class _Up, enable_if_t< 784 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>() 785 , int> = 0> 786 _LIBCPP_INLINE_VISIBILITY 787 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) 788 { 789 this->__construct_from(__v); 790 } 791 template <class _Up, enable_if_t< 792 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>() 793 , int> = 0> 794 _LIBCPP_INLINE_VISIBILITY 795 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) 796 { 797 this->__construct_from(__v); 798 } 799 800 // LWG2756: conditionally explicit conversion from optional<_Up>&& 801 template <class _Up, enable_if_t< 802 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>() 803 , int> = 0> 804 _LIBCPP_INLINE_VISIBILITY 805 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) 806 { 807 this->__construct_from(_VSTD::move(__v)); 808 } 809 template <class _Up, enable_if_t< 810 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>() 811 , int> = 0> 812 _LIBCPP_INLINE_VISIBILITY 813 _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) 814 { 815 this->__construct_from(_VSTD::move(__v)); 816 } 817 818#if _LIBCPP_STD_VER >= 23 819 template<class _Fp, class... _Args> 820 _LIBCPP_HIDE_FROM_ABI 821 constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) 822 : __base(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...) { 823 } 824#endif 825 826 _LIBCPP_INLINE_VISIBILITY 827 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept 828 { 829 reset(); 830 return *this; 831 } 832 833 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default; 834 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default; 835 836 // LWG2756 837 template <class _Up = value_type, 838 class = enable_if_t< 839 _And< 840 _IsNotSame<__remove_cvref_t<_Up>, optional>, 841 _Or< 842 _IsNotSame<__remove_cvref_t<_Up>, value_type>, 843 _Not<is_scalar<value_type>> 844 >, 845 is_constructible<value_type, _Up>, 846 is_assignable<value_type&, _Up> 847 >::value> 848 > 849 _LIBCPP_INLINE_VISIBILITY 850 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& 851 operator=(_Up&& __v) 852 { 853 if (this->has_value()) 854 this->__get() = _VSTD::forward<_Up>(__v); 855 else 856 this->__construct(_VSTD::forward<_Up>(__v)); 857 return *this; 858 } 859 860 // LWG2756 861 template <class _Up, enable_if_t< 862 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>() 863 , int> = 0> 864 _LIBCPP_INLINE_VISIBILITY 865 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& 866 operator=(const optional<_Up>& __v) 867 { 868 this->__assign_from(__v); 869 return *this; 870 } 871 872 // LWG2756 873 template <class _Up, enable_if_t< 874 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>() 875 , int> = 0> 876 _LIBCPP_INLINE_VISIBILITY 877 _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& 878 operator=(optional<_Up>&& __v) 879 { 880 this->__assign_from(_VSTD::move(__v)); 881 return *this; 882 } 883 884 template <class... _Args, 885 class = enable_if_t 886 < 887 is_constructible_v<value_type, _Args...> 888 > 889 > 890 _LIBCPP_INLINE_VISIBILITY 891 _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & 892 emplace(_Args&&... __args) 893 { 894 reset(); 895 this->__construct(_VSTD::forward<_Args>(__args)...); 896 return this->__get(); 897 } 898 899 template <class _Up, class... _Args, 900 class = enable_if_t 901 < 902 is_constructible_v<value_type, initializer_list<_Up>&, _Args...> 903 > 904 > 905 _LIBCPP_INLINE_VISIBILITY 906 _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & 907 emplace(initializer_list<_Up> __il, _Args&&... __args) 908 { 909 reset(); 910 this->__construct(__il, _VSTD::forward<_Args>(__args)...); 911 return this->__get(); 912 } 913 914 _LIBCPP_INLINE_VISIBILITY 915 _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional& __opt) 916 noexcept(is_nothrow_move_constructible_v<value_type> && 917 is_nothrow_swappable_v<value_type>) 918 { 919 if (this->has_value() == __opt.has_value()) 920 { 921 using _VSTD::swap; 922 if (this->has_value()) 923 swap(this->__get(), __opt.__get()); 924 } 925 else 926 { 927 if (this->has_value()) 928 { 929 __opt.__construct(_VSTD::move(this->__get())); 930 reset(); 931 } 932 else 933 { 934 this->__construct(_VSTD::move(__opt.__get())); 935 __opt.reset(); 936 } 937 } 938 } 939 940 _LIBCPP_INLINE_VISIBILITY 941 constexpr 942 add_pointer_t<value_type const> 943 operator->() const 944 { 945 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value"); 946 return _VSTD::addressof(this->__get()); 947 } 948 949 _LIBCPP_INLINE_VISIBILITY 950 constexpr 951 add_pointer_t<value_type> 952 operator->() 953 { 954 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value"); 955 return _VSTD::addressof(this->__get()); 956 } 957 958 _LIBCPP_INLINE_VISIBILITY 959 constexpr 960 const value_type& 961 operator*() const& noexcept 962 { 963 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); 964 return this->__get(); 965 } 966 967 _LIBCPP_INLINE_VISIBILITY 968 constexpr 969 value_type& 970 operator*() & noexcept 971 { 972 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); 973 return this->__get(); 974 } 975 976 _LIBCPP_INLINE_VISIBILITY 977 constexpr 978 value_type&& 979 operator*() && noexcept 980 { 981 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); 982 return _VSTD::move(this->__get()); 983 } 984 985 _LIBCPP_INLINE_VISIBILITY 986 constexpr 987 const value_type&& 988 operator*() const&& noexcept 989 { 990 _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); 991 return _VSTD::move(this->__get()); 992 } 993 994 _LIBCPP_INLINE_VISIBILITY 995 constexpr explicit operator bool() const noexcept { return has_value(); } 996 997 using __base::has_value; 998 using __base::__get; 999 1000 _LIBCPP_INLINE_VISIBILITY 1001 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1002 constexpr value_type const& value() const& 1003 { 1004 if (!this->has_value()) 1005 __throw_bad_optional_access(); 1006 return this->__get(); 1007 } 1008 1009 _LIBCPP_INLINE_VISIBILITY 1010 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1011 constexpr value_type& value() & 1012 { 1013 if (!this->has_value()) 1014 __throw_bad_optional_access(); 1015 return this->__get(); 1016 } 1017 1018 _LIBCPP_INLINE_VISIBILITY 1019 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1020 constexpr value_type&& value() && 1021 { 1022 if (!this->has_value()) 1023 __throw_bad_optional_access(); 1024 return _VSTD::move(this->__get()); 1025 } 1026 1027 _LIBCPP_INLINE_VISIBILITY 1028 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1029 constexpr value_type const&& value() const&& 1030 { 1031 if (!this->has_value()) 1032 __throw_bad_optional_access(); 1033 return _VSTD::move(this->__get()); 1034 } 1035 1036 template <class _Up> 1037 _LIBCPP_INLINE_VISIBILITY 1038 constexpr value_type value_or(_Up&& __v) const& 1039 { 1040 static_assert(is_copy_constructible_v<value_type>, 1041 "optional<T>::value_or: T must be copy constructible"); 1042 static_assert(is_convertible_v<_Up, value_type>, 1043 "optional<T>::value_or: U must be convertible to T"); 1044 return this->has_value() ? this->__get() : 1045 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 1046 } 1047 1048 template <class _Up> 1049 _LIBCPP_INLINE_VISIBILITY 1050 constexpr value_type value_or(_Up&& __v) && 1051 { 1052 static_assert(is_move_constructible_v<value_type>, 1053 "optional<T>::value_or: T must be move constructible"); 1054 static_assert(is_convertible_v<_Up, value_type>, 1055 "optional<T>::value_or: U must be convertible to T"); 1056 return this->has_value() ? _VSTD::move(this->__get()) : 1057 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 1058 } 1059 1060#if _LIBCPP_STD_VER >= 23 1061 template<class _Func> 1062 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1063 constexpr auto and_then(_Func&& __f) & { 1064 using _Up = invoke_result_t<_Func, value_type&>; 1065 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, 1066 "Result of f(value()) must be a specialization of std::optional"); 1067 if (*this) 1068 return _VSTD::invoke(_VSTD::forward<_Func>(__f), value()); 1069 return remove_cvref_t<_Up>(); 1070 } 1071 1072 template<class _Func> 1073 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1074 constexpr auto and_then(_Func&& __f) const& { 1075 using _Up = invoke_result_t<_Func, const value_type&>; 1076 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, 1077 "Result of f(value()) must be a specialization of std::optional"); 1078 if (*this) 1079 return _VSTD::invoke(_VSTD::forward<_Func>(__f), value()); 1080 return remove_cvref_t<_Up>(); 1081 } 1082 1083 template<class _Func> 1084 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1085 constexpr auto and_then(_Func&& __f) && { 1086 using _Up = invoke_result_t<_Func, value_type&&>; 1087 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, 1088 "Result of f(std::move(value())) must be a specialization of std::optional"); 1089 if (*this) 1090 return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value())); 1091 return remove_cvref_t<_Up>(); 1092 } 1093 1094 template<class _Func> 1095 _LIBCPP_HIDE_FROM_ABI 1096 constexpr auto and_then(_Func&& __f) const&& { 1097 using _Up = invoke_result_t<_Func, const value_type&&>; 1098 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, 1099 "Result of f(std::move(value())) must be a specialization of std::optional"); 1100 if (*this) 1101 return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value())); 1102 return remove_cvref_t<_Up>(); 1103 } 1104 1105 template<class _Func> 1106 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1107 constexpr auto transform(_Func&& __f) & { 1108 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>; 1109 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); 1110 static_assert(!is_same_v<_Up, in_place_t>, 1111 "Result of f(value()) should not be std::in_place_t"); 1112 static_assert(!is_same_v<_Up, nullopt_t>, 1113 "Result of f(value()) should not be std::nullopt_t"); 1114 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type"); 1115 if (*this) 1116 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value()); 1117 return optional<_Up>(); 1118 } 1119 1120 template<class _Func> 1121 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1122 constexpr auto transform(_Func&& __f) const& { 1123 using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>; 1124 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); 1125 static_assert(!is_same_v<_Up, in_place_t>, 1126 "Result of f(value()) should not be std::in_place_t"); 1127 static_assert(!is_same_v<_Up, nullopt_t>, 1128 "Result of f(value()) should not be std::nullopt_t"); 1129 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type"); 1130 if (*this) 1131 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value()); 1132 return optional<_Up>(); 1133 } 1134 1135 template<class _Func> 1136 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1137 constexpr auto transform(_Func&& __f) && { 1138 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>; 1139 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array"); 1140 static_assert(!is_same_v<_Up, in_place_t>, 1141 "Result of f(std::move(value())) should not be std::in_place_t"); 1142 static_assert(!is_same_v<_Up, nullopt_t>, 1143 "Result of f(std::move(value())) should not be std::nullopt_t"); 1144 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type"); 1145 if (*this) 1146 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value())); 1147 return optional<_Up>(); 1148 } 1149 1150 template<class _Func> 1151 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1152 constexpr auto transform(_Func&& __f) const&& { 1153 using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>; 1154 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array"); 1155 static_assert(!is_same_v<_Up, in_place_t>, 1156 "Result of f(std::move(value())) should not be std::in_place_t"); 1157 static_assert(!is_same_v<_Up, nullopt_t>, 1158 "Result of f(std::move(value())) should not be std::nullopt_t"); 1159 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type"); 1160 if (*this) 1161 return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value())); 1162 return optional<_Up>(); 1163 } 1164 1165 template<invocable _Func> 1166 _LIBCPP_HIDE_FROM_ABI 1167 constexpr optional or_else(_Func&& __f) const& requires is_copy_constructible_v<value_type> { 1168 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>, 1169 "Result of f() should be the same type as this optional"); 1170 if (*this) 1171 return *this; 1172 return _VSTD::forward<_Func>(__f)(); 1173 } 1174 1175 template<invocable _Func> 1176 _LIBCPP_HIDE_FROM_ABI 1177 constexpr optional or_else(_Func&& __f) && requires is_move_constructible_v<value_type> { 1178 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>, 1179 "Result of f() should be the same type as this optional"); 1180 if (*this) 1181 return _VSTD::move(*this); 1182 return _VSTD::forward<_Func>(__f)(); 1183 } 1184#endif // _LIBCPP_STD_VER >= 23 1185 1186 using __base::reset; 1187}; 1188 1189#if _LIBCPP_STD_VER >= 17 1190template<class _Tp> 1191 optional(_Tp) -> optional<_Tp>; 1192#endif 1193 1194// Comparisons between optionals 1195template <class _Tp, class _Up> 1196_LIBCPP_INLINE_VISIBILITY constexpr 1197enable_if_t< 1198 is_convertible_v<decltype(std::declval<const _Tp&>() == 1199 std::declval<const _Up&>()), bool>, 1200 bool 1201> 1202operator==(const optional<_Tp>& __x, const optional<_Up>& __y) 1203{ 1204 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 1205 return false; 1206 if (!static_cast<bool>(__x)) 1207 return true; 1208 return *__x == *__y; 1209} 1210 1211template <class _Tp, class _Up> 1212_LIBCPP_INLINE_VISIBILITY constexpr 1213enable_if_t< 1214 is_convertible_v<decltype(std::declval<const _Tp&>() != 1215 std::declval<const _Up&>()), bool>, 1216 bool 1217> 1218operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) 1219{ 1220 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 1221 return true; 1222 if (!static_cast<bool>(__x)) 1223 return false; 1224 return *__x != *__y; 1225} 1226 1227template <class _Tp, class _Up> 1228_LIBCPP_INLINE_VISIBILITY constexpr 1229enable_if_t< 1230 is_convertible_v<decltype(std::declval<const _Tp&>() < 1231 std::declval<const _Up&>()), bool>, 1232 bool 1233> 1234operator<(const optional<_Tp>& __x, const optional<_Up>& __y) 1235{ 1236 if (!static_cast<bool>(__y)) 1237 return false; 1238 if (!static_cast<bool>(__x)) 1239 return true; 1240 return *__x < *__y; 1241} 1242 1243template <class _Tp, class _Up> 1244_LIBCPP_INLINE_VISIBILITY constexpr 1245enable_if_t< 1246 is_convertible_v<decltype(std::declval<const _Tp&>() > 1247 std::declval<const _Up&>()), bool>, 1248 bool 1249> 1250operator>(const optional<_Tp>& __x, const optional<_Up>& __y) 1251{ 1252 if (!static_cast<bool>(__x)) 1253 return false; 1254 if (!static_cast<bool>(__y)) 1255 return true; 1256 return *__x > *__y; 1257} 1258 1259template <class _Tp, class _Up> 1260_LIBCPP_INLINE_VISIBILITY constexpr 1261enable_if_t< 1262 is_convertible_v<decltype(std::declval<const _Tp&>() <= 1263 std::declval<const _Up&>()), bool>, 1264 bool 1265> 1266operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) 1267{ 1268 if (!static_cast<bool>(__x)) 1269 return true; 1270 if (!static_cast<bool>(__y)) 1271 return false; 1272 return *__x <= *__y; 1273} 1274 1275template <class _Tp, class _Up> 1276_LIBCPP_INLINE_VISIBILITY constexpr 1277enable_if_t< 1278 is_convertible_v<decltype(std::declval<const _Tp&>() >= 1279 std::declval<const _Up&>()), bool>, 1280 bool 1281> 1282operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) 1283{ 1284 if (!static_cast<bool>(__y)) 1285 return true; 1286 if (!static_cast<bool>(__x)) 1287 return false; 1288 return *__x >= *__y; 1289} 1290 1291// Comparisons with nullopt 1292template <class _Tp> 1293_LIBCPP_INLINE_VISIBILITY constexpr 1294bool 1295operator==(const optional<_Tp>& __x, nullopt_t) noexcept 1296{ 1297 return !static_cast<bool>(__x); 1298} 1299 1300template <class _Tp> 1301_LIBCPP_INLINE_VISIBILITY constexpr 1302bool 1303operator==(nullopt_t, const optional<_Tp>& __x) noexcept 1304{ 1305 return !static_cast<bool>(__x); 1306} 1307 1308template <class _Tp> 1309_LIBCPP_INLINE_VISIBILITY constexpr 1310bool 1311operator!=(const optional<_Tp>& __x, nullopt_t) noexcept 1312{ 1313 return static_cast<bool>(__x); 1314} 1315 1316template <class _Tp> 1317_LIBCPP_INLINE_VISIBILITY constexpr 1318bool 1319operator!=(nullopt_t, const optional<_Tp>& __x) noexcept 1320{ 1321 return static_cast<bool>(__x); 1322} 1323 1324template <class _Tp> 1325_LIBCPP_INLINE_VISIBILITY constexpr 1326bool 1327operator<(const optional<_Tp>&, nullopt_t) noexcept 1328{ 1329 return false; 1330} 1331 1332template <class _Tp> 1333_LIBCPP_INLINE_VISIBILITY constexpr 1334bool 1335operator<(nullopt_t, const optional<_Tp>& __x) noexcept 1336{ 1337 return static_cast<bool>(__x); 1338} 1339 1340template <class _Tp> 1341_LIBCPP_INLINE_VISIBILITY constexpr 1342bool 1343operator<=(const optional<_Tp>& __x, nullopt_t) noexcept 1344{ 1345 return !static_cast<bool>(__x); 1346} 1347 1348template <class _Tp> 1349_LIBCPP_INLINE_VISIBILITY constexpr 1350bool 1351operator<=(nullopt_t, const optional<_Tp>&) noexcept 1352{ 1353 return true; 1354} 1355 1356template <class _Tp> 1357_LIBCPP_INLINE_VISIBILITY constexpr 1358bool 1359operator>(const optional<_Tp>& __x, nullopt_t) noexcept 1360{ 1361 return static_cast<bool>(__x); 1362} 1363 1364template <class _Tp> 1365_LIBCPP_INLINE_VISIBILITY constexpr 1366bool 1367operator>(nullopt_t, const optional<_Tp>&) noexcept 1368{ 1369 return false; 1370} 1371 1372template <class _Tp> 1373_LIBCPP_INLINE_VISIBILITY constexpr 1374bool 1375operator>=(const optional<_Tp>&, nullopt_t) noexcept 1376{ 1377 return true; 1378} 1379 1380template <class _Tp> 1381_LIBCPP_INLINE_VISIBILITY constexpr 1382bool 1383operator>=(nullopt_t, const optional<_Tp>& __x) noexcept 1384{ 1385 return !static_cast<bool>(__x); 1386} 1387 1388// Comparisons with T 1389template <class _Tp, class _Up> 1390_LIBCPP_INLINE_VISIBILITY constexpr 1391enable_if_t< 1392 is_convertible_v<decltype(std::declval<const _Tp&>() == 1393 std::declval<const _Up&>()), bool>, 1394 bool 1395> 1396operator==(const optional<_Tp>& __x, const _Up& __v) 1397{ 1398 return static_cast<bool>(__x) ? *__x == __v : false; 1399} 1400 1401template <class _Tp, class _Up> 1402_LIBCPP_INLINE_VISIBILITY constexpr 1403enable_if_t< 1404 is_convertible_v<decltype(std::declval<const _Tp&>() == 1405 std::declval<const _Up&>()), bool>, 1406 bool 1407> 1408operator==(const _Tp& __v, const optional<_Up>& __x) 1409{ 1410 return static_cast<bool>(__x) ? __v == *__x : false; 1411} 1412 1413template <class _Tp, class _Up> 1414_LIBCPP_INLINE_VISIBILITY constexpr 1415enable_if_t< 1416 is_convertible_v<decltype(std::declval<const _Tp&>() != 1417 std::declval<const _Up&>()), bool>, 1418 bool 1419> 1420operator!=(const optional<_Tp>& __x, const _Up& __v) 1421{ 1422 return static_cast<bool>(__x) ? *__x != __v : true; 1423} 1424 1425template <class _Tp, class _Up> 1426_LIBCPP_INLINE_VISIBILITY constexpr 1427enable_if_t< 1428 is_convertible_v<decltype(std::declval<const _Tp&>() != 1429 std::declval<const _Up&>()), bool>, 1430 bool 1431> 1432operator!=(const _Tp& __v, const optional<_Up>& __x) 1433{ 1434 return static_cast<bool>(__x) ? __v != *__x : true; 1435} 1436 1437template <class _Tp, class _Up> 1438_LIBCPP_INLINE_VISIBILITY constexpr 1439enable_if_t< 1440 is_convertible_v<decltype(std::declval<const _Tp&>() < 1441 std::declval<const _Up&>()), bool>, 1442 bool 1443> 1444operator<(const optional<_Tp>& __x, const _Up& __v) 1445{ 1446 return static_cast<bool>(__x) ? *__x < __v : true; 1447} 1448 1449template <class _Tp, class _Up> 1450_LIBCPP_INLINE_VISIBILITY constexpr 1451enable_if_t< 1452 is_convertible_v<decltype(std::declval<const _Tp&>() < 1453 std::declval<const _Up&>()), bool>, 1454 bool 1455> 1456operator<(const _Tp& __v, const optional<_Up>& __x) 1457{ 1458 return static_cast<bool>(__x) ? __v < *__x : false; 1459} 1460 1461template <class _Tp, class _Up> 1462_LIBCPP_INLINE_VISIBILITY constexpr 1463enable_if_t< 1464 is_convertible_v<decltype(std::declval<const _Tp&>() <= 1465 std::declval<const _Up&>()), bool>, 1466 bool 1467> 1468operator<=(const optional<_Tp>& __x, const _Up& __v) 1469{ 1470 return static_cast<bool>(__x) ? *__x <= __v : true; 1471} 1472 1473template <class _Tp, class _Up> 1474_LIBCPP_INLINE_VISIBILITY constexpr 1475enable_if_t< 1476 is_convertible_v<decltype(std::declval<const _Tp&>() <= 1477 std::declval<const _Up&>()), bool>, 1478 bool 1479> 1480operator<=(const _Tp& __v, const optional<_Up>& __x) 1481{ 1482 return static_cast<bool>(__x) ? __v <= *__x : false; 1483} 1484 1485template <class _Tp, class _Up> 1486_LIBCPP_INLINE_VISIBILITY constexpr 1487enable_if_t< 1488 is_convertible_v<decltype(std::declval<const _Tp&>() > 1489 std::declval<const _Up&>()), bool>, 1490 bool 1491> 1492operator>(const optional<_Tp>& __x, const _Up& __v) 1493{ 1494 return static_cast<bool>(__x) ? *__x > __v : false; 1495} 1496 1497template <class _Tp, class _Up> 1498_LIBCPP_INLINE_VISIBILITY constexpr 1499enable_if_t< 1500 is_convertible_v<decltype(std::declval<const _Tp&>() > 1501 std::declval<const _Up&>()), bool>, 1502 bool 1503> 1504operator>(const _Tp& __v, const optional<_Up>& __x) 1505{ 1506 return static_cast<bool>(__x) ? __v > *__x : true; 1507} 1508 1509template <class _Tp, class _Up> 1510_LIBCPP_INLINE_VISIBILITY constexpr 1511enable_if_t< 1512 is_convertible_v<decltype(std::declval<const _Tp&>() >= 1513 std::declval<const _Up&>()), bool>, 1514 bool 1515> 1516operator>=(const optional<_Tp>& __x, const _Up& __v) 1517{ 1518 return static_cast<bool>(__x) ? *__x >= __v : false; 1519} 1520 1521template <class _Tp, class _Up> 1522_LIBCPP_INLINE_VISIBILITY constexpr 1523enable_if_t< 1524 is_convertible_v<decltype(std::declval<const _Tp&>() >= 1525 std::declval<const _Up&>()), bool>, 1526 bool 1527> 1528operator>=(const _Tp& __v, const optional<_Up>& __x) 1529{ 1530 return static_cast<bool>(__x) ? __v >= *__x : true; 1531} 1532 1533 1534template <class _Tp> 1535inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 1536enable_if_t< 1537 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, 1538 void 1539> 1540swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 1541{ 1542 __x.swap(__y); 1543} 1544 1545template <class _Tp> 1546_LIBCPP_INLINE_VISIBILITY constexpr 1547optional<decay_t<_Tp>> make_optional(_Tp&& __v) 1548{ 1549 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v)); 1550} 1551 1552template <class _Tp, class... _Args> 1553_LIBCPP_INLINE_VISIBILITY constexpr 1554optional<_Tp> make_optional(_Args&&... __args) 1555{ 1556 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); 1557} 1558 1559template <class _Tp, class _Up, class... _Args> 1560_LIBCPP_INLINE_VISIBILITY constexpr 1561optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) 1562{ 1563 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...); 1564} 1565 1566template <class _Tp> 1567struct _LIBCPP_TEMPLATE_VIS hash< 1568 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> 1569> 1570{ 1571#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 1572 _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type; 1573 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 1574#endif 1575 1576 _LIBCPP_INLINE_VISIBILITY 1577 size_t operator()(const optional<_Tp>& __opt) const 1578 { 1579 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0; 1580 } 1581}; 1582 1583_LIBCPP_END_NAMESPACE_STD 1584 1585#endif // _LIBCPP_STD_VER >= 17 1586 1587#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 1588# include <atomic> 1589# include <climits> 1590# include <concepts> 1591# include <ctime> 1592# include <iterator> 1593# include <memory> 1594# include <ratio> 1595# include <tuple> 1596# include <type_traits> 1597# include <typeinfo> 1598# include <utility> 1599# include <variant> 1600#endif 1601 1602#endif // _LIBCPP_OPTIONAL 1603