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