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