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