1a9e65961SEric Fiselier// -*- C++ -*- 2a9e65961SEric Fiselier//===-------------------------- optional ----------------------------------===// 3a9e65961SEric Fiselier// 4a9e65961SEric Fiselier// The LLVM Compiler Infrastructure 5a9e65961SEric Fiselier// 6a9e65961SEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open 7a9e65961SEric Fiselier// Source Licenses. See LICENSE.TXT for details. 8a9e65961SEric Fiselier// 9a9e65961SEric Fiselier//===----------------------------------------------------------------------===// 10a9e65961SEric Fiselier 11a9e65961SEric Fiselier#ifndef _LIBCPP_OPTIONAL 12a9e65961SEric Fiselier#define _LIBCPP_OPTIONAL 13a9e65961SEric Fiselier 14a9e65961SEric Fiselier/* 15a9e65961SEric Fiselier optional synopsis 16a9e65961SEric Fiselier 17a9e65961SEric Fiselier// C++1z 18a9e65961SEric Fiselier 19a9e65961SEric Fiseliernamespace std { 20a9e65961SEric Fiselier // 20.6.3, optional for object types 21a9e65961SEric Fiselier template <class T> class optional; 22a9e65961SEric Fiselier 23a9e65961SEric Fiselier // 20.6.4, no-value state indicator 24a9e65961SEric Fiselier struct nullopt_t{see below }; 25a9e65961SEric Fiselier constexpr nullopt_t nullopt(unspecified ); 26a9e65961SEric Fiselier 27a9e65961SEric Fiselier // 20.6.5, class bad_optional_access 28a9e65961SEric Fiselier class bad_optional_access; 29a9e65961SEric Fiselier 30a9e65961SEric Fiselier // 20.6.6, relational operators 31a9e65961SEric Fiselier template <class T> 32a9e65961SEric Fiselier constexpr bool operator==(const optional<T>&, const optional<T>&); 33a9e65961SEric Fiselier template <class T> 34a9e65961SEric Fiselier constexpr bool operator!=(const optional<T>&, const optional<T>&); 35a9e65961SEric Fiselier template <class T> 36a9e65961SEric Fiselier constexpr bool operator<(const optional<T>&, const optional<T>&); 37a9e65961SEric Fiselier template <class T> 38a9e65961SEric Fiselier constexpr bool operator>(const optional<T>&, const optional<T>&); 39a9e65961SEric Fiselier template <class T> 40a9e65961SEric Fiselier constexpr bool operator<=(const optional<T>&, const optional<T>&); 41a9e65961SEric Fiselier template <class T> 42a9e65961SEric Fiselier constexpr bool operator>=(const optional<T>&, const optional<T>&); 43a9e65961SEric Fiselier template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; 44a9e65961SEric Fiselier template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; 45a9e65961SEric Fiselier template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; 46a9e65961SEric Fiselier template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; 47a9e65961SEric Fiselier template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; 48a9e65961SEric Fiselier template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; 49a9e65961SEric Fiselier template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; 50a9e65961SEric Fiselier template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; 51a9e65961SEric Fiselier template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; 52a9e65961SEric Fiselier template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; 53a9e65961SEric Fiselier template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; 54a9e65961SEric Fiselier template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; 55a9e65961SEric Fiselier 56a9e65961SEric Fiselier // 20.6.8, comparison with T 57a9e65961SEric Fiselier template <class T> constexpr bool operator==(const optional<T>&, const T&); 58a9e65961SEric Fiselier template <class T> constexpr bool operator==(const T&, const optional<T>&); 59a9e65961SEric Fiselier template <class T> constexpr bool operator!=(const optional<T>&, const T&); 60a9e65961SEric Fiselier template <class T> constexpr bool operator!=(const T&, const optional<T>&); 61a9e65961SEric Fiselier template <class T> constexpr bool operator<(const optional<T>&, const T&); 62a9e65961SEric Fiselier template <class T> constexpr bool operator<(const T&, const optional<T>&); 63a9e65961SEric Fiselier template <class T> constexpr bool operator<=(const optional<T>&, const T&); 64a9e65961SEric Fiselier template <class T> constexpr bool operator<=(const T&, const optional<T>&); 65a9e65961SEric Fiselier template <class T> constexpr bool operator>(const optional<T>&, const T&); 66a9e65961SEric Fiselier template <class T> constexpr bool operator>(const T&, const optional<T>&); 67a9e65961SEric Fiselier template <class T> constexpr bool operator>=(const optional<T>&, const T&); 68a9e65961SEric Fiselier template <class T> constexpr bool operator>=(const T&, const optional<T>&); 69a9e65961SEric Fiselier 70a9e65961SEric Fiselier // 20.6.9, specialized algorithms 71a9e65961SEric Fiselier template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); 72a9e65961SEric Fiselier template <class T> constexpr optional<see below > make_optional(T&&); 73a9e65961SEric Fiselier template <class T, class... Args> 74a9e65961SEric Fiselier constexpr optional<T> make_optional(Args&&... args); 75a9e65961SEric Fiselier template <class T, class U, class... Args> 76a9e65961SEric Fiselier constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); 77a9e65961SEric Fiselier 78a9e65961SEric Fiselier // 20.6.10, hash support 79a9e65961SEric Fiselier template <class T> struct hash; 80a9e65961SEric Fiselier template <class T> struct hash<optional<T>>; 81a9e65961SEric Fiselier 82a9e65961SEric Fiselier template <class T> class optional { 83a9e65961SEric Fiselier public: 84a9e65961SEric Fiselier using value_type = T; 85a9e65961SEric Fiselier 86a9e65961SEric Fiselier // 20.6.3.1, constructors 87a9e65961SEric Fiselier constexpr optional() noexcept; 88a9e65961SEric Fiselier constexpr optional(nullopt_t) noexcept; 89a9e65961SEric Fiselier optional(const optional &); 90a9e65961SEric Fiselier optional(optional &&) noexcept(see below ); 91a9e65961SEric Fiselier template <class... Args> constexpr explicit optional(in_place_t, Args &&...); 92a9e65961SEric Fiselier template <class U, class... Args> 93a9e65961SEric Fiselier constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...); 94a9e65961SEric Fiselier template <class U = T> 95a9e65961SEric Fiselier constexpr EXPLICIT optional(U &&); 96a9e65961SEric Fiselier template <class U> 97a9e65961SEric Fiselier constexpr EXPLICIT optional(const optional<U> &); 98a9e65961SEric Fiselier template <class U> 99a9e65961SEric Fiselier constexpr EXPLICIT optional(optional<U> &&); 100a9e65961SEric Fiselier 101a9e65961SEric Fiselier // 20.6.3.2, destructor 102a9e65961SEric Fiselier ~optional(); 103a9e65961SEric Fiselier 104a9e65961SEric Fiselier // 20.6.3.3, assignment 105a9e65961SEric Fiselier optional &operator=(nullopt_t) noexcept; 106a9e65961SEric Fiselier optional &operator=(const optional &); 107a9e65961SEric Fiselier optional &operator=(optional &&) noexcept(see below ); 108a9e65961SEric Fiselier template <class U = T> optional &operator=(U &&); 109a9e65961SEric Fiselier template <class U> optional &operator=(const optional<U> &); 110a9e65961SEric Fiselier template <class U> optional &operator=(optional<U> &&); 111a9e65961SEric Fiselier template <class... Args> void emplace(Args &&...); 112a9e65961SEric Fiselier template <class U, class... Args> 113a9e65961SEric Fiselier void emplace(initializer_list<U>, Args &&...); 114a9e65961SEric Fiselier 115a9e65961SEric Fiselier // 20.6.3.4, swap 116a9e65961SEric Fiselier void swap(optional &) noexcept(see below ); 117a9e65961SEric Fiselier 118a9e65961SEric Fiselier // 20.6.3.5, observers 119a9e65961SEric Fiselier constexpr T const *operator->() const; 120a9e65961SEric Fiselier constexpr T *operator->(); 121a9e65961SEric Fiselier constexpr T const &operator*() const &; 122a9e65961SEric Fiselier constexpr T &operator*() &; 123a9e65961SEric Fiselier constexpr T &&operator*() &&; 124a9e65961SEric Fiselier constexpr const T &&operator*() const &&; 125a9e65961SEric Fiselier constexpr explicit operator bool() const noexcept; 126a9e65961SEric Fiselier constexpr bool has_value() const noexcept; 127a9e65961SEric Fiselier constexpr T const &value() const &; 128a9e65961SEric Fiselier constexpr T &value() &; 129a9e65961SEric Fiselier constexpr T &&value() &&; 130a9e65961SEric Fiselier constexpr const T &&value() const &&; 131a9e65961SEric Fiselier template <class U> constexpr T value_or(U &&) const &; 132a9e65961SEric Fiselier template <class U> constexpr T value_or(U &&) &&; 133a9e65961SEric Fiselier 134a9e65961SEric Fiselier // 20.6.3.6, modifiers 135a9e65961SEric Fiselier void reset() noexcept; 136a9e65961SEric Fiselier 137a9e65961SEric Fiselier private: 138a9e65961SEric Fiselier T *val; // exposition only 139a9e65961SEric Fiselier }; 140a9e65961SEric Fiselier} // namespace std 141a9e65961SEric Fiselier 142a9e65961SEric Fiselier*/ 143a9e65961SEric Fiselier 144a9e65961SEric Fiselier#include <__config> 145a9e65961SEric Fiselier#include <__debug> 146a9e65961SEric Fiselier#include <__functional_base> 147a9e65961SEric Fiselier#include <__undef_min_max> 148a9e65961SEric Fiselier#include <functional> 149a9e65961SEric Fiselier#include <initializer_list> 150a9e65961SEric Fiselier#include <new> 151a9e65961SEric Fiselier#include <stdexcept> 152a9e65961SEric Fiselier#include <type_traits> 153a9e65961SEric Fiselier#include <utility> 154a9e65961SEric Fiselier 155a9e65961SEric Fiselier#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 156a9e65961SEric Fiselier#pragma GCC system_header 157a9e65961SEric Fiselier#endif 158a9e65961SEric Fiselier 159a9e65961SEric Fiseliernamespace std // purposefully not using versioning namespace 160a9e65961SEric Fiselier{ 161a9e65961SEric Fiselier 162a9e65961SEric Fiselierclass _LIBCPP_EXCEPTION_ABI bad_optional_access 163a9e65961SEric Fiselier : public logic_error 164a9e65961SEric Fiselier{ 165a9e65961SEric Fiselierpublic: 166a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 167a9e65961SEric Fiselier bad_optional_access() : logic_error("bad optional access") {} 168a9e65961SEric Fiselier 169a9e65961SEric Fiselier // Get the key function ~bad_optional_access() into the dylib 170a9e65961SEric Fiselier _LIBCPP_FUNC_VIS 171a9e65961SEric Fiselier virtual ~bad_optional_access() _NOEXCEPT; 172a9e65961SEric Fiselier}; 173a9e65961SEric Fiselier 174a9e65961SEric Fiselier} // std 175a9e65961SEric Fiselier 176a9e65961SEric Fiselier#if _LIBCPP_STD_VER > 14 177a9e65961SEric Fiselier 178a9e65961SEric Fiselier_LIBCPP_BEGIN_NAMESPACE_STD 179a9e65961SEric Fiselier 180a9e65961SEric Fiselier_LIBCPP_NORETURN 181a9e65961SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 182a9e65961SEric Fiseliervoid __throw_bad_optional_access() { 183a9e65961SEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS 184a9e65961SEric Fiselier throw bad_optional_access(); 185a9e65961SEric Fiselier#else 186a9e65961SEric Fiselier _VSTD::abort(); 187a9e65961SEric Fiselier#endif 188a9e65961SEric Fiselier} 189a9e65961SEric Fiselier 190a9e65961SEric Fiselierstruct nullopt_t 191a9e65961SEric Fiselier{ 192a9e65961SEric Fiselier struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; }; 193a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {} 194a9e65961SEric Fiselier}; 195a9e65961SEric Fiselier 196a9e65961SEric Fiselier/* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}}; 197a9e65961SEric Fiselier 198a9e65961SEric Fiseliertemplate <class _Tp, bool = is_trivially_destructible<_Tp>::value> 199a9e65961SEric Fiselierstruct __optional_destruct_base; 200a9e65961SEric Fiselier 201a9e65961SEric Fiseliertemplate <class _Tp> 202a9e65961SEric Fiselierstruct __optional_destruct_base<_Tp, false> 203a9e65961SEric Fiselier{ 204a9e65961SEric Fiselier typedef _Tp value_type; 205a9e65961SEric Fiselier static_assert(is_object_v<value_type>, 206a9e65961SEric Fiselier "instantiation of optional with a non-object type is undefined behavior"); 207a9e65961SEric Fiselier union 208a9e65961SEric Fiselier { 209a9e65961SEric Fiselier char __null_state_; 210a9e65961SEric Fiselier value_type __val_; 211a9e65961SEric Fiselier }; 212a9e65961SEric Fiselier bool __engaged_; 213a9e65961SEric Fiselier 214a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 215a9e65961SEric Fiselier ~__optional_destruct_base() 216a9e65961SEric Fiselier { 217a9e65961SEric Fiselier if (__engaged_) 218a9e65961SEric Fiselier __val_.~value_type(); 219a9e65961SEric Fiselier } 220a9e65961SEric Fiselier 221a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 222a9e65961SEric Fiselier constexpr __optional_destruct_base() noexcept 223a9e65961SEric Fiselier : __null_state_(), 224a9e65961SEric Fiselier __engaged_(false) {} 225a9e65961SEric Fiselier 226a9e65961SEric Fiselier template <class... _Args> 227a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 228a9e65961SEric Fiselier constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) 229a9e65961SEric Fiselier : __val_(_VSTD::forward<_Args>(__args)...), 230a9e65961SEric Fiselier __engaged_(true) {} 231a9e65961SEric Fiselier 232a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 233a9e65961SEric Fiselier void reset() noexcept 234a9e65961SEric Fiselier { 235a9e65961SEric Fiselier if (__engaged_) 236a9e65961SEric Fiselier { 237a9e65961SEric Fiselier __val_.~value_type(); 238a9e65961SEric Fiselier __engaged_ = false; 239a9e65961SEric Fiselier } 240a9e65961SEric Fiselier } 241a9e65961SEric Fiselier}; 242a9e65961SEric Fiselier 243a9e65961SEric Fiseliertemplate <class _Tp> 244a9e65961SEric Fiselierstruct __optional_destruct_base<_Tp, true> 245a9e65961SEric Fiselier{ 246a9e65961SEric Fiselier typedef _Tp value_type; 247a9e65961SEric Fiselier static_assert(is_object_v<value_type>, 248a9e65961SEric Fiselier "instantiation of optional with a non-object type is undefined behavior"); 249a9e65961SEric Fiselier union 250a9e65961SEric Fiselier { 251a9e65961SEric Fiselier char __null_state_; 252a9e65961SEric Fiselier value_type __val_; 253a9e65961SEric Fiselier }; 254a9e65961SEric Fiselier bool __engaged_; 255a9e65961SEric Fiselier 256a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 257a9e65961SEric Fiselier constexpr __optional_destruct_base() noexcept 258a9e65961SEric Fiselier : __null_state_(), 259a9e65961SEric Fiselier __engaged_(false) {} 260a9e65961SEric Fiselier 261a9e65961SEric Fiselier template <class... _Args> 262a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 263a9e65961SEric Fiselier constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) 264a9e65961SEric Fiselier : __val_(_VSTD::forward<_Args>(__args)...), 265a9e65961SEric Fiselier __engaged_(true) {} 266a9e65961SEric Fiselier 267a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 268a9e65961SEric Fiselier void reset() noexcept 269a9e65961SEric Fiselier { 270a9e65961SEric Fiselier if (__engaged_) 271a9e65961SEric Fiselier { 272a9e65961SEric Fiselier __engaged_ = false; 273a9e65961SEric Fiselier } 274a9e65961SEric Fiselier } 275a9e65961SEric Fiselier}; 276a9e65961SEric Fiselier 277a9e65961SEric Fiseliertemplate <class _Tp, bool = is_reference<_Tp>::value> 278a9e65961SEric Fiselierstruct __optional_storage_base : __optional_destruct_base<_Tp> 279a9e65961SEric Fiselier{ 280a9e65961SEric Fiselier using __base = __optional_destruct_base<_Tp>; 281a9e65961SEric Fiselier using value_type = _Tp; 282a9e65961SEric Fiselier using __base::__base; 283a9e65961SEric Fiselier 284a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 285a9e65961SEric Fiselier constexpr bool has_value() const noexcept 286a9e65961SEric Fiselier { 287a9e65961SEric Fiselier return this->__engaged_; 288a9e65961SEric Fiselier } 289a9e65961SEric Fiselier 290a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 291a9e65961SEric Fiselier constexpr value_type& __get() & noexcept 292a9e65961SEric Fiselier { 293a9e65961SEric Fiselier return this->__val_; 294a9e65961SEric Fiselier } 295a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 296a9e65961SEric Fiselier constexpr const value_type& __get() const& noexcept 297a9e65961SEric Fiselier { 298a9e65961SEric Fiselier return this->__val_; 299a9e65961SEric Fiselier } 300a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 301a9e65961SEric Fiselier constexpr value_type&& __get() && noexcept 302a9e65961SEric Fiselier { 303a9e65961SEric Fiselier return _VSTD::move(this->__val_); 304a9e65961SEric Fiselier } 305a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 306a9e65961SEric Fiselier constexpr const value_type&& __get() const&& noexcept 307a9e65961SEric Fiselier { 308a9e65961SEric Fiselier return _VSTD::move(this->__val_); 309a9e65961SEric Fiselier } 310a9e65961SEric Fiselier 311a9e65961SEric Fiselier template <class... _Args> 312a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 313a9e65961SEric Fiselier void __construct(_Args&&... __args) 314a9e65961SEric Fiselier { 315a9e65961SEric Fiselier _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); 316a9e65961SEric Fiselier ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); 317a9e65961SEric Fiselier this->__engaged_ = true; 318a9e65961SEric Fiselier } 319a9e65961SEric Fiselier 320a9e65961SEric Fiselier template <class _That> 321a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 322a9e65961SEric Fiselier void __construct_from(_That&& __opt) 323a9e65961SEric Fiselier { 324a9e65961SEric Fiselier if (__opt.has_value()) 325a9e65961SEric Fiselier __construct(_VSTD::forward<_That>(__opt).__get()); 326a9e65961SEric Fiselier } 327a9e65961SEric Fiselier 328a9e65961SEric Fiselier template <class _That> 329a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 330a9e65961SEric Fiselier void __assign_from(_That&& __opt) 331a9e65961SEric Fiselier { 332a9e65961SEric Fiselier if (this->__engaged_ == __opt.has_value()) 333a9e65961SEric Fiselier { 334a9e65961SEric Fiselier if (this->__engaged_) 335a9e65961SEric Fiselier this->__val_ = _VSTD::forward<_That>(__opt).__get(); 336a9e65961SEric Fiselier } 337a9e65961SEric Fiselier else 338a9e65961SEric Fiselier { 339a9e65961SEric Fiselier if (this->__engaged_) 340a9e65961SEric Fiselier this->reset(); 341a9e65961SEric Fiselier else 342a9e65961SEric Fiselier __construct(_VSTD::forward<_That>(__opt).__get()); 343a9e65961SEric Fiselier } 344a9e65961SEric Fiselier } 345a9e65961SEric Fiselier}; 346a9e65961SEric Fiselier 347a9e65961SEric Fiselier// optional<T&> is currently required ill-formed, however it may to be in the 348a9e65961SEric Fiselier// future. For this reason it has already been implemented to ensure we can 349a9e65961SEric Fiselier// make the change in an ABI compatible manner. 350a9e65961SEric Fiseliertemplate <class _Tp> 351a9e65961SEric Fiselierstruct __optional_storage_base<_Tp, true> 352a9e65961SEric Fiselier{ 353a9e65961SEric Fiselier using value_type = _Tp; 354a9e65961SEric Fiselier using __raw_type = remove_reference_t<_Tp>; 355a9e65961SEric Fiselier __raw_type* __value_; 356a9e65961SEric Fiselier 357a9e65961SEric Fiselier template <class _Up> 358a9e65961SEric Fiselier static constexpr bool __can_bind_reference() { 359a9e65961SEric Fiselier using _RawUp = typename remove_reference<_Up>::type; 360a9e65961SEric Fiselier using _UpPtr = _RawUp*; 361a9e65961SEric Fiselier using _RawTp = typename remove_reference<_Tp>::type; 362a9e65961SEric Fiselier using _TpPtr = _RawTp*; 363a9e65961SEric Fiselier using _CheckLValueArg = integral_constant<bool, 364a9e65961SEric Fiselier (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) 365a9e65961SEric Fiselier || is_same<_RawUp, reference_wrapper<_RawTp>>::value 366a9e65961SEric Fiselier || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value 367a9e65961SEric Fiselier >; 368a9e65961SEric Fiselier return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) 369a9e65961SEric Fiselier || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value && 370a9e65961SEric Fiselier is_convertible<_UpPtr, _TpPtr>::value); 371a9e65961SEric Fiselier } 372a9e65961SEric Fiselier 373a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 374a9e65961SEric Fiselier constexpr __optional_storage_base() noexcept 375a9e65961SEric Fiselier : __value_(nullptr) {} 376a9e65961SEric Fiselier 377a9e65961SEric Fiselier template <class _UArg> 378a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 379a9e65961SEric Fiselier constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) 380a9e65961SEric Fiselier : __value_(_VSTD::addressof(__uarg)) 381a9e65961SEric Fiselier { 382a9e65961SEric Fiselier static_assert(__can_bind_reference<_UArg>(), 383a9e65961SEric Fiselier "Attempted to construct a reference element in tuple from a " 384a9e65961SEric Fiselier "possible temporary"); 385a9e65961SEric Fiselier } 386a9e65961SEric Fiselier 387a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 388a9e65961SEric Fiselier void reset() noexcept { __value_ = nullptr; } 389a9e65961SEric Fiselier 390a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 391a9e65961SEric Fiselier constexpr bool has_value() const noexcept 392a9e65961SEric Fiselier { return __value_ != nullptr; } 393a9e65961SEric Fiselier 394a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 395a9e65961SEric Fiselier constexpr value_type& __get() const& noexcept 396a9e65961SEric Fiselier { return *__value_; } 397a9e65961SEric Fiselier 398a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 399a9e65961SEric Fiselier constexpr value_type&& __get() const&& noexcept 400a9e65961SEric Fiselier { return _VSTD::forward<value_type>(*__value_); } 401a9e65961SEric Fiselier 402a9e65961SEric Fiselier template <class _UArg> 403a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 404a9e65961SEric Fiselier void __construct(_UArg&& __val) 405a9e65961SEric Fiselier { 406a9e65961SEric Fiselier _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); 407a9e65961SEric Fiselier static_assert(__can_bind_reference<_UArg>(), 408a9e65961SEric Fiselier "Attempted to construct a reference element in tuple from a " 409a9e65961SEric Fiselier "possible temporary"); 410a9e65961SEric Fiselier __value_ = _VSTD::addressof(__val); 411a9e65961SEric Fiselier } 412a9e65961SEric Fiselier 413a9e65961SEric Fiselier template <class _That> 414a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 415a9e65961SEric Fiselier void __construct_from(_That&& __opt) 416a9e65961SEric Fiselier { 417a9e65961SEric Fiselier if (__opt.has_value()) 418a9e65961SEric Fiselier __construct(_VSTD::forward<_That>(__opt).__get()); 419a9e65961SEric Fiselier } 420a9e65961SEric Fiselier 421a9e65961SEric Fiselier template <class _That> 422a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 423a9e65961SEric Fiselier void __assign_from(_That&& __opt) 424a9e65961SEric Fiselier { 425a9e65961SEric Fiselier if (has_value() == __opt.has_value()) 426a9e65961SEric Fiselier { 427a9e65961SEric Fiselier if (has_value()) 428a9e65961SEric Fiselier *__value_ = _VSTD::forward<_That>(__opt).__get(); 429a9e65961SEric Fiselier } 430a9e65961SEric Fiselier else 431a9e65961SEric Fiselier { 432a9e65961SEric Fiselier if (has_value()) 433a9e65961SEric Fiselier reset(); 434a9e65961SEric Fiselier else 435a9e65961SEric Fiselier __construct(_VSTD::forward<_That>(__opt).__get()); 436a9e65961SEric Fiselier } 437a9e65961SEric Fiselier } 438a9e65961SEric Fiselier}; 439a9e65961SEric Fiselier 440a9e65961SEric Fiseliertemplate <class _Tp, bool = is_trivially_copyable<_Tp>::value> 441a9e65961SEric Fiselierstruct __optional_storage; 442a9e65961SEric Fiselier 443a9e65961SEric Fiseliertemplate <class _Tp> 444a9e65961SEric Fiselierstruct __optional_storage<_Tp, true> : __optional_storage_base<_Tp> 445a9e65961SEric Fiselier{ 446a9e65961SEric Fiselier using __optional_storage_base<_Tp>::__optional_storage_base; 447a9e65961SEric Fiselier}; 448a9e65961SEric Fiselier 449a9e65961SEric Fiseliertemplate <class _Tp> 450a9e65961SEric Fiselierstruct __optional_storage<_Tp, false> : __optional_storage_base<_Tp> 451a9e65961SEric Fiselier{ 452a9e65961SEric Fiselier using value_type = _Tp; 453a9e65961SEric Fiselier using __optional_storage_base<_Tp>::__optional_storage_base; 454a9e65961SEric Fiselier 455a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 456a9e65961SEric Fiselier __optional_storage() = default; 457a9e65961SEric Fiselier 458a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 459a9e65961SEric Fiselier __optional_storage(const __optional_storage& __opt) 460a9e65961SEric Fiselier { 461a9e65961SEric Fiselier this->__construct_from(__opt); 462a9e65961SEric Fiselier } 463a9e65961SEric Fiselier 464a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 465a9e65961SEric Fiselier __optional_storage(__optional_storage&& __opt) 466a9e65961SEric Fiselier noexcept(is_nothrow_move_constructible_v<value_type>) 467a9e65961SEric Fiselier { 468a9e65961SEric Fiselier this->__construct_from(_VSTD::move(__opt)); 469a9e65961SEric Fiselier } 470a9e65961SEric Fiselier 471a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 472a9e65961SEric Fiselier __optional_storage& operator=(const __optional_storage& __opt) 473a9e65961SEric Fiselier { 474a9e65961SEric Fiselier this->__assign_from(__opt); 475a9e65961SEric Fiselier return *this; 476a9e65961SEric Fiselier } 477a9e65961SEric Fiselier 478a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 479a9e65961SEric Fiselier __optional_storage& operator=(__optional_storage&& __opt) 480a9e65961SEric Fiselier noexcept(is_nothrow_move_assignable_v<value_type> && 481a9e65961SEric Fiselier is_nothrow_move_constructible_v<value_type>) 482a9e65961SEric Fiselier { 483a9e65961SEric Fiselier this->__assign_from(_VSTD::move(__opt)); 484a9e65961SEric Fiselier return *this; 485a9e65961SEric Fiselier } 486a9e65961SEric Fiselier}; 487a9e65961SEric Fiselier 488a9e65961SEric Fiseliertemplate <class _Tp> 489a9e65961SEric Fiselierusing __optional_sfinae_ctor_base_t = __sfinae_ctor_base< 490a9e65961SEric Fiselier is_copy_constructible<_Tp>::value, 491a9e65961SEric Fiselier is_move_constructible<_Tp>::value 492a9e65961SEric Fiselier>; 493a9e65961SEric Fiselier 494a9e65961SEric Fiseliertemplate <class _Tp> 495a9e65961SEric Fiselierusing __optional_sfinae_assign_base_t = __sfinae_assign_base< 496a9e65961SEric Fiselier (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value), 497a9e65961SEric Fiselier (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) 498a9e65961SEric Fiselier>; 499a9e65961SEric Fiselier 500a9e65961SEric Fiseliertemplate <class _Tp> 501a9e65961SEric Fiselierclass optional 502a9e65961SEric Fiselier : private __optional_storage<_Tp> 503a9e65961SEric Fiselier , private __optional_sfinae_ctor_base_t<_Tp> 504a9e65961SEric Fiselier , private __optional_sfinae_assign_base_t<_Tp> 505a9e65961SEric Fiselier{ 506a9e65961SEric Fiselier using __base = __optional_storage<_Tp>; 507a9e65961SEric Fiselierpublic: 508a9e65961SEric Fiselier using value_type = _Tp; 509a9e65961SEric Fiselier 510a9e65961SEric Fiselierprivate: 511a9e65961SEric Fiselier // Disable the reference extension using this static assert. 512a9e65961SEric Fiselier static_assert(!is_same_v<value_type, in_place_t>, 513a9e65961SEric Fiselier "instantiation of optional with in_place_t is ill-formed"); 514a9e65961SEric Fiselier static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>, 515a9e65961SEric Fiselier "instantiation of optional with nullopt_t is ill-formed"); 516a9e65961SEric Fiselier static_assert(!is_reference_v<value_type>, 517a9e65961SEric Fiselier "instantiation of optional with a reference type is ill-formed"); 518a9e65961SEric Fiselier static_assert(is_destructible_v<value_type>, 519a9e65961SEric Fiselier "instantiation of optional with a non-destructible type is ill-formed"); 520a9e65961SEric Fiselier 521a9e65961SEric Fiselier // LWG2756: conditionally explicit conversion from _Up 522a9e65961SEric Fiselier struct _CheckOptionalArgsConstructor { 523a9e65961SEric Fiselier template <class _Up> 524a9e65961SEric Fiselier static constexpr bool __enable_implicit() { 525a9e65961SEric Fiselier return is_constructible_v<_Tp, _Up&&> && 526a9e65961SEric Fiselier is_convertible_v<_Up&&, _Tp>; 527a9e65961SEric Fiselier } 528a9e65961SEric Fiselier 529a9e65961SEric Fiselier template <class _Up> 530a9e65961SEric Fiselier static constexpr bool __enable_explicit() { 531a9e65961SEric Fiselier return is_constructible_v<_Tp, _Up&&> && 532a9e65961SEric Fiselier !is_convertible_v<_Up&&, _Tp>; 533a9e65961SEric Fiselier } 534a9e65961SEric Fiselier }; 535a9e65961SEric Fiselier template <class _Up> 536a9e65961SEric Fiselier using _CheckOptionalArgsCtor = conditional_t< 537a9e65961SEric Fiselier !is_same_v<in_place_t, _Up> && 538a9e65961SEric Fiselier !is_same_v<decay_t<_Up>, optional>, 539a9e65961SEric Fiselier _CheckOptionalArgsConstructor, 540a9e65961SEric Fiselier __check_tuple_constructor_fail 541a9e65961SEric Fiselier >; 542a9e65961SEric Fiselier template <class _QualUp> 543a9e65961SEric Fiselier struct _CheckOptionalLikeConstructor { 544a9e65961SEric Fiselier template <class _Up, class _Opt = optional<_Up>> 545a9e65961SEric Fiselier using __check_constructible_from_opt = __lazy_or< 546a9e65961SEric Fiselier is_constructible<_Tp, _Opt&>, 547a9e65961SEric Fiselier is_constructible<_Tp, _Opt const&>, 548a9e65961SEric Fiselier is_constructible<_Tp, _Opt&&>, 549a9e65961SEric Fiselier is_constructible<_Tp, _Opt const&&>, 550a9e65961SEric Fiselier is_convertible<_Opt&, _Tp>, 551a9e65961SEric Fiselier is_convertible<_Opt const&, _Tp>, 552a9e65961SEric Fiselier is_convertible<_Opt&&, _Tp>, 553a9e65961SEric Fiselier is_convertible<_Opt const&&, _Tp> 554a9e65961SEric Fiselier >; 555a9e65961SEric Fiselier template <class _Up, class _Opt = optional<_Up>> 556a9e65961SEric Fiselier using __check_assignable_from_opt = __lazy_or< 557a9e65961SEric Fiselier is_assignable<_Tp&, _Opt&>, 558a9e65961SEric Fiselier is_assignable<_Tp&, _Opt const&>, 559a9e65961SEric Fiselier is_assignable<_Tp&, _Opt&&>, 560a9e65961SEric Fiselier is_assignable<_Tp&, _Opt const&&> 561a9e65961SEric Fiselier >; 562a9e65961SEric Fiselier template <class _Up, class _QUp = _QualUp> 563a9e65961SEric Fiselier static constexpr bool __enable_implicit() { 564a9e65961SEric Fiselier return is_convertible<_QUp, _Tp>::value && 565a9e65961SEric Fiselier !__check_constructible_from_opt<_Up>::value; 566a9e65961SEric Fiselier } 567a9e65961SEric Fiselier template <class _Up, class _QUp = _QualUp> 568a9e65961SEric Fiselier static constexpr bool __enable_explicit() { 569a9e65961SEric Fiselier return !is_convertible<_QUp, _Tp>::value && 570a9e65961SEric Fiselier !__check_constructible_from_opt<_Up>::value; 571a9e65961SEric Fiselier } 572a9e65961SEric Fiselier template <class _Up, class _QUp = _QualUp> 573a9e65961SEric Fiselier static constexpr bool __enable_assign() { 574a9e65961SEric Fiselier // Construction and assignability of _Qup to _Tp has already been 575a9e65961SEric Fiselier // checked. 576a9e65961SEric Fiselier return !__check_constructible_from_opt<_Up>::value && 577a9e65961SEric Fiselier !__check_assignable_from_opt<_Up>::value; 578a9e65961SEric Fiselier } 579a9e65961SEric Fiselier }; 580a9e65961SEric Fiselier 581a9e65961SEric Fiselier template <class _Up, class _QualUp> 582a9e65961SEric Fiselier using _CheckOptionalLikeCtor = conditional_t< 583a9e65961SEric Fiselier __lazy_and< 584a9e65961SEric Fiselier __lazy_not<is_same<_Up, _Tp>>, 585a9e65961SEric Fiselier is_constructible<_Tp, _QualUp> 586a9e65961SEric Fiselier >::value, 587a9e65961SEric Fiselier _CheckOptionalLikeConstructor<_QualUp>, 588a9e65961SEric Fiselier __check_tuple_constructor_fail 589a9e65961SEric Fiselier >; 590a9e65961SEric Fiselier template <class _Up, class _QualUp> 591a9e65961SEric Fiselier using _CheckOptionalLikeAssign = conditional_t< 592a9e65961SEric Fiselier __lazy_and< 593a9e65961SEric Fiselier __lazy_not<is_same<_Up, _Tp>>, 594a9e65961SEric Fiselier is_constructible<_Tp, _QualUp>, 595a9e65961SEric Fiselier is_assignable<_Tp&, _QualUp> 596a9e65961SEric Fiselier >::value, 597a9e65961SEric Fiselier _CheckOptionalLikeConstructor<_QualUp>, 598a9e65961SEric Fiselier __check_tuple_constructor_fail 599a9e65961SEric Fiselier >; 600a9e65961SEric Fiselierpublic: 601a9e65961SEric Fiselier 602a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} 603a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; 604a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; 605a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} 606a9e65961SEric Fiselier 607a9e65961SEric Fiselier template <class... _Args, class = enable_if_t< 608a9e65961SEric Fiselier is_constructible_v<value_type, _Args...>> 609a9e65961SEric Fiselier > 610a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 611a9e65961SEric Fiselier constexpr explicit optional(in_place_t, _Args&&... __args) 612a9e65961SEric Fiselier : __base(in_place, _VSTD::forward<_Args>(__args)...) {} 613a9e65961SEric Fiselier 614a9e65961SEric Fiselier template <class _Up, class... _Args, class = enable_if_t< 615a9e65961SEric Fiselier is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> 616a9e65961SEric Fiselier > 617a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 618a9e65961SEric Fiselier constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 619a9e65961SEric Fiselier : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} 620a9e65961SEric Fiselier 621a9e65961SEric Fiselier template <class _Up = value_type, enable_if_t< 622a9e65961SEric Fiselier _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>() 623a9e65961SEric Fiselier , int> = 0> 624a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 625a9e65961SEric Fiselier constexpr optional(_Up&& __v) 626a9e65961SEric Fiselier : __base(in_place, _VSTD::forward<_Up>(__v)) {} 627a9e65961SEric Fiselier 628a9e65961SEric Fiselier template <class _Up, enable_if_t< 629a9e65961SEric Fiselier _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>() 630a9e65961SEric Fiselier , int> = 0> 631a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 632a9e65961SEric Fiselier constexpr explicit optional(_Up&& __v) 633a9e65961SEric Fiselier : __base(in_place, _VSTD::forward<_Up>(__v)) {} 634a9e65961SEric Fiselier 635a9e65961SEric Fiselier // LWG2756: conditionally explicit conversion from const optional<_Up>& 636a9e65961SEric Fiselier template <class _Up, enable_if_t< 637a9e65961SEric Fiselier _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>() 638a9e65961SEric Fiselier , int> = 0> 639a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 640a9e65961SEric Fiselier optional(const optional<_Up>& __v) 641a9e65961SEric Fiselier { 642a9e65961SEric Fiselier this->__construct_from(__v); 643a9e65961SEric Fiselier } 644a9e65961SEric Fiselier template <class _Up, enable_if_t< 645a9e65961SEric Fiselier _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>() 646a9e65961SEric Fiselier , int> = 0> 647a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 648a9e65961SEric Fiselier explicit optional(const optional<_Up>& __v) 649a9e65961SEric Fiselier { 650a9e65961SEric Fiselier this->__construct_from(__v); 651a9e65961SEric Fiselier } 652a9e65961SEric Fiselier 653a9e65961SEric Fiselier // LWG2756: conditionally explicit conversion from optional<_Up>&& 654a9e65961SEric Fiselier template <class _Up, enable_if_t< 655a9e65961SEric Fiselier _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>() 656a9e65961SEric Fiselier , int> = 0> 657a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 658a9e65961SEric Fiselier optional(optional<_Up>&& __v) 659a9e65961SEric Fiselier { 660a9e65961SEric Fiselier this->__construct_from(_VSTD::move(__v)); 661a9e65961SEric Fiselier } 662a9e65961SEric Fiselier template <class _Up, enable_if_t< 663a9e65961SEric Fiselier _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>() 664a9e65961SEric Fiselier , int> = 0> 665a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 666a9e65961SEric Fiselier explicit optional(optional<_Up>&& __v) 667a9e65961SEric Fiselier { 668a9e65961SEric Fiselier this->__construct_from(_VSTD::move(__v)); 669a9e65961SEric Fiselier } 670a9e65961SEric Fiselier 671a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 672a9e65961SEric Fiselier optional& operator=(nullopt_t) noexcept 673a9e65961SEric Fiselier { 674a9e65961SEric Fiselier reset(); 675a9e65961SEric Fiselier return *this; 676a9e65961SEric Fiselier } 677a9e65961SEric Fiselier 678a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default; 679a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default; 680a9e65961SEric Fiselier 681a9e65961SEric Fiselier // LWG2756 682a9e65961SEric Fiselier template <class _Up = value_type, 683a9e65961SEric Fiselier class = enable_if_t 684*015fcffdSEric Fiselier <__lazy_and< 685*015fcffdSEric Fiselier integral_constant<bool, 686*015fcffdSEric Fiselier !is_same_v<decay_t<_Up>, optional> && 687*015fcffdSEric Fiselier !(is_same_v<_Up, value_type> && is_scalar_v<value_type>) 688*015fcffdSEric Fiselier >, 689*015fcffdSEric Fiselier is_constructible<value_type, _Up>, 690*015fcffdSEric Fiselier is_assignable<value_type&, _Up> 691*015fcffdSEric Fiselier >::value> 692a9e65961SEric Fiselier > 693a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 694a9e65961SEric Fiselier optional& 695a9e65961SEric Fiselier operator=(_Up&& __v) 696a9e65961SEric Fiselier { 697a9e65961SEric Fiselier if (this->has_value()) 698a9e65961SEric Fiselier this->__get() = _VSTD::forward<_Up>(__v); 699a9e65961SEric Fiselier else 700a9e65961SEric Fiselier this->__construct(_VSTD::forward<_Up>(__v)); 701a9e65961SEric Fiselier return *this; 702a9e65961SEric Fiselier } 703a9e65961SEric Fiselier 704a9e65961SEric Fiselier // LWG2756 705a9e65961SEric Fiselier template <class _Up, enable_if_t< 706a9e65961SEric Fiselier _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>() 707a9e65961SEric Fiselier , int> = 0> 708a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 709a9e65961SEric Fiselier optional& 710a9e65961SEric Fiselier operator=(const optional<_Up>& __v) 711a9e65961SEric Fiselier { 712a9e65961SEric Fiselier this->__assign_from(__v); 713a9e65961SEric Fiselier return *this; 714a9e65961SEric Fiselier } 715a9e65961SEric Fiselier 716a9e65961SEric Fiselier // LWG2756 717a9e65961SEric Fiselier template <class _Up, enable_if_t< 718a9e65961SEric Fiselier _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>() 719a9e65961SEric Fiselier , int> = 0> 720a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 721a9e65961SEric Fiselier optional& 722a9e65961SEric Fiselier operator=(optional<_Up>&& __v) 723a9e65961SEric Fiselier { 724a9e65961SEric Fiselier this->__assign_from(_VSTD::move(__v)); 725a9e65961SEric Fiselier return *this; 726a9e65961SEric Fiselier } 727a9e65961SEric Fiselier 728a9e65961SEric Fiselier template <class... _Args, 729a9e65961SEric Fiselier class = enable_if_t 730a9e65961SEric Fiselier < 731a9e65961SEric Fiselier is_constructible_v<value_type, _Args...> 732a9e65961SEric Fiselier > 733a9e65961SEric Fiselier > 734a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 735a9e65961SEric Fiselier void 736a9e65961SEric Fiselier emplace(_Args&&... __args) 737a9e65961SEric Fiselier { 738a9e65961SEric Fiselier reset(); 739a9e65961SEric Fiselier this->__construct(_VSTD::forward<_Args>(__args)...); 740a9e65961SEric Fiselier } 741a9e65961SEric Fiselier 742a9e65961SEric Fiselier template <class _Up, class... _Args, 743a9e65961SEric Fiselier class = enable_if_t 744a9e65961SEric Fiselier < 745a9e65961SEric Fiselier is_constructible_v<value_type, initializer_list<_Up>&, _Args...> 746a9e65961SEric Fiselier > 747a9e65961SEric Fiselier > 748a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 749a9e65961SEric Fiselier void 750a9e65961SEric Fiselier emplace(initializer_list<_Up> __il, _Args&&... __args) 751a9e65961SEric Fiselier { 752a9e65961SEric Fiselier reset(); 753a9e65961SEric Fiselier this->__construct(__il, _VSTD::forward<_Args>(__args)...); 754a9e65961SEric Fiselier } 755a9e65961SEric Fiselier 756a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 757a9e65961SEric Fiselier void swap(optional& __opt) 758a9e65961SEric Fiselier noexcept(is_nothrow_move_constructible_v<value_type> && 759a9e65961SEric Fiselier is_nothrow_swappable_v<value_type>) 760a9e65961SEric Fiselier { 761a9e65961SEric Fiselier if (this->has_value() == __opt.has_value()) 762a9e65961SEric Fiselier { 763a9e65961SEric Fiselier using _VSTD::swap; 764a9e65961SEric Fiselier if (this->has_value()) 765a9e65961SEric Fiselier swap(this->__get(), __opt.__get()); 766a9e65961SEric Fiselier } 767a9e65961SEric Fiselier else 768a9e65961SEric Fiselier { 769a9e65961SEric Fiselier if (this->has_value()) 770a9e65961SEric Fiselier { 771a9e65961SEric Fiselier __opt.__construct(_VSTD::move(this->__get())); 772a9e65961SEric Fiselier reset(); 773a9e65961SEric Fiselier } 774a9e65961SEric Fiselier else 775a9e65961SEric Fiselier { 776a9e65961SEric Fiselier this->__construct(_VSTD::move(__opt.__get())); 777a9e65961SEric Fiselier __opt.reset(); 778a9e65961SEric Fiselier } 779a9e65961SEric Fiselier } 780a9e65961SEric Fiselier } 781a9e65961SEric Fiselier 782a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 783a9e65961SEric Fiselier constexpr 784a9e65961SEric Fiselier add_pointer_t<value_type const> 785a9e65961SEric Fiselier operator->() const 786a9e65961SEric Fiselier { 787a9e65961SEric Fiselier _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); 788a9e65961SEric Fiselier#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 789a9e65961SEric Fiselier return _VSTD::addressof(this->__get()); 790a9e65961SEric Fiselier#else 791a9e65961SEric Fiselier return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); 792a9e65961SEric Fiselier#endif 793a9e65961SEric Fiselier } 794a9e65961SEric Fiselier 795a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 796a9e65961SEric Fiselier constexpr 797a9e65961SEric Fiselier add_pointer_t<value_type> 798a9e65961SEric Fiselier operator->() 799a9e65961SEric Fiselier { 800a9e65961SEric Fiselier _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); 801a9e65961SEric Fiselier#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF 802a9e65961SEric Fiselier return _VSTD::addressof(this->__get()); 803a9e65961SEric Fiselier#else 804a9e65961SEric Fiselier return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); 805a9e65961SEric Fiselier#endif 806a9e65961SEric Fiselier } 807a9e65961SEric Fiselier 808a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 809a9e65961SEric Fiselier constexpr 810a9e65961SEric Fiselier const value_type& 811a9e65961SEric Fiselier operator*() const& 812a9e65961SEric Fiselier { 813a9e65961SEric Fiselier _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 814a9e65961SEric Fiselier return this->__get(); 815a9e65961SEric Fiselier } 816a9e65961SEric Fiselier 817a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 818a9e65961SEric Fiselier constexpr 819a9e65961SEric Fiselier value_type& 820a9e65961SEric Fiselier operator*() & 821a9e65961SEric Fiselier { 822a9e65961SEric Fiselier _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 823a9e65961SEric Fiselier return this->__get(); 824a9e65961SEric Fiselier } 825a9e65961SEric Fiselier 826a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 827a9e65961SEric Fiselier constexpr 828a9e65961SEric Fiselier value_type&& 829a9e65961SEric Fiselier operator*() && 830a9e65961SEric Fiselier { 831a9e65961SEric Fiselier _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 832a9e65961SEric Fiselier return _VSTD::move(this->__get()); 833a9e65961SEric Fiselier } 834a9e65961SEric Fiselier 835a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 836a9e65961SEric Fiselier constexpr 837a9e65961SEric Fiselier const value_type&& 838a9e65961SEric Fiselier operator*() const&& 839a9e65961SEric Fiselier { 840a9e65961SEric Fiselier _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); 841a9e65961SEric Fiselier return _VSTD::move(this->__get()); 842a9e65961SEric Fiselier } 843a9e65961SEric Fiselier 844a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 845a9e65961SEric Fiselier constexpr explicit operator bool() const noexcept { return has_value(); } 846a9e65961SEric Fiselier 847a9e65961SEric Fiselier using __base::has_value; 848a9e65961SEric Fiselier using __base::__get; 849a9e65961SEric Fiselier 850a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 851a9e65961SEric Fiselier constexpr value_type const& value() const& 852a9e65961SEric Fiselier { 853a9e65961SEric Fiselier if (!this->has_value()) 854a9e65961SEric Fiselier __throw_bad_optional_access(); 855a9e65961SEric Fiselier return this->__get(); 856a9e65961SEric Fiselier } 857a9e65961SEric Fiselier 858a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 859a9e65961SEric Fiselier constexpr value_type& value() & 860a9e65961SEric Fiselier { 861a9e65961SEric Fiselier if (!this->has_value()) 862a9e65961SEric Fiselier __throw_bad_optional_access(); 863a9e65961SEric Fiselier return this->__get(); 864a9e65961SEric Fiselier } 865a9e65961SEric Fiselier 866a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 867a9e65961SEric Fiselier constexpr value_type&& value() && 868a9e65961SEric Fiselier { 869a9e65961SEric Fiselier if (!this->has_value()) 870a9e65961SEric Fiselier __throw_bad_optional_access(); 871a9e65961SEric Fiselier return _VSTD::move(this->__get()); 872a9e65961SEric Fiselier } 873a9e65961SEric Fiselier 874a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 875a9e65961SEric Fiselier constexpr value_type const&& value() const&& 876a9e65961SEric Fiselier { 877a9e65961SEric Fiselier if (!this->has_value()) 878a9e65961SEric Fiselier __throw_bad_optional_access(); 879a9e65961SEric Fiselier return _VSTD::move(this->__get()); 880a9e65961SEric Fiselier } 881a9e65961SEric Fiselier 882a9e65961SEric Fiselier template <class _Up> 883a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 884a9e65961SEric Fiselier constexpr value_type value_or(_Up&& __v) const& 885a9e65961SEric Fiselier { 886a9e65961SEric Fiselier static_assert(is_copy_constructible_v<value_type>, 887a9e65961SEric Fiselier "optional<T>::value_or: T must be copy constructible"); 888a9e65961SEric Fiselier static_assert(is_convertible_v<_Up, value_type>, 889a9e65961SEric Fiselier "optional<T>::value_or: U must be convertible to T"); 890a9e65961SEric Fiselier return this->has_value() ? this->__get() : 891a9e65961SEric Fiselier static_cast<value_type>(_VSTD::forward<_Up>(__v)); 892a9e65961SEric Fiselier } 893a9e65961SEric Fiselier 894a9e65961SEric Fiselier template <class _Up> 895a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 896a9e65961SEric Fiselier value_type value_or(_Up&& __v) && 897a9e65961SEric Fiselier { 898a9e65961SEric Fiselier static_assert(is_move_constructible_v<value_type>, 899a9e65961SEric Fiselier "optional<T>::value_or: T must be move constructible"); 900a9e65961SEric Fiselier static_assert(is_convertible_v<_Up, value_type>, 901a9e65961SEric Fiselier "optional<T>::value_or: U must be convertible to T"); 902a9e65961SEric Fiselier return this->has_value() ? _VSTD::move(this->__get()) : 903a9e65961SEric Fiselier static_cast<value_type>(_VSTD::forward<_Up>(__v)); 904a9e65961SEric Fiselier } 905a9e65961SEric Fiselier 906a9e65961SEric Fiselier using __base::reset; 907a9e65961SEric Fiselier 908a9e65961SEric Fiselierprivate: 909a9e65961SEric Fiselier template <class _Up> 910a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 911a9e65961SEric Fiselier static _Up* 912a9e65961SEric Fiselier __operator_arrow(true_type, _Up& __x) 913a9e65961SEric Fiselier { 914a9e65961SEric Fiselier return _VSTD::addressof(__x); 915a9e65961SEric Fiselier } 916a9e65961SEric Fiselier 917a9e65961SEric Fiselier template <class _Up> 918a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 919a9e65961SEric Fiselier static constexpr _Up* 920a9e65961SEric Fiselier __operator_arrow(false_type, _Up& __x) 921a9e65961SEric Fiselier { 922a9e65961SEric Fiselier return &__x; 923a9e65961SEric Fiselier } 924a9e65961SEric Fiselier}; 925a9e65961SEric Fiselier 926a9e65961SEric Fiselier// Comparisons between optionals 927a9e65961SEric Fiseliertemplate <class _Tp> 928a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 929a9e65961SEric Fiselierenable_if_t< 930a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 931a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 932a9e65961SEric Fiselier bool 933a9e65961SEric Fiselier> 934a9e65961SEric Fiselieroperator==(const optional<_Tp>& __x, const optional<_Tp>& __y) 935a9e65961SEric Fiselier{ 936a9e65961SEric Fiselier if (static_cast<bool>(__x) != static_cast<bool>(__y)) 937a9e65961SEric Fiselier return false; 938a9e65961SEric Fiselier if (!static_cast<bool>(__x)) 939a9e65961SEric Fiselier return true; 940a9e65961SEric Fiselier return *__x == *__y; 941a9e65961SEric Fiselier} 942a9e65961SEric Fiselier 943a9e65961SEric Fiseliertemplate <class _Tp> 944a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 945a9e65961SEric Fiselierenable_if_t< 946a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 947a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 948a9e65961SEric Fiselier bool 949a9e65961SEric Fiselier> 950a9e65961SEric Fiselieroperator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) 951a9e65961SEric Fiselier{ 952a9e65961SEric Fiselier if (static_cast<bool>(__x) != static_cast<bool>(__y)) 953a9e65961SEric Fiselier return true; 954a9e65961SEric Fiselier if (!static_cast<bool>(__x)) 955a9e65961SEric Fiselier return false; 956a9e65961SEric Fiselier return *__x != *__y; 957a9e65961SEric Fiselier} 958a9e65961SEric Fiselier 959a9e65961SEric Fiseliertemplate <class _Tp> 960a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 961a9e65961SEric Fiselierenable_if_t< 962a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 963a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 964a9e65961SEric Fiselier bool 965a9e65961SEric Fiselier> 966a9e65961SEric Fiselieroperator<(const optional<_Tp>& __x, const optional<_Tp>& __y) 967a9e65961SEric Fiselier{ 968a9e65961SEric Fiselier if (!static_cast<bool>(__y)) 969a9e65961SEric Fiselier return false; 970a9e65961SEric Fiselier if (!static_cast<bool>(__x)) 971a9e65961SEric Fiselier return true; 972a9e65961SEric Fiselier return *__x < *__y; 973a9e65961SEric Fiselier} 974a9e65961SEric Fiselier 975a9e65961SEric Fiseliertemplate <class _Tp> 976a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 977a9e65961SEric Fiselierenable_if_t< 978a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 979a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 980a9e65961SEric Fiselier bool 981a9e65961SEric Fiselier> 982a9e65961SEric Fiselieroperator>(const optional<_Tp>& __x, const optional<_Tp>& __y) 983a9e65961SEric Fiselier{ 984a9e65961SEric Fiselier if (!static_cast<bool>(__x)) 985a9e65961SEric Fiselier return false; 986a9e65961SEric Fiselier if (!static_cast<bool>(__y)) 987a9e65961SEric Fiselier return true; 988a9e65961SEric Fiselier return *__x > *__y; 989a9e65961SEric Fiselier} 990a9e65961SEric Fiselier 991a9e65961SEric Fiseliertemplate <class _Tp> 992a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 993a9e65961SEric Fiselierenable_if_t< 994a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 995a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 996a9e65961SEric Fiselier bool 997a9e65961SEric Fiselier> 998a9e65961SEric Fiselieroperator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) 999a9e65961SEric Fiselier{ 1000a9e65961SEric Fiselier if (!static_cast<bool>(__x)) 1001a9e65961SEric Fiselier return true; 1002a9e65961SEric Fiselier if (!static_cast<bool>(__y)) 1003a9e65961SEric Fiselier return false; 1004a9e65961SEric Fiselier return *__x <= *__y; 1005a9e65961SEric Fiselier} 1006a9e65961SEric Fiselier 1007a9e65961SEric Fiseliertemplate <class _Tp> 1008a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1009a9e65961SEric Fiselierenable_if_t< 1010a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1011a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1012a9e65961SEric Fiselier bool 1013a9e65961SEric Fiselier> 1014a9e65961SEric Fiselieroperator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) 1015a9e65961SEric Fiselier{ 1016a9e65961SEric Fiselier if (!static_cast<bool>(__y)) 1017a9e65961SEric Fiselier return true; 1018a9e65961SEric Fiselier if (!static_cast<bool>(__x)) 1019a9e65961SEric Fiselier return false; 1020a9e65961SEric Fiselier return *__x >= *__y; 1021a9e65961SEric Fiselier} 1022a9e65961SEric Fiselier 1023a9e65961SEric Fiselier// Comparisons with nullopt 1024a9e65961SEric Fiseliertemplate <class _Tp> 1025a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1026a9e65961SEric Fiselierbool 1027a9e65961SEric Fiselieroperator==(const optional<_Tp>& __x, nullopt_t) noexcept 1028a9e65961SEric Fiselier{ 1029a9e65961SEric Fiselier return !static_cast<bool>(__x); 1030a9e65961SEric Fiselier} 1031a9e65961SEric Fiselier 1032a9e65961SEric Fiseliertemplate <class _Tp> 1033a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1034a9e65961SEric Fiselierbool 1035a9e65961SEric Fiselieroperator==(nullopt_t, const optional<_Tp>& __x) noexcept 1036a9e65961SEric Fiselier{ 1037a9e65961SEric Fiselier return !static_cast<bool>(__x); 1038a9e65961SEric Fiselier} 1039a9e65961SEric Fiselier 1040a9e65961SEric Fiseliertemplate <class _Tp> 1041a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1042a9e65961SEric Fiselierbool 1043a9e65961SEric Fiselieroperator!=(const optional<_Tp>& __x, nullopt_t) noexcept 1044a9e65961SEric Fiselier{ 1045a9e65961SEric Fiselier return static_cast<bool>(__x); 1046a9e65961SEric Fiselier} 1047a9e65961SEric Fiselier 1048a9e65961SEric Fiseliertemplate <class _Tp> 1049a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1050a9e65961SEric Fiselierbool 1051a9e65961SEric Fiselieroperator!=(nullopt_t, const optional<_Tp>& __x) noexcept 1052a9e65961SEric Fiselier{ 1053a9e65961SEric Fiselier return static_cast<bool>(__x); 1054a9e65961SEric Fiselier} 1055a9e65961SEric Fiselier 1056a9e65961SEric Fiseliertemplate <class _Tp> 1057a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1058a9e65961SEric Fiselierbool 1059a9e65961SEric Fiselieroperator<(const optional<_Tp>&, nullopt_t) noexcept 1060a9e65961SEric Fiselier{ 1061a9e65961SEric Fiselier return false; 1062a9e65961SEric Fiselier} 1063a9e65961SEric Fiselier 1064a9e65961SEric Fiseliertemplate <class _Tp> 1065a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1066a9e65961SEric Fiselierbool 1067a9e65961SEric Fiselieroperator<(nullopt_t, const optional<_Tp>& __x) noexcept 1068a9e65961SEric Fiselier{ 1069a9e65961SEric Fiselier return static_cast<bool>(__x); 1070a9e65961SEric Fiselier} 1071a9e65961SEric Fiselier 1072a9e65961SEric Fiseliertemplate <class _Tp> 1073a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1074a9e65961SEric Fiselierbool 1075a9e65961SEric Fiselieroperator<=(const optional<_Tp>& __x, nullopt_t) noexcept 1076a9e65961SEric Fiselier{ 1077a9e65961SEric Fiselier return !static_cast<bool>(__x); 1078a9e65961SEric Fiselier} 1079a9e65961SEric Fiselier 1080a9e65961SEric Fiseliertemplate <class _Tp> 1081a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1082a9e65961SEric Fiselierbool 1083a9e65961SEric Fiselieroperator<=(nullopt_t, const optional<_Tp>& __x) noexcept 1084a9e65961SEric Fiselier{ 1085a9e65961SEric Fiselier return true; 1086a9e65961SEric Fiselier} 1087a9e65961SEric Fiselier 1088a9e65961SEric Fiseliertemplate <class _Tp> 1089a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1090a9e65961SEric Fiselierbool 1091a9e65961SEric Fiselieroperator>(const optional<_Tp>& __x, nullopt_t) noexcept 1092a9e65961SEric Fiselier{ 1093a9e65961SEric Fiselier return static_cast<bool>(__x); 1094a9e65961SEric Fiselier} 1095a9e65961SEric Fiselier 1096a9e65961SEric Fiseliertemplate <class _Tp> 1097a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1098a9e65961SEric Fiselierbool 1099a9e65961SEric Fiselieroperator>(nullopt_t, const optional<_Tp>& __x) noexcept 1100a9e65961SEric Fiselier{ 1101a9e65961SEric Fiselier return false; 1102a9e65961SEric Fiselier} 1103a9e65961SEric Fiselier 1104a9e65961SEric Fiseliertemplate <class _Tp> 1105a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1106a9e65961SEric Fiselierbool 1107a9e65961SEric Fiselieroperator>=(const optional<_Tp>&, nullopt_t) noexcept 1108a9e65961SEric Fiselier{ 1109a9e65961SEric Fiselier return true; 1110a9e65961SEric Fiselier} 1111a9e65961SEric Fiselier 1112a9e65961SEric Fiseliertemplate <class _Tp> 1113a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1114a9e65961SEric Fiselierbool 1115a9e65961SEric Fiselieroperator>=(nullopt_t, const optional<_Tp>& __x) noexcept 1116a9e65961SEric Fiselier{ 1117a9e65961SEric Fiselier return !static_cast<bool>(__x); 1118a9e65961SEric Fiselier} 1119a9e65961SEric Fiselier 1120a9e65961SEric Fiselier// Comparisons with T 1121a9e65961SEric Fiseliertemplate <class _Tp> 1122a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1123a9e65961SEric Fiselierenable_if_t< 1124a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1125a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1126a9e65961SEric Fiselier bool 1127a9e65961SEric Fiselier> 1128a9e65961SEric Fiselieroperator==(const optional<_Tp>& __x, const _Tp& __v) 1129a9e65961SEric Fiselier{ 1130a9e65961SEric Fiselier return static_cast<bool>(__x) ? *__x == __v : false; 1131a9e65961SEric Fiselier} 1132a9e65961SEric Fiselier 1133a9e65961SEric Fiseliertemplate <class _Tp> 1134a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1135a9e65961SEric Fiselierenable_if_t< 1136a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == 1137a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1138a9e65961SEric Fiselier bool 1139a9e65961SEric Fiselier> 1140a9e65961SEric Fiselieroperator==(const _Tp& __v, const optional<_Tp>& __x) 1141a9e65961SEric Fiselier{ 1142a9e65961SEric Fiselier return static_cast<bool>(__x) ? __v == *__x : false; 1143a9e65961SEric Fiselier} 1144a9e65961SEric Fiselier 1145a9e65961SEric Fiseliertemplate <class _Tp> 1146a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1147a9e65961SEric Fiselierenable_if_t< 1148a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1149a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1150a9e65961SEric Fiselier bool 1151a9e65961SEric Fiselier> 1152a9e65961SEric Fiselieroperator!=(const optional<_Tp>& __x, const _Tp& __v) 1153a9e65961SEric Fiselier{ 1154a9e65961SEric Fiselier return static_cast<bool>(__x) ? *__x != __v : true; 1155a9e65961SEric Fiselier} 1156a9e65961SEric Fiselier 1157a9e65961SEric Fiseliertemplate <class _Tp> 1158a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1159a9e65961SEric Fiselierenable_if_t< 1160a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != 1161a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1162a9e65961SEric Fiselier bool 1163a9e65961SEric Fiselier> 1164a9e65961SEric Fiselieroperator!=(const _Tp& __v, const optional<_Tp>& __x) 1165a9e65961SEric Fiselier{ 1166a9e65961SEric Fiselier return static_cast<bool>(__x) ? __v != *__x : true; 1167a9e65961SEric Fiselier} 1168a9e65961SEric Fiselier 1169a9e65961SEric Fiseliertemplate <class _Tp> 1170a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1171a9e65961SEric Fiselierenable_if_t< 1172a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1173a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1174a9e65961SEric Fiselier bool 1175a9e65961SEric Fiselier> 1176a9e65961SEric Fiselieroperator<(const optional<_Tp>& __x, const _Tp& __v) 1177a9e65961SEric Fiselier{ 1178a9e65961SEric Fiselier return static_cast<bool>(__x) ? *__x < __v : true; 1179a9e65961SEric Fiselier} 1180a9e65961SEric Fiselier 1181a9e65961SEric Fiseliertemplate <class _Tp> 1182a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1183a9e65961SEric Fiselierenable_if_t< 1184a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < 1185a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1186a9e65961SEric Fiselier bool 1187a9e65961SEric Fiselier> 1188a9e65961SEric Fiselieroperator<(const _Tp& __v, const optional<_Tp>& __x) 1189a9e65961SEric Fiselier{ 1190a9e65961SEric Fiselier return static_cast<bool>(__x) ? __v < *__x : false; 1191a9e65961SEric Fiselier} 1192a9e65961SEric Fiselier 1193a9e65961SEric Fiseliertemplate <class _Tp> 1194a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1195a9e65961SEric Fiselierenable_if_t< 1196a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1197a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1198a9e65961SEric Fiselier bool 1199a9e65961SEric Fiselier> 1200a9e65961SEric Fiselieroperator<=(const optional<_Tp>& __x, const _Tp& __v) 1201a9e65961SEric Fiselier{ 1202a9e65961SEric Fiselier return static_cast<bool>(__x) ? *__x <= __v : true; 1203a9e65961SEric Fiselier} 1204a9e65961SEric Fiselier 1205a9e65961SEric Fiseliertemplate <class _Tp> 1206a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1207a9e65961SEric Fiselierenable_if_t< 1208a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= 1209a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1210a9e65961SEric Fiselier bool 1211a9e65961SEric Fiselier> 1212a9e65961SEric Fiselieroperator<=(const _Tp& __v, const optional<_Tp>& __x) 1213a9e65961SEric Fiselier{ 1214a9e65961SEric Fiselier return static_cast<bool>(__x) ? __v <= *__x : false; 1215a9e65961SEric Fiselier} 1216a9e65961SEric Fiselier 1217a9e65961SEric Fiseliertemplate <class _Tp> 1218a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1219a9e65961SEric Fiselierenable_if_t< 1220a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1221a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1222a9e65961SEric Fiselier bool 1223a9e65961SEric Fiselier> 1224a9e65961SEric Fiselieroperator>(const optional<_Tp>& __x, const _Tp& __v) 1225a9e65961SEric Fiselier{ 1226a9e65961SEric Fiselier return static_cast<bool>(__x) ? *__x > __v : false; 1227a9e65961SEric Fiselier} 1228a9e65961SEric Fiselier 1229a9e65961SEric Fiseliertemplate <class _Tp> 1230a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1231a9e65961SEric Fiselierenable_if_t< 1232a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > 1233a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1234a9e65961SEric Fiselier bool 1235a9e65961SEric Fiselier> 1236a9e65961SEric Fiselieroperator>(const _Tp& __v, const optional<_Tp>& __x) 1237a9e65961SEric Fiselier{ 1238a9e65961SEric Fiselier return static_cast<bool>(__x) ? __v > *__x : true; 1239a9e65961SEric Fiselier} 1240a9e65961SEric Fiselier 1241a9e65961SEric Fiseliertemplate <class _Tp> 1242a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1243a9e65961SEric Fiselierenable_if_t< 1244a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1245a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1246a9e65961SEric Fiselier bool 1247a9e65961SEric Fiselier> 1248a9e65961SEric Fiselieroperator>=(const optional<_Tp>& __x, const _Tp& __v) 1249a9e65961SEric Fiselier{ 1250a9e65961SEric Fiselier return static_cast<bool>(__x) ? *__x >= __v : false; 1251a9e65961SEric Fiselier} 1252a9e65961SEric Fiselier 1253a9e65961SEric Fiseliertemplate <class _Tp> 1254a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1255a9e65961SEric Fiselierenable_if_t< 1256a9e65961SEric Fiselier is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= 1257a9e65961SEric Fiselier _VSTD::declval<const _Tp&>()), bool>, 1258a9e65961SEric Fiselier bool 1259a9e65961SEric Fiselier> 1260a9e65961SEric Fiselieroperator>=(const _Tp& __v, const optional<_Tp>& __x) 1261a9e65961SEric Fiselier{ 1262a9e65961SEric Fiselier return static_cast<bool>(__x) ? __v >= *__x : true; 1263a9e65961SEric Fiselier} 1264a9e65961SEric Fiselier 1265a9e65961SEric Fiselier 1266a9e65961SEric Fiseliertemplate <class _Tp> 1267a9e65961SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 1268a9e65961SEric Fiselierenable_if_t< 1269a9e65961SEric Fiselier is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, 1270a9e65961SEric Fiselier void 1271a9e65961SEric Fiselier> 1272a9e65961SEric Fiselierswap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 1273a9e65961SEric Fiselier{ 1274a9e65961SEric Fiselier __x.swap(__y); 1275a9e65961SEric Fiselier} 1276a9e65961SEric Fiselier 1277a9e65961SEric Fiseliertemplate <class _Tp> 1278a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1279a9e65961SEric Fiselieroptional<decay_t<_Tp>> make_optional(_Tp&& __v) 1280a9e65961SEric Fiselier{ 1281a9e65961SEric Fiselier return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v)); 1282a9e65961SEric Fiselier} 1283a9e65961SEric Fiselier 1284a9e65961SEric Fiseliertemplate <class _Tp, class... _Args> 1285a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1286a9e65961SEric Fiselieroptional<_Tp> make_optional(_Args&&... __args) 1287a9e65961SEric Fiselier{ 1288a9e65961SEric Fiselier return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); 1289a9e65961SEric Fiselier} 1290a9e65961SEric Fiselier 1291a9e65961SEric Fiseliertemplate <class _Tp, class _Up, class... _Args> 1292a9e65961SEric Fiselier_LIBCPP_INLINE_VISIBILITY constexpr 1293a9e65961SEric Fiselieroptional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) 1294a9e65961SEric Fiselier{ 1295a9e65961SEric Fiselier return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...); 1296a9e65961SEric Fiselier} 1297a9e65961SEric Fiselier 1298a9e65961SEric Fiseliertemplate <class _Tp> 1299a9e65961SEric Fiselierstruct _LIBCPP_TYPE_VIS_ONLY hash<optional<_Tp> > 1300a9e65961SEric Fiselier{ 1301a9e65961SEric Fiselier typedef optional<_Tp> argument_type; 1302a9e65961SEric Fiselier typedef size_t result_type; 1303a9e65961SEric Fiselier 1304a9e65961SEric Fiselier _LIBCPP_INLINE_VISIBILITY 1305a9e65961SEric Fiselier result_type operator()(const argument_type& __opt) const _NOEXCEPT 1306a9e65961SEric Fiselier { 1307a9e65961SEric Fiselier return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0; 1308a9e65961SEric Fiselier } 1309a9e65961SEric Fiselier}; 1310a9e65961SEric Fiselier 1311a9e65961SEric Fiselier_LIBCPP_END_NAMESPACE_STD 1312a9e65961SEric Fiselier 1313a9e65961SEric Fiselier#endif // _LIBCPP_STD_VER > 14 1314a9e65961SEric Fiselier 1315a9e65961SEric Fiselier#endif // _LIBCPP_OPTIONAL 1316