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