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