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