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