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