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