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