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