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