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