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