1261272Sdim// -*- C++ -*- 2261272Sdim//===-------------------------- optional ----------------------------------===// 3261272Sdim// 4261272Sdim// The LLVM Compiler Infrastructure 5261272Sdim// 6261272Sdim// This file is dual licensed under the MIT and the University of Illinois Open 7261272Sdim// Source Licenses. See LICENSE.TXT for details. 8261272Sdim// 9261272Sdim//===----------------------------------------------------------------------===// 10261272Sdim 11261272Sdim#ifndef _LIBCPP_OPTIONAL 12261272Sdim#define _LIBCPP_OPTIONAL 13261272Sdim 14261272Sdim/* 15261272Sdim optional synopsis 16261272Sdim 17261272Sdim// C++1y 18261272Sdim 19276792Sdimnamespace std { namespace experimental { inline namespace fundamentals_v1 { 20261272Sdim 21276792Sdim // 5.3, optional for object types 22276792Sdim template <class T> class optional; 23261272Sdim 24276792Sdim // 5.4, In-place construction 25276792Sdim struct in_place_t{}; 26276792Sdim constexpr in_place_t in_place{}; 27261272Sdim 28276792Sdim // 5.5, No-value state indicator 29276792Sdim struct nullopt_t{see below}; 30276792Sdim constexpr nullopt_t nullopt(unspecified); 31261272Sdim 32276792Sdim // 5.6, Class bad_optional_access 33276792Sdim class bad_optional_access; 34261272Sdim 35276792Sdim // 5.7, Relational operators 36276792Sdim template <class T> 37276792Sdim constexpr bool operator==(const optional<T>&, const optional<T>&); 38276792Sdim template <class T> 39276792Sdim constexpr bool operator!=(const optional<T>&, const optional<T>&); 40276792Sdim template <class T> 41276792Sdim constexpr bool operator<(const optional<T>&, const optional<T>&); 42276792Sdim template <class T> 43276792Sdim constexpr bool operator>(const optional<T>&, const optional<T>&); 44276792Sdim template <class T> 45276792Sdim constexpr bool operator<=(const optional<T>&, const optional<T>&); 46276792Sdim template <class T> 47276792Sdim constexpr bool operator>=(const optional<T>&, const optional<T>&); 48261272Sdim 49276792Sdim // 5.8, Comparison with nullopt 50276792Sdim template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; 51276792Sdim template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; 52276792Sdim template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; 53276792Sdim template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; 54276792Sdim template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; 55276792Sdim template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; 56276792Sdim template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; 57276792Sdim template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; 58276792Sdim template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; 59276792Sdim template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; 60276792Sdim template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; 61276792Sdim template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; 62261272Sdim 63276792Sdim // 5.9, Comparison with T 64276792Sdim template <class T> constexpr bool operator==(const optional<T>&, const T&); 65276792Sdim template <class T> constexpr bool operator==(const T&, const optional<T>&); 66276792Sdim template <class T> constexpr bool operator!=(const optional<T>&, const T&); 67276792Sdim template <class T> constexpr bool operator!=(const T&, const optional<T>&); 68276792Sdim template <class T> constexpr bool operator<(const optional<T>&, const T&); 69276792Sdim template <class T> constexpr bool operator<(const T&, const optional<T>&); 70276792Sdim template <class T> constexpr bool operator<=(const optional<T>&, const T&); 71276792Sdim template <class T> constexpr bool operator<=(const T&, const optional<T>&); 72276792Sdim template <class T> constexpr bool operator>(const optional<T>&, const T&); 73276792Sdim template <class T> constexpr bool operator>(const T&, const optional<T>&); 74276792Sdim template <class T> constexpr bool operator>=(const optional<T>&, const T&); 75276792Sdim template <class T> constexpr bool operator>=(const T&, const optional<T>&); 76261272Sdim 77276792Sdim // 5.10, Specialized algorithms 78276792Sdim template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below); 79276792Sdim template <class T> constexpr optional<see below> make_optional(T&&); 80261272Sdim 81276792Sdim template <class T> 82276792Sdim class optional 83276792Sdim { 84276792Sdim public: 85276792Sdim typedef T value_type; 86261272Sdim 87276792Sdim // 5.3.1, Constructors 88276792Sdim constexpr optional() noexcept; 89276792Sdim constexpr optional(nullopt_t) noexcept; 90276792Sdim optional(const optional&); 91276792Sdim optional(optional&&) noexcept(see below); 92276792Sdim constexpr optional(const T&); 93276792Sdim constexpr optional(T&&); 94276792Sdim template <class... Args> constexpr explicit optional(in_place_t, Args&&...); 95276792Sdim template <class U, class... Args> 96276792Sdim constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...); 97261272Sdim 98276792Sdim // 5.3.2, Destructor 99276792Sdim ~optional(); 100261272Sdim 101276792Sdim // 5.3.3, Assignment 102276792Sdim optional& operator=(nullopt_t) noexcept; 103276792Sdim optional& operator=(const optional&); 104276792Sdim optional& operator=(optional&&) noexcept(see below); 105276792Sdim template <class U> optional& operator=(U&&); 106276792Sdim template <class... Args> void emplace(Args&&...); 107276792Sdim template <class U, class... Args> 108276792Sdim void emplace(initializer_list<U>, Args&&...); 109261272Sdim 110276792Sdim // 5.3.4, Swap 111276792Sdim void swap(optional&) noexcept(see below); 112261272Sdim 113276792Sdim // 5.3.5, Observers 114276792Sdim constexpr T const* operator ->() const; 115276792Sdim constexpr T* operator ->(); 116276792Sdim constexpr T const& operator *() const &; 117276792Sdim constexpr T& operator *() &; 118276792Sdim constexpr T&& operator *() &&; 119276792Sdim constexpr const T&& operator *() const &&; 120276792Sdim constexpr explicit operator bool() const noexcept; 121276792Sdim constexpr T const& value() const &; 122276792Sdim constexpr T& value() &; 123276792Sdim constexpr T&& value() &&; 124276792Sdim constexpr const T&& value() const &&; 125276792Sdim template <class U> constexpr T value_or(U&&) const &; 126276792Sdim template <class U> constexpr T value_or(U&&) &&; 127261272Sdim 128276792Sdim private: 129276792Sdim T* val; // exposition only 130276792Sdim }; 131261272Sdim 132276792Sdim } // namespace fundamentals_v1 133276792Sdim } // namespace experimental 134261272Sdim 135276792Sdim // 5.11, Hash support 136276792Sdim template <class T> struct hash; 137276792Sdim template <class T> struct hash<experimental::optional<T>>; 138276792Sdim 139276792Sdim} // namespace std 140276792Sdim 141261272Sdim*/ 142261272Sdim 143276792Sdim#include <experimental/__config> 144261272Sdim#include <functional> 145261272Sdim#include <stdexcept> 146261272Sdim 147276792Sdim_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL 148261272Sdimclass _LIBCPP_EXCEPTION_ABI bad_optional_access 149276792Sdim : public std::logic_error 150261272Sdim{ 151261272Sdimpublic: 152276792Sdim bad_optional_access() : std::logic_error("Bad optional Access") {} 153276792Sdim 154276792Sdim// Get the key function ~bad_optional_access() into the dylib 155261272Sdim virtual ~bad_optional_access() _NOEXCEPT; 156261272Sdim}; 157261272Sdim 158276792Sdim_LIBCPP_END_NAMESPACE_EXPERIMENTAL 159261272Sdim 160276792Sdim 161261272Sdim#if _LIBCPP_STD_VER > 11 162261272Sdim 163261272Sdim#include <initializer_list> 164261272Sdim#include <type_traits> 165261272Sdim#include <new> 166261272Sdim#include <__functional_base> 167261272Sdim#include <__undef_min_max> 168276792Sdim#include <__debug> 169261272Sdim 170261272Sdim#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 171261272Sdim#pragma GCC system_header 172261272Sdim#endif 173261272Sdim 174276792Sdim_LIBCPP_BEGIN_NAMESPACE_LFTS 175261272Sdim 176261272Sdimstruct in_place_t {}; 177261272Sdimconstexpr in_place_t in_place{}; 178261272Sdim 179261272Sdimstruct nullopt_t 180261272Sdim{ 181261272Sdim explicit constexpr nullopt_t(int) noexcept {} 182261272Sdim}; 183261272Sdim 184261272Sdimconstexpr nullopt_t nullopt{0}; 185261272Sdim 186261272Sdimtemplate <class _Tp, bool = is_trivially_destructible<_Tp>::value> 187261272Sdimclass __optional_storage 188261272Sdim{ 189261272Sdimprotected: 190261272Sdim typedef _Tp value_type; 191261272Sdim union 192261272Sdim { 193261272Sdim char __null_state_; 194261272Sdim value_type __val_; 195261272Sdim }; 196261272Sdim bool __engaged_ = false; 197261272Sdim 198261272Sdim _LIBCPP_INLINE_VISIBILITY 199261272Sdim ~__optional_storage() 200261272Sdim { 201261272Sdim if (__engaged_) 202261272Sdim __val_.~value_type(); 203261272Sdim } 204261272Sdim 205261272Sdim _LIBCPP_INLINE_VISIBILITY 206261272Sdim constexpr __optional_storage() noexcept 207261272Sdim : __null_state_('\0') {} 208261272Sdim 209261272Sdim _LIBCPP_INLINE_VISIBILITY 210261272Sdim __optional_storage(const __optional_storage& __x) 211261272Sdim : __engaged_(__x.__engaged_) 212261272Sdim { 213261272Sdim if (__engaged_) 214261272Sdim ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); 215261272Sdim } 216261272Sdim 217261272Sdim _LIBCPP_INLINE_VISIBILITY 218261272Sdim __optional_storage(__optional_storage&& __x) 219261272Sdim noexcept(is_nothrow_move_constructible<value_type>::value) 220261272Sdim : __engaged_(__x.__engaged_) 221261272Sdim { 222261272Sdim if (__engaged_) 223261272Sdim ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); 224261272Sdim } 225261272Sdim 226261272Sdim _LIBCPP_INLINE_VISIBILITY 227261272Sdim constexpr __optional_storage(const value_type& __v) 228261272Sdim : __val_(__v), 229261272Sdim __engaged_(true) {} 230261272Sdim 231261272Sdim _LIBCPP_INLINE_VISIBILITY 232261272Sdim constexpr __optional_storage(value_type&& __v) 233261272Sdim : __val_(_VSTD::move(__v)), 234261272Sdim __engaged_(true) {} 235261272Sdim 236261272Sdim template <class... _Args> 237261272Sdim _LIBCPP_INLINE_VISIBILITY 238261272Sdim constexpr 239261272Sdim explicit __optional_storage(in_place_t, _Args&&... __args) 240261272Sdim : __val_(_VSTD::forward<_Args>(__args)...), 241261272Sdim __engaged_(true) {} 242261272Sdim}; 243261272Sdim 244261272Sdimtemplate <class _Tp> 245261272Sdimclass __optional_storage<_Tp, true> 246261272Sdim{ 247261272Sdimprotected: 248261272Sdim typedef _Tp value_type; 249261272Sdim union 250261272Sdim { 251261272Sdim char __null_state_; 252261272Sdim value_type __val_; 253261272Sdim }; 254261272Sdim bool __engaged_ = false; 255261272Sdim 256261272Sdim _LIBCPP_INLINE_VISIBILITY 257261272Sdim constexpr __optional_storage() noexcept 258261272Sdim : __null_state_('\0') {} 259261272Sdim 260261272Sdim _LIBCPP_INLINE_VISIBILITY 261261272Sdim __optional_storage(const __optional_storage& __x) 262261272Sdim : __engaged_(__x.__engaged_) 263261272Sdim { 264261272Sdim if (__engaged_) 265261272Sdim ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); 266261272Sdim } 267261272Sdim 268261272Sdim _LIBCPP_INLINE_VISIBILITY 269261272Sdim __optional_storage(__optional_storage&& __x) 270261272Sdim noexcept(is_nothrow_move_constructible<value_type>::value) 271261272Sdim : __engaged_(__x.__engaged_) 272261272Sdim { 273261272Sdim if (__engaged_) 274261272Sdim ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); 275261272Sdim } 276261272Sdim 277261272Sdim _LIBCPP_INLINE_VISIBILITY 278261272Sdim constexpr __optional_storage(const value_type& __v) 279261272Sdim : __val_(__v), 280261272Sdim __engaged_(true) {} 281261272Sdim 282261272Sdim _LIBCPP_INLINE_VISIBILITY 283261272Sdim constexpr __optional_storage(value_type&& __v) 284261272Sdim : __val_(_VSTD::move(__v)), 285261272Sdim __engaged_(true) {} 286261272Sdim 287261272Sdim template <class... _Args> 288261272Sdim _LIBCPP_INLINE_VISIBILITY 289261272Sdim constexpr 290261272Sdim explicit __optional_storage(in_place_t, _Args&&... __args) 291261272Sdim : __val_(_VSTD::forward<_Args>(__args)...), 292261272Sdim __engaged_(true) {} 293261272Sdim}; 294261272Sdim 295261272Sdimtemplate <class _Tp> 296261272Sdimclass optional 297261272Sdim : private __optional_storage<_Tp> 298261272Sdim{ 299261272Sdim typedef __optional_storage<_Tp> __base; 300261272Sdimpublic: 301261272Sdim typedef _Tp value_type; 302261272Sdim 303261272Sdim static_assert(!is_reference<value_type>::value, 304261272Sdim "Instantiation of optional with a reference type is ill-formed."); 305261272Sdim static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value, 306261272Sdim "Instantiation of optional with a in_place_t type is ill-formed."); 307261272Sdim static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value, 308261272Sdim "Instantiation of optional with a nullopt_t type is ill-formed."); 309261272Sdim static_assert(is_object<value_type>::value, 310261272Sdim "Instantiation of optional with a non-object type is undefined behavior."); 311261272Sdim static_assert(is_nothrow_destructible<value_type>::value, 312261272Sdim "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior."); 313261272Sdim 314261272Sdim _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} 315261272Sdim _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; 316261272Sdim _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; 317261272Sdim _LIBCPP_INLINE_VISIBILITY ~optional() = default; 318261272Sdim _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} 319261272Sdim _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v) 320261272Sdim : __base(__v) {} 321261272Sdim _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v) 322261272Sdim : __base(_VSTD::move(__v)) {} 323261272Sdim 324261272Sdim template <class... _Args, 325261272Sdim class = typename enable_if 326261272Sdim < 327261272Sdim is_constructible<value_type, _Args...>::value 328261272Sdim >::type 329261272Sdim > 330261272Sdim _LIBCPP_INLINE_VISIBILITY 331261272Sdim constexpr 332261272Sdim explicit optional(in_place_t, _Args&&... __args) 333261272Sdim : __base(in_place, _VSTD::forward<_Args>(__args)...) {} 334261272Sdim 335261272Sdim template <class _Up, class... _Args, 336261272Sdim class = typename enable_if 337261272Sdim < 338261272Sdim is_constructible<value_type, initializer_list<_Up>&, _Args...>::value 339261272Sdim >::type 340261272Sdim > 341261272Sdim _LIBCPP_INLINE_VISIBILITY 342261272Sdim constexpr 343261272Sdim explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 344261272Sdim : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} 345261272Sdim 346261272Sdim _LIBCPP_INLINE_VISIBILITY 347261272Sdim optional& operator=(nullopt_t) noexcept 348261272Sdim { 349261272Sdim if (this->__engaged_) 350261272Sdim { 351261272Sdim this->__val_.~value_type(); 352261272Sdim this->__engaged_ = false; 353261272Sdim } 354261272Sdim return *this; 355261272Sdim } 356261272Sdim 357261272Sdim _LIBCPP_INLINE_VISIBILITY 358261272Sdim optional& 359261272Sdim operator=(const optional& __opt) 360261272Sdim { 361261272Sdim if (this->__engaged_ == __opt.__engaged_) 362261272Sdim { 363261272Sdim if (this->__engaged_) 364261272Sdim this->__val_ = __opt.__val_; 365261272Sdim } 366261272Sdim else 367261272Sdim { 368261272Sdim if (this->__engaged_) 369261272Sdim this->__val_.~value_type(); 370261272Sdim else 371261272Sdim ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_); 372261272Sdim this->__engaged_ = __opt.__engaged_; 373261272Sdim } 374261272Sdim return *this; 375261272Sdim } 376261272Sdim 377261272Sdim _LIBCPP_INLINE_VISIBILITY 378261272Sdim optional& 379261272Sdim operator=(optional&& __opt) 380261272Sdim noexcept(is_nothrow_move_assignable<value_type>::value && 381261272Sdim is_nothrow_move_constructible<value_type>::value) 382261272Sdim { 383261272Sdim if (this->__engaged_ == __opt.__engaged_) 384261272Sdim { 385261272Sdim if (this->__engaged_) 386261272Sdim this->__val_ = _VSTD::move(__opt.__val_); 387261272Sdim } 388261272Sdim else 389261272Sdim { 390261272Sdim if (this->__engaged_) 391261272Sdim this->__val_.~value_type(); 392261272Sdim else 393261272Sdim ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); 394261272Sdim this->__engaged_ = __opt.__engaged_; 395261272Sdim } 396261272Sdim return *this; 397261272Sdim } 398261272Sdim 399261272Sdim template <class _Up, 400261272Sdim class = typename enable_if 401261272Sdim < 402261272Sdim is_same<typename remove_reference<_Up>::type, value_type>::value && 403261272Sdim is_constructible<value_type, _Up>::value && 404261272Sdim is_assignable<value_type&, _Up>::value 405261272Sdim >::type 406261272Sdim > 407261272Sdim _LIBCPP_INLINE_VISIBILITY 408261272Sdim optional& 409261272Sdim operator=(_Up&& __v) 410261272Sdim { 411261272Sdim if (this->__engaged_) 412261272Sdim this->__val_ = _VSTD::forward<_Up>(__v); 413261272Sdim else 414261272Sdim { 415261272Sdim ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); 416261272Sdim this->__engaged_ = true; 417261272Sdim } 418261272Sdim return *this; 419261272Sdim } 420261272Sdim 421261272Sdim template <class... _Args, 422261272Sdim class = typename enable_if 423261272Sdim < 424261272Sdim is_constructible<value_type, _Args...>::value 425261272Sdim >::type 426261272Sdim > 427261272Sdim _LIBCPP_INLINE_VISIBILITY 428261272Sdim void 429261272Sdim emplace(_Args&&... __args) 430261272Sdim { 431261272Sdim *this = nullopt; 432261272Sdim ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); 433261272Sdim this->__engaged_ = true; 434261272Sdim } 435261272Sdim 436261272Sdim template <class _Up, class... _Args, 437261272Sdim class = typename enable_if 438261272Sdim < 439261272Sdim is_constructible<value_type, initializer_list<_Up>&, _Args...>::value 440261272Sdim >::type 441261272Sdim > 442261272Sdim _LIBCPP_INLINE_VISIBILITY 443261272Sdim void 444261272Sdim emplace(initializer_list<_Up> __il, _Args&&... __args) 445261272Sdim { 446261272Sdim *this = nullopt; 447261272Sdim ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...); 448261272Sdim this->__engaged_ = true; 449261272Sdim } 450261272Sdim 451261272Sdim _LIBCPP_INLINE_VISIBILITY 452261272Sdim void 453261272Sdim swap(optional& __opt) 454261272Sdim noexcept(is_nothrow_move_constructible<value_type>::value && 455261272Sdim __is_nothrow_swappable<value_type>::value) 456261272Sdim { 457261272Sdim using _VSTD::swap; 458261272Sdim if (this->__engaged_ == __opt.__engaged_) 459261272Sdim { 460261272Sdim if (this->__engaged_) 461261272Sdim swap(this->__val_, __opt.__val_); 462261272Sdim } 463261272Sdim else 464261272Sdim { 465261272Sdim if (this->__engaged_) 466261272Sdim { 467261272Sdim ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_)); 468261272Sdim this->__val_.~value_type(); 469261272Sdim } 470261272Sdim else 471261272Sdim { 472261272Sdim ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); 473261272Sdim __opt.__val_.~value_type(); 474261272Sdim } 475261272Sdim swap(this->__engaged_, __opt.__engaged_); 476261272Sdim } 477261272Sdim } 478261272Sdim 479261272Sdim _LIBCPP_INLINE_VISIBILITY 480261272Sdim constexpr 481261272Sdim value_type const* 482261272Sdim operator->() const 483261272Sdim { 484261272Sdim _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); 485261272Sdim return __operator_arrow(__has_operator_addressof<value_type>{}); 486261272Sdim } 487261272Sdim 488261272Sdim _LIBCPP_INLINE_VISIBILITY 489261272Sdim value_type* 490261272Sdim operator->() 491261272Sdim { 492261272Sdim _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); 493261272Sdim return _VSTD::addressof(this->__val_); 494261272Sdim } 495261272Sdim 496261272Sdim _LIBCPP_INLINE_VISIBILITY 497261272Sdim constexpr 498261272Sdim const value_type& 499261272Sdim operator*() const 500261272Sdim { 501261272Sdim _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); 502261272Sdim return this->__val_; 503261272Sdim } 504261272Sdim 505261272Sdim _LIBCPP_INLINE_VISIBILITY 506261272Sdim value_type& 507261272Sdim operator*() 508261272Sdim { 509261272Sdim _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value"); 510261272Sdim return this->__val_; 511261272Sdim } 512261272Sdim 513261272Sdim _LIBCPP_INLINE_VISIBILITY 514261272Sdim constexpr explicit operator bool() const noexcept {return this->__engaged_;} 515261272Sdim 516261272Sdim _LIBCPP_INLINE_VISIBILITY 517261272Sdim constexpr value_type const& value() const 518261272Sdim { 519261272Sdim if (!this->__engaged_) 520276792Sdim throw bad_optional_access(); 521261272Sdim return this->__val_; 522261272Sdim } 523261272Sdim 524261272Sdim _LIBCPP_INLINE_VISIBILITY 525261272Sdim value_type& value() 526261272Sdim { 527261272Sdim if (!this->__engaged_) 528276792Sdim throw bad_optional_access(); 529261272Sdim return this->__val_; 530261272Sdim } 531261272Sdim 532261272Sdim template <class _Up> 533261272Sdim _LIBCPP_INLINE_VISIBILITY 534261272Sdim constexpr value_type value_or(_Up&& __v) const& 535261272Sdim { 536261272Sdim static_assert(is_copy_constructible<value_type>::value, 537261272Sdim "optional<T>::value_or: T must be copy constructible"); 538261272Sdim static_assert(is_convertible<_Up, value_type>::value, 539261272Sdim "optional<T>::value_or: U must be convertible to T"); 540261272Sdim return this->__engaged_ ? this->__val_ : 541261272Sdim static_cast<value_type>(_VSTD::forward<_Up>(__v)); 542261272Sdim } 543261272Sdim 544261272Sdim template <class _Up> 545261272Sdim _LIBCPP_INLINE_VISIBILITY 546261272Sdim value_type value_or(_Up&& __v) && 547261272Sdim { 548261272Sdim static_assert(is_move_constructible<value_type>::value, 549261272Sdim "optional<T>::value_or: T must be move constructible"); 550261272Sdim static_assert(is_convertible<_Up, value_type>::value, 551261272Sdim "optional<T>::value_or: U must be convertible to T"); 552261272Sdim return this->__engaged_ ? _VSTD::move(this->__val_) : 553261272Sdim static_cast<value_type>(_VSTD::forward<_Up>(__v)); 554261272Sdim } 555261272Sdim 556261272Sdimprivate: 557261272Sdim _LIBCPP_INLINE_VISIBILITY 558261272Sdim value_type const* 559261272Sdim __operator_arrow(true_type) const 560261272Sdim { 561261272Sdim return _VSTD::addressof(this->__val_); 562261272Sdim } 563261272Sdim 564261272Sdim _LIBCPP_INLINE_VISIBILITY 565261272Sdim constexpr 566261272Sdim value_type const* 567261272Sdim __operator_arrow(false_type) const 568261272Sdim { 569261272Sdim return &this->__val_; 570261272Sdim } 571261272Sdim}; 572261272Sdim 573276792Sdim// Comparisons between optionals 574261272Sdimtemplate <class _Tp> 575261272Sdiminline _LIBCPP_INLINE_VISIBILITY 576261272Sdimconstexpr 577261272Sdimbool 578261272Sdimoperator==(const optional<_Tp>& __x, const optional<_Tp>& __y) 579261272Sdim{ 580261272Sdim if (static_cast<bool>(__x) != static_cast<bool>(__y)) 581261272Sdim return false; 582261272Sdim if (!static_cast<bool>(__x)) 583261272Sdim return true; 584261272Sdim return *__x == *__y; 585261272Sdim} 586261272Sdim 587261272Sdimtemplate <class _Tp> 588261272Sdiminline _LIBCPP_INLINE_VISIBILITY 589261272Sdimconstexpr 590261272Sdimbool 591276792Sdimoperator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) 592276792Sdim{ 593276792Sdim return !(__x == __y); 594276792Sdim} 595276792Sdim 596276792Sdimtemplate <class _Tp> 597276792Sdiminline _LIBCPP_INLINE_VISIBILITY 598276792Sdimconstexpr 599276792Sdimbool 600261272Sdimoperator<(const optional<_Tp>& __x, const optional<_Tp>& __y) 601261272Sdim{ 602261272Sdim if (!static_cast<bool>(__y)) 603261272Sdim return false; 604261272Sdim if (!static_cast<bool>(__x)) 605261272Sdim return true; 606276792Sdim return *__x < *__y; 607261272Sdim} 608261272Sdim 609261272Sdimtemplate <class _Tp> 610261272Sdiminline _LIBCPP_INLINE_VISIBILITY 611261272Sdimconstexpr 612261272Sdimbool 613276792Sdimoperator>(const optional<_Tp>& __x, const optional<_Tp>& __y) 614276792Sdim{ 615276792Sdim return __y < __x; 616276792Sdim} 617276792Sdim 618276792Sdimtemplate <class _Tp> 619276792Sdiminline _LIBCPP_INLINE_VISIBILITY 620276792Sdimconstexpr 621276792Sdimbool 622276792Sdimoperator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) 623276792Sdim{ 624276792Sdim return !(__y < __x); 625276792Sdim} 626276792Sdim 627276792Sdimtemplate <class _Tp> 628276792Sdiminline _LIBCPP_INLINE_VISIBILITY 629276792Sdimconstexpr 630276792Sdimbool 631276792Sdimoperator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) 632276792Sdim{ 633276792Sdim return !(__x < __y); 634276792Sdim} 635276792Sdim 636276792Sdim 637276792Sdim// Comparisons with nullopt 638276792Sdimtemplate <class _Tp> 639276792Sdiminline _LIBCPP_INLINE_VISIBILITY 640276792Sdimconstexpr 641276792Sdimbool 642261272Sdimoperator==(const optional<_Tp>& __x, nullopt_t) noexcept 643261272Sdim{ 644261272Sdim return !static_cast<bool>(__x); 645261272Sdim} 646261272Sdim 647261272Sdimtemplate <class _Tp> 648261272Sdiminline _LIBCPP_INLINE_VISIBILITY 649261272Sdimconstexpr 650261272Sdimbool 651261272Sdimoperator==(nullopt_t, const optional<_Tp>& __x) noexcept 652261272Sdim{ 653261272Sdim return !static_cast<bool>(__x); 654261272Sdim} 655261272Sdim 656261272Sdimtemplate <class _Tp> 657261272Sdiminline _LIBCPP_INLINE_VISIBILITY 658261272Sdimconstexpr 659261272Sdimbool 660276792Sdimoperator!=(const optional<_Tp>& __x, nullopt_t) noexcept 661276792Sdim{ 662276792Sdim return static_cast<bool>(__x); 663276792Sdim} 664276792Sdim 665276792Sdimtemplate <class _Tp> 666276792Sdiminline _LIBCPP_INLINE_VISIBILITY 667276792Sdimconstexpr 668276792Sdimbool 669276792Sdimoperator!=(nullopt_t, const optional<_Tp>& __x) noexcept 670276792Sdim{ 671276792Sdim return static_cast<bool>(__x); 672276792Sdim} 673276792Sdim 674276792Sdimtemplate <class _Tp> 675276792Sdiminline _LIBCPP_INLINE_VISIBILITY 676276792Sdimconstexpr 677276792Sdimbool 678261272Sdimoperator<(const optional<_Tp>&, nullopt_t) noexcept 679261272Sdim{ 680261272Sdim return false; 681261272Sdim} 682261272Sdim 683261272Sdimtemplate <class _Tp> 684261272Sdiminline _LIBCPP_INLINE_VISIBILITY 685261272Sdimconstexpr 686261272Sdimbool 687261272Sdimoperator<(nullopt_t, const optional<_Tp>& __x) noexcept 688261272Sdim{ 689261272Sdim return static_cast<bool>(__x); 690261272Sdim} 691261272Sdim 692261272Sdimtemplate <class _Tp> 693261272Sdiminline _LIBCPP_INLINE_VISIBILITY 694261272Sdimconstexpr 695261272Sdimbool 696276792Sdimoperator<=(const optional<_Tp>& __x, nullopt_t) noexcept 697276792Sdim{ 698276792Sdim return !static_cast<bool>(__x); 699276792Sdim} 700276792Sdim 701276792Sdimtemplate <class _Tp> 702276792Sdiminline _LIBCPP_INLINE_VISIBILITY 703276792Sdimconstexpr 704276792Sdimbool 705276792Sdimoperator<=(nullopt_t, const optional<_Tp>& __x) noexcept 706276792Sdim{ 707276792Sdim return true; 708276792Sdim} 709276792Sdim 710276792Sdimtemplate <class _Tp> 711276792Sdiminline _LIBCPP_INLINE_VISIBILITY 712276792Sdimconstexpr 713276792Sdimbool 714276792Sdimoperator>(const optional<_Tp>& __x, nullopt_t) noexcept 715276792Sdim{ 716276792Sdim return static_cast<bool>(__x); 717276792Sdim} 718276792Sdim 719276792Sdimtemplate <class _Tp> 720276792Sdiminline _LIBCPP_INLINE_VISIBILITY 721276792Sdimconstexpr 722276792Sdimbool 723276792Sdimoperator>(nullopt_t, const optional<_Tp>& __x) noexcept 724276792Sdim{ 725276792Sdim return false; 726276792Sdim} 727276792Sdim 728276792Sdimtemplate <class _Tp> 729276792Sdiminline _LIBCPP_INLINE_VISIBILITY 730276792Sdimconstexpr 731276792Sdimbool 732276792Sdimoperator>=(const optional<_Tp>&, nullopt_t) noexcept 733276792Sdim{ 734276792Sdim return true; 735276792Sdim} 736276792Sdim 737276792Sdimtemplate <class _Tp> 738276792Sdiminline _LIBCPP_INLINE_VISIBILITY 739276792Sdimconstexpr 740276792Sdimbool 741276792Sdimoperator>=(nullopt_t, const optional<_Tp>& __x) noexcept 742276792Sdim{ 743276792Sdim return !static_cast<bool>(__x); 744276792Sdim} 745276792Sdim 746276792Sdim// Comparisons with T 747276792Sdimtemplate <class _Tp> 748276792Sdiminline _LIBCPP_INLINE_VISIBILITY 749276792Sdimconstexpr 750276792Sdimbool 751261272Sdimoperator==(const optional<_Tp>& __x, const _Tp& __v) 752261272Sdim{ 753261272Sdim return static_cast<bool>(__x) ? *__x == __v : false; 754261272Sdim} 755261272Sdim 756261272Sdimtemplate <class _Tp> 757261272Sdiminline _LIBCPP_INLINE_VISIBILITY 758261272Sdimconstexpr 759261272Sdimbool 760261272Sdimoperator==(const _Tp& __v, const optional<_Tp>& __x) 761261272Sdim{ 762261272Sdim return static_cast<bool>(__x) ? *__x == __v : false; 763261272Sdim} 764261272Sdim 765261272Sdimtemplate <class _Tp> 766261272Sdiminline _LIBCPP_INLINE_VISIBILITY 767261272Sdimconstexpr 768261272Sdimbool 769276792Sdimoperator!=(const optional<_Tp>& __x, const _Tp& __v) 770276792Sdim{ 771276792Sdim return static_cast<bool>(__x) ? !(*__x == __v) : true; 772276792Sdim} 773276792Sdim 774276792Sdimtemplate <class _Tp> 775276792Sdiminline _LIBCPP_INLINE_VISIBILITY 776276792Sdimconstexpr 777276792Sdimbool 778276792Sdimoperator!=(const _Tp& __v, const optional<_Tp>& __x) 779276792Sdim{ 780276792Sdim return static_cast<bool>(__x) ? !(*__x == __v) : true; 781276792Sdim} 782276792Sdim 783276792Sdimtemplate <class _Tp> 784276792Sdiminline _LIBCPP_INLINE_VISIBILITY 785276792Sdimconstexpr 786276792Sdimbool 787261272Sdimoperator<(const optional<_Tp>& __x, const _Tp& __v) 788261272Sdim{ 789261272Sdim return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true; 790261272Sdim} 791261272Sdim 792261272Sdimtemplate <class _Tp> 793261272Sdiminline _LIBCPP_INLINE_VISIBILITY 794261272Sdimconstexpr 795261272Sdimbool 796261272Sdimoperator<(const _Tp& __v, const optional<_Tp>& __x) 797261272Sdim{ 798261272Sdim return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false; 799261272Sdim} 800261272Sdim 801261272Sdimtemplate <class _Tp> 802261272Sdiminline _LIBCPP_INLINE_VISIBILITY 803276792Sdimconstexpr 804276792Sdimbool 805276792Sdimoperator<=(const optional<_Tp>& __x, const _Tp& __v) 806276792Sdim{ 807276792Sdim return !(__x > __v); 808276792Sdim} 809276792Sdim 810276792Sdimtemplate <class _Tp> 811276792Sdiminline _LIBCPP_INLINE_VISIBILITY 812276792Sdimconstexpr 813276792Sdimbool 814276792Sdimoperator<=(const _Tp& __v, const optional<_Tp>& __x) 815276792Sdim{ 816276792Sdim return !(__v > __x); 817276792Sdim} 818276792Sdim 819276792Sdimtemplate <class _Tp> 820276792Sdiminline _LIBCPP_INLINE_VISIBILITY 821276792Sdimconstexpr 822276792Sdimbool 823276792Sdimoperator>(const optional<_Tp>& __x, const _Tp& __v) 824276792Sdim{ 825276792Sdim return static_cast<bool>(__x) ? __v < __x : false; 826276792Sdim} 827276792Sdim 828276792Sdimtemplate <class _Tp> 829276792Sdiminline _LIBCPP_INLINE_VISIBILITY 830276792Sdimconstexpr 831276792Sdimbool 832276792Sdimoperator>(const _Tp& __v, const optional<_Tp>& __x) 833276792Sdim{ 834276792Sdim return static_cast<bool>(__x) ? __x < __v : true; 835276792Sdim} 836276792Sdim 837276792Sdimtemplate <class _Tp> 838276792Sdiminline _LIBCPP_INLINE_VISIBILITY 839276792Sdimconstexpr 840276792Sdimbool 841276792Sdimoperator>=(const optional<_Tp>& __x, const _Tp& __v) 842276792Sdim{ 843276792Sdim return !(__x < __v); 844276792Sdim} 845276792Sdim 846276792Sdimtemplate <class _Tp> 847276792Sdiminline _LIBCPP_INLINE_VISIBILITY 848276792Sdimconstexpr 849276792Sdimbool 850276792Sdimoperator>=(const _Tp& __v, const optional<_Tp>& __x) 851276792Sdim{ 852276792Sdim return !(__v < __x); 853276792Sdim} 854276792Sdim 855276792Sdim 856276792Sdimtemplate <class _Tp> 857276792Sdiminline _LIBCPP_INLINE_VISIBILITY 858261272Sdimvoid 859261272Sdimswap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 860261272Sdim{ 861261272Sdim __x.swap(__y); 862261272Sdim} 863261272Sdim 864261272Sdimtemplate <class _Tp> 865261272Sdiminline _LIBCPP_INLINE_VISIBILITY 866261272Sdimconstexpr 867261272Sdimoptional<typename decay<_Tp>::type> 868261272Sdimmake_optional(_Tp&& __v) 869261272Sdim{ 870261272Sdim return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v)); 871261272Sdim} 872261272Sdim 873276792Sdim_LIBCPP_END_NAMESPACE_LFTS 874261272Sdim 875261272Sdim_LIBCPP_BEGIN_NAMESPACE_STD 876261272Sdim 877261272Sdimtemplate <class _Tp> 878261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> > 879261272Sdim{ 880261272Sdim typedef std::experimental::optional<_Tp> argument_type; 881261272Sdim typedef size_t result_type; 882261272Sdim 883261272Sdim _LIBCPP_INLINE_VISIBILITY 884261272Sdim result_type operator()(const argument_type& __opt) const _NOEXCEPT 885261272Sdim { 886261272Sdim return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0; 887261272Sdim } 888261272Sdim}; 889261272Sdim 890261272Sdim_LIBCPP_END_NAMESPACE_STD 891261272Sdim 892261272Sdim#endif // _LIBCPP_STD_VER > 11 893261272Sdim 894276792Sdim#endif // _LIBCPP_OPTIONAL 895