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