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