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