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<__uncvref_t<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 static_assert(!is_array_v<value_type>, 604 "instantiation of optional with an array type is ill-formed"); 605 606 // LWG2756: conditionally explicit conversion from _Up 607 struct _CheckOptionalArgsConstructor { 608 template <class _Up> 609 static constexpr bool __enable_implicit() { 610 return is_constructible_v<_Tp, _Up&&> && 611 is_convertible_v<_Up&&, _Tp>; 612 } 613 614 template <class _Up> 615 static constexpr bool __enable_explicit() { 616 return is_constructible_v<_Tp, _Up&&> && 617 !is_convertible_v<_Up&&, _Tp>; 618 } 619 }; 620 template <class _Up> 621 using _CheckOptionalArgsCtor = conditional_t< 622 !is_same_v<__uncvref_t<_Up>, in_place_t> && 623 !is_same_v<__uncvref_t<_Up>, optional>, 624 _CheckOptionalArgsConstructor, 625 __check_tuple_constructor_fail 626 >; 627 template <class _QualUp> 628 struct _CheckOptionalLikeConstructor { 629 template <class _Up, class _Opt = optional<_Up>> 630 using __check_constructible_from_opt = __lazy_or< 631 is_constructible<_Tp, _Opt&>, 632 is_constructible<_Tp, _Opt const&>, 633 is_constructible<_Tp, _Opt&&>, 634 is_constructible<_Tp, _Opt const&&>, 635 is_convertible<_Opt&, _Tp>, 636 is_convertible<_Opt const&, _Tp>, 637 is_convertible<_Opt&&, _Tp>, 638 is_convertible<_Opt const&&, _Tp> 639 >; 640 template <class _Up, class _Opt = optional<_Up>> 641 using __check_assignable_from_opt = __lazy_or< 642 is_assignable<_Tp&, _Opt&>, 643 is_assignable<_Tp&, _Opt const&>, 644 is_assignable<_Tp&, _Opt&&>, 645 is_assignable<_Tp&, _Opt const&&> 646 >; 647 template <class _Up, class _QUp = _QualUp> 648 static constexpr bool __enable_implicit() { 649 return is_convertible<_QUp, _Tp>::value && 650 !__check_constructible_from_opt<_Up>::value; 651 } 652 template <class _Up, class _QUp = _QualUp> 653 static constexpr bool __enable_explicit() { 654 return !is_convertible<_QUp, _Tp>::value && 655 !__check_constructible_from_opt<_Up>::value; 656 } 657 template <class _Up, class _QUp = _QualUp> 658 static constexpr bool __enable_assign() { 659 // Construction and assignability of _Qup to _Tp has already been 660 // checked. 661 return !__check_constructible_from_opt<_Up>::value && 662 !__check_assignable_from_opt<_Up>::value; 663 } 664 }; 665 666 template <class _Up, class _QualUp> 667 using _CheckOptionalLikeCtor = conditional_t< 668 __lazy_and< 669 __lazy_not<is_same<_Up, _Tp>>, 670 is_constructible<_Tp, _QualUp> 671 >::value, 672 _CheckOptionalLikeConstructor<_QualUp>, 673 __check_tuple_constructor_fail 674 >; 675 template <class _Up, class _QualUp> 676 using _CheckOptionalLikeAssign = conditional_t< 677 __lazy_and< 678 __lazy_not<is_same<_Up, _Tp>>, 679 is_constructible<_Tp, _QualUp>, 680 is_assignable<_Tp&, _QualUp> 681 >::value, 682 _CheckOptionalLikeConstructor<_QualUp>, 683 __check_tuple_constructor_fail 684 >; 685public: 686 687 _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} 688 _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default; 689 _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default; 690 _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} 691 692 template <class _InPlaceT, class... _Args, class = enable_if_t< 693 __lazy_and< 694 is_same<_InPlaceT, in_place_t>, 695 is_constructible<value_type, _Args...> 696 >::value 697 > 698 > 699 _LIBCPP_INLINE_VISIBILITY 700 constexpr explicit optional(_InPlaceT, _Args&&... __args) 701 : __base(in_place, _VSTD::forward<_Args>(__args)...) {} 702 703 template <class _Up, class... _Args, class = enable_if_t< 704 is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> 705 > 706 _LIBCPP_INLINE_VISIBILITY 707 constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 708 : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} 709 710 template <class _Up = value_type, enable_if_t< 711 _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>() 712 , int> = 0> 713 _LIBCPP_INLINE_VISIBILITY 714 constexpr optional(_Up&& __v) 715 : __base(in_place, _VSTD::forward<_Up>(__v)) {} 716 717 template <class _Up, enable_if_t< 718 _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>() 719 , int> = 0> 720 _LIBCPP_INLINE_VISIBILITY 721 constexpr explicit optional(_Up&& __v) 722 : __base(in_place, _VSTD::forward<_Up>(__v)) {} 723 724 // LWG2756: conditionally explicit conversion from const optional<_Up>& 725 template <class _Up, enable_if_t< 726 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>() 727 , int> = 0> 728 _LIBCPP_INLINE_VISIBILITY 729 optional(const optional<_Up>& __v) 730 { 731 this->__construct_from(__v); 732 } 733 template <class _Up, enable_if_t< 734 _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>() 735 , int> = 0> 736 _LIBCPP_INLINE_VISIBILITY 737 explicit optional(const optional<_Up>& __v) 738 { 739 this->__construct_from(__v); 740 } 741 742 // LWG2756: conditionally explicit conversion from optional<_Up>&& 743 template <class _Up, enable_if_t< 744 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>() 745 , int> = 0> 746 _LIBCPP_INLINE_VISIBILITY 747 optional(optional<_Up>&& __v) 748 { 749 this->__construct_from(_VSTD::move(__v)); 750 } 751 template <class _Up, enable_if_t< 752 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>() 753 , int> = 0> 754 _LIBCPP_INLINE_VISIBILITY 755 explicit optional(optional<_Up>&& __v) 756 { 757 this->__construct_from(_VSTD::move(__v)); 758 } 759 760 _LIBCPP_INLINE_VISIBILITY 761 optional& operator=(nullopt_t) noexcept 762 { 763 reset(); 764 return *this; 765 } 766 767 _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default; 768 _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default; 769 770 // LWG2756 771 template <class _Up = value_type, 772 class = enable_if_t 773 <__lazy_and< 774 integral_constant<bool, 775 !is_same_v<__uncvref_t<_Up>, optional> && 776 !(is_same_v<_Up, value_type> && is_scalar_v<value_type>) 777 >, 778 is_constructible<value_type, _Up>, 779 is_assignable<value_type&, _Up> 780 >::value> 781 > 782 _LIBCPP_INLINE_VISIBILITY 783 optional& 784 operator=(_Up&& __v) 785 { 786 if (this->has_value()) 787 this->__get() = _VSTD::forward<_Up>(__v); 788 else 789 this->__construct(_VSTD::forward<_Up>(__v)); 790 return *this; 791 } 792 793 // LWG2756 794 template <class _Up, enable_if_t< 795 _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>() 796 , int> = 0> 797 _LIBCPP_INLINE_VISIBILITY 798 optional& 799 operator=(const optional<_Up>& __v) 800 { 801 this->__assign_from(__v); 802 return *this; 803 } 804 805 // LWG2756 806 template <class _Up, enable_if_t< 807 _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>() 808 , int> = 0> 809 _LIBCPP_INLINE_VISIBILITY 810 optional& 811 operator=(optional<_Up>&& __v) 812 { 813 this->__assign_from(_VSTD::move(__v)); 814 return *this; 815 } 816 817 template <class... _Args, 818 class = enable_if_t 819 < 820 is_constructible_v<value_type, _Args...> 821 > 822 > 823 _LIBCPP_INLINE_VISIBILITY 824 _Tp & 825 emplace(_Args&&... __args) 826 { 827 reset(); 828 this->__construct(_VSTD::forward<_Args>(__args)...); 829 return this->__get(); 830 } 831 832 template <class _Up, class... _Args, 833 class = enable_if_t 834 < 835 is_constructible_v<value_type, initializer_list<_Up>&, _Args...> 836 > 837 > 838 _LIBCPP_INLINE_VISIBILITY 839 _Tp & 840 emplace(initializer_list<_Up> __il, _Args&&... __args) 841 { 842 reset(); 843 this->__construct(__il, _VSTD::forward<_Args>(__args)...); 844 return this->__get(); 845 } 846 847 _LIBCPP_INLINE_VISIBILITY 848 void swap(optional& __opt) 849 noexcept(is_nothrow_move_constructible_v<value_type> && 850 is_nothrow_swappable_v<value_type>) 851 { 852 if (this->has_value() == __opt.has_value()) 853 { 854 using _VSTD::swap; 855 if (this->has_value()) 856 swap(this->__get(), __opt.__get()); 857 } 858 else 859 { 860 if (this->has_value()) 861 { 862 __opt.__construct(_VSTD::move(this->__get())); 863 reset(); 864 } 865 else 866 { 867 this->__construct(_VSTD::move(__opt.__get())); 868 __opt.reset(); 869 } 870 } 871 } 872 873 _LIBCPP_INLINE_VISIBILITY 874 constexpr 875 add_pointer_t<value_type const> 876 operator->() const 877 { 878 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); 879#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 880 return _VSTD::addressof(this->__get()); 881#else 882 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); 883#endif 884 } 885 886 _LIBCPP_INLINE_VISIBILITY 887 constexpr 888 add_pointer_t<value_type> 889 operator->() 890 { 891 _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); 892#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 893 return _VSTD::addressof(this->__get()); 894#else 895 return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); 896#endif 897 } 898 899 _LIBCPP_INLINE_VISIBILITY 900 constexpr 901 const value_type& 902 operator*() const& 903 { 904 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 905 return this->__get(); 906 } 907 908 _LIBCPP_INLINE_VISIBILITY 909 constexpr 910 value_type& 911 operator*() & 912 { 913 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 914 return this->__get(); 915 } 916 917 _LIBCPP_INLINE_VISIBILITY 918 constexpr 919 value_type&& 920 operator*() && 921 { 922 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 923 return _VSTD::move(this->__get()); 924 } 925 926 _LIBCPP_INLINE_VISIBILITY 927 constexpr 928 const value_type&& 929 operator*() const&& 930 { 931 _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 932 return _VSTD::move(this->__get()); 933 } 934 935 _LIBCPP_INLINE_VISIBILITY 936 constexpr explicit operator bool() const noexcept { return has_value(); } 937 938 using __base::has_value; 939 using __base::__get; 940 941 _LIBCPP_INLINE_VISIBILITY 942 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 943 constexpr value_type const& value() const& 944 { 945 if (!this->has_value()) 946 __throw_bad_optional_access(); 947 return this->__get(); 948 } 949 950 _LIBCPP_INLINE_VISIBILITY 951 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 952 constexpr value_type& value() & 953 { 954 if (!this->has_value()) 955 __throw_bad_optional_access(); 956 return this->__get(); 957 } 958 959 _LIBCPP_INLINE_VISIBILITY 960 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 961 constexpr value_type&& value() && 962 { 963 if (!this->has_value()) 964 __throw_bad_optional_access(); 965 return _VSTD::move(this->__get()); 966 } 967 968 _LIBCPP_INLINE_VISIBILITY 969 _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 970 constexpr value_type const&& value() const&& 971 { 972 if (!this->has_value()) 973 __throw_bad_optional_access(); 974 return _VSTD::move(this->__get()); 975 } 976 977 template <class _Up> 978 _LIBCPP_INLINE_VISIBILITY 979 constexpr value_type value_or(_Up&& __v) const& 980 { 981 static_assert(is_copy_constructible_v<value_type>, 982 "optional<T>::value_or: T must be copy constructible"); 983 static_assert(is_convertible_v<_Up, value_type>, 984 "optional<T>::value_or: U must be convertible to T"); 985 return this->has_value() ? this->__get() : 986 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 987 } 988 989 template <class _Up> 990 _LIBCPP_INLINE_VISIBILITY 991 constexpr value_type value_or(_Up&& __v) && 992 { 993 static_assert(is_move_constructible_v<value_type>, 994 "optional<T>::value_or: T must be move constructible"); 995 static_assert(is_convertible_v<_Up, value_type>, 996 "optional<T>::value_or: U must be convertible to T"); 997 return this->has_value() ? _VSTD::move(this->__get()) : 998 static_cast<value_type>(_VSTD::forward<_Up>(__v)); 999 } 1000 1001 using __base::reset; 1002 1003private: 1004 template <class _Up> 1005 _LIBCPP_INLINE_VISIBILITY 1006 static _Up* 1007 __operator_arrow(true_type, _Up& __x) 1008 { 1009 return _VSTD::addressof(__x); 1010 } 1011 1012 template <class _Up> 1013 _LIBCPP_INLINE_VISIBILITY 1014 static constexpr _Up* 1015 __operator_arrow(false_type, _Up& __x) 1016 { 1017 return &__x; 1018 } 1019}; 1020 1021#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 1022template<class T> 1023 optional(T) -> optional<T>; 1024#endif 1025 1026// Comparisons between optionals 1027template <class _Tp, class _Up> 1028_LIBCPP_INLINE_VISIBILITY constexpr 1029enable_if_t< 1030 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1031 _VSTD::declval<const _Up&>()), bool>, 1032 bool 1033> 1034operator==(const optional<_Tp>& __x, const optional<_Up>& __y) 1035{ 1036 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 1037 return false; 1038 if (!static_cast<bool>(__x)) 1039 return true; 1040 return *__x == *__y; 1041} 1042 1043template <class _Tp, class _Up> 1044_LIBCPP_INLINE_VISIBILITY constexpr 1045enable_if_t< 1046 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1047 _VSTD::declval<const _Up&>()), bool>, 1048 bool 1049> 1050operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) 1051{ 1052 if (static_cast<bool>(__x) != static_cast<bool>(__y)) 1053 return true; 1054 if (!static_cast<bool>(__x)) 1055 return false; 1056 return *__x != *__y; 1057} 1058 1059template <class _Tp, class _Up> 1060_LIBCPP_INLINE_VISIBILITY constexpr 1061enable_if_t< 1062 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1063 _VSTD::declval<const _Up&>()), bool>, 1064 bool 1065> 1066operator<(const optional<_Tp>& __x, const optional<_Up>& __y) 1067{ 1068 if (!static_cast<bool>(__y)) 1069 return false; 1070 if (!static_cast<bool>(__x)) 1071 return true; 1072 return *__x < *__y; 1073} 1074 1075template <class _Tp, class _Up> 1076_LIBCPP_INLINE_VISIBILITY constexpr 1077enable_if_t< 1078 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1079 _VSTD::declval<const _Up&>()), bool>, 1080 bool 1081> 1082operator>(const optional<_Tp>& __x, const optional<_Up>& __y) 1083{ 1084 if (!static_cast<bool>(__x)) 1085 return false; 1086 if (!static_cast<bool>(__y)) 1087 return true; 1088 return *__x > *__y; 1089} 1090 1091template <class _Tp, class _Up> 1092_LIBCPP_INLINE_VISIBILITY constexpr 1093enable_if_t< 1094 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1095 _VSTD::declval<const _Up&>()), bool>, 1096 bool 1097> 1098operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) 1099{ 1100 if (!static_cast<bool>(__x)) 1101 return true; 1102 if (!static_cast<bool>(__y)) 1103 return false; 1104 return *__x <= *__y; 1105} 1106 1107template <class _Tp, class _Up> 1108_LIBCPP_INLINE_VISIBILITY constexpr 1109enable_if_t< 1110 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1111 _VSTD::declval<const _Up&>()), bool>, 1112 bool 1113> 1114operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) 1115{ 1116 if (!static_cast<bool>(__y)) 1117 return true; 1118 if (!static_cast<bool>(__x)) 1119 return false; 1120 return *__x >= *__y; 1121} 1122 1123// Comparisons with nullopt 1124template <class _Tp> 1125_LIBCPP_INLINE_VISIBILITY constexpr 1126bool 1127operator==(const optional<_Tp>& __x, nullopt_t) noexcept 1128{ 1129 return !static_cast<bool>(__x); 1130} 1131 1132template <class _Tp> 1133_LIBCPP_INLINE_VISIBILITY constexpr 1134bool 1135operator==(nullopt_t, const optional<_Tp>& __x) noexcept 1136{ 1137 return !static_cast<bool>(__x); 1138} 1139 1140template <class _Tp> 1141_LIBCPP_INLINE_VISIBILITY constexpr 1142bool 1143operator!=(const optional<_Tp>& __x, nullopt_t) noexcept 1144{ 1145 return static_cast<bool>(__x); 1146} 1147 1148template <class _Tp> 1149_LIBCPP_INLINE_VISIBILITY constexpr 1150bool 1151operator!=(nullopt_t, const optional<_Tp>& __x) noexcept 1152{ 1153 return static_cast<bool>(__x); 1154} 1155 1156template <class _Tp> 1157_LIBCPP_INLINE_VISIBILITY constexpr 1158bool 1159operator<(const optional<_Tp>&, nullopt_t) noexcept 1160{ 1161 return false; 1162} 1163 1164template <class _Tp> 1165_LIBCPP_INLINE_VISIBILITY constexpr 1166bool 1167operator<(nullopt_t, const optional<_Tp>& __x) noexcept 1168{ 1169 return static_cast<bool>(__x); 1170} 1171 1172template <class _Tp> 1173_LIBCPP_INLINE_VISIBILITY constexpr 1174bool 1175operator<=(const optional<_Tp>& __x, nullopt_t) noexcept 1176{ 1177 return !static_cast<bool>(__x); 1178} 1179 1180template <class _Tp> 1181_LIBCPP_INLINE_VISIBILITY constexpr 1182bool 1183operator<=(nullopt_t, const optional<_Tp>&) noexcept 1184{ 1185 return true; 1186} 1187 1188template <class _Tp> 1189_LIBCPP_INLINE_VISIBILITY constexpr 1190bool 1191operator>(const optional<_Tp>& __x, nullopt_t) noexcept 1192{ 1193 return static_cast<bool>(__x); 1194} 1195 1196template <class _Tp> 1197_LIBCPP_INLINE_VISIBILITY constexpr 1198bool 1199operator>(nullopt_t, const optional<_Tp>&) noexcept 1200{ 1201 return false; 1202} 1203 1204template <class _Tp> 1205_LIBCPP_INLINE_VISIBILITY constexpr 1206bool 1207operator>=(const optional<_Tp>&, nullopt_t) noexcept 1208{ 1209 return true; 1210} 1211 1212template <class _Tp> 1213_LIBCPP_INLINE_VISIBILITY constexpr 1214bool 1215operator>=(nullopt_t, const optional<_Tp>& __x) noexcept 1216{ 1217 return !static_cast<bool>(__x); 1218} 1219 1220// Comparisons with T 1221template <class _Tp, class _Up> 1222_LIBCPP_INLINE_VISIBILITY constexpr 1223enable_if_t< 1224 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1225 _VSTD::declval<const _Up&>()), bool>, 1226 bool 1227> 1228operator==(const optional<_Tp>& __x, const _Up& __v) 1229{ 1230 return static_cast<bool>(__x) ? *__x == __v : false; 1231} 1232 1233template <class _Tp, class _Up> 1234_LIBCPP_INLINE_VISIBILITY constexpr 1235enable_if_t< 1236 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1237 _VSTD::declval<const _Up&>()), bool>, 1238 bool 1239> 1240operator==(const _Tp& __v, const optional<_Up>& __x) 1241{ 1242 return static_cast<bool>(__x) ? __v == *__x : false; 1243} 1244 1245template <class _Tp, class _Up> 1246_LIBCPP_INLINE_VISIBILITY constexpr 1247enable_if_t< 1248 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1249 _VSTD::declval<const _Up&>()), bool>, 1250 bool 1251> 1252operator!=(const optional<_Tp>& __x, const _Up& __v) 1253{ 1254 return static_cast<bool>(__x) ? *__x != __v : true; 1255} 1256 1257template <class _Tp, class _Up> 1258_LIBCPP_INLINE_VISIBILITY constexpr 1259enable_if_t< 1260 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1261 _VSTD::declval<const _Up&>()), bool>, 1262 bool 1263> 1264operator!=(const _Tp& __v, const optional<_Up>& __x) 1265{ 1266 return static_cast<bool>(__x) ? __v != *__x : true; 1267} 1268 1269template <class _Tp, class _Up> 1270_LIBCPP_INLINE_VISIBILITY constexpr 1271enable_if_t< 1272 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1273 _VSTD::declval<const _Up&>()), bool>, 1274 bool 1275> 1276operator<(const optional<_Tp>& __x, const _Up& __v) 1277{ 1278 return static_cast<bool>(__x) ? *__x < __v : true; 1279} 1280 1281template <class _Tp, class _Up> 1282_LIBCPP_INLINE_VISIBILITY constexpr 1283enable_if_t< 1284 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1285 _VSTD::declval<const _Up&>()), bool>, 1286 bool 1287> 1288operator<(const _Tp& __v, const optional<_Up>& __x) 1289{ 1290 return static_cast<bool>(__x) ? __v < *__x : false; 1291} 1292 1293template <class _Tp, class _Up> 1294_LIBCPP_INLINE_VISIBILITY constexpr 1295enable_if_t< 1296 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1297 _VSTD::declval<const _Up&>()), bool>, 1298 bool 1299> 1300operator<=(const optional<_Tp>& __x, const _Up& __v) 1301{ 1302 return static_cast<bool>(__x) ? *__x <= __v : true; 1303} 1304 1305template <class _Tp, class _Up> 1306_LIBCPP_INLINE_VISIBILITY constexpr 1307enable_if_t< 1308 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1309 _VSTD::declval<const _Up&>()), bool>, 1310 bool 1311> 1312operator<=(const _Tp& __v, const optional<_Up>& __x) 1313{ 1314 return static_cast<bool>(__x) ? __v <= *__x : false; 1315} 1316 1317template <class _Tp, class _Up> 1318_LIBCPP_INLINE_VISIBILITY constexpr 1319enable_if_t< 1320 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1321 _VSTD::declval<const _Up&>()), bool>, 1322 bool 1323> 1324operator>(const optional<_Tp>& __x, const _Up& __v) 1325{ 1326 return static_cast<bool>(__x) ? *__x > __v : false; 1327} 1328 1329template <class _Tp, class _Up> 1330_LIBCPP_INLINE_VISIBILITY constexpr 1331enable_if_t< 1332 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1333 _VSTD::declval<const _Up&>()), bool>, 1334 bool 1335> 1336operator>(const _Tp& __v, const optional<_Up>& __x) 1337{ 1338 return static_cast<bool>(__x) ? __v > *__x : true; 1339} 1340 1341template <class _Tp, class _Up> 1342_LIBCPP_INLINE_VISIBILITY constexpr 1343enable_if_t< 1344 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1345 _VSTD::declval<const _Up&>()), bool>, 1346 bool 1347> 1348operator>=(const optional<_Tp>& __x, const _Up& __v) 1349{ 1350 return static_cast<bool>(__x) ? *__x >= __v : false; 1351} 1352 1353template <class _Tp, class _Up> 1354_LIBCPP_INLINE_VISIBILITY constexpr 1355enable_if_t< 1356 is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1357 _VSTD::declval<const _Up&>()), bool>, 1358 bool 1359> 1360operator>=(const _Tp& __v, const optional<_Up>& __x) 1361{ 1362 return static_cast<bool>(__x) ? __v >= *__x : true; 1363} 1364 1365 1366template <class _Tp> 1367inline _LIBCPP_INLINE_VISIBILITY 1368enable_if_t< 1369 is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, 1370 void 1371> 1372swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 1373{ 1374 __x.swap(__y); 1375} 1376 1377template <class _Tp> 1378_LIBCPP_INLINE_VISIBILITY constexpr 1379optional<decay_t<_Tp>> make_optional(_Tp&& __v) 1380{ 1381 return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v)); 1382} 1383 1384template <class _Tp, class... _Args> 1385_LIBCPP_INLINE_VISIBILITY constexpr 1386optional<_Tp> make_optional(_Args&&... __args) 1387{ 1388 return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); 1389} 1390 1391template <class _Tp, class _Up, class... _Args> 1392_LIBCPP_INLINE_VISIBILITY constexpr 1393optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) 1394{ 1395 return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...); 1396} 1397 1398template <class _Tp> 1399struct _LIBCPP_TEMPLATE_VIS hash< 1400 __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> 1401> 1402{ 1403 typedef optional<_Tp> argument_type; 1404 typedef size_t result_type; 1405 1406 _LIBCPP_INLINE_VISIBILITY 1407 result_type operator()(const argument_type& __opt) const 1408 { 1409 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0; 1410 } 1411}; 1412 1413_LIBCPP_END_NAMESPACE_STD 1414 1415#endif // _LIBCPP_STD_VER > 14 1416 1417_LIBCPP_POP_MACROS 1418 1419#endif // _LIBCPP_OPTIONAL 1420