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