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