146035553Spatrick// -*- C++ -*- 2*4bdff4beSrobert//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick#ifndef _LIBCPP_OPTIONAL 1146035553Spatrick#define _LIBCPP_OPTIONAL 1246035553Spatrick 1346035553Spatrick/* 1446035553Spatrick optional synopsis 1546035553Spatrick 1646035553Spatrick// C++1z 1746035553Spatrick 1846035553Spatricknamespace std { 1946035553Spatrick // 23.6.3, optional for object types 2046035553Spatrick template <class T> class optional; 2146035553Spatrick 2246035553Spatrick // 23.6.4, no-value state indicator 2346035553Spatrick struct nullopt_t{see below }; 2446035553Spatrick inline constexpr nullopt_t nullopt(unspecified ); 2546035553Spatrick 2646035553Spatrick // 23.6.5, class bad_optional_access 2746035553Spatrick class bad_optional_access; 2846035553Spatrick 2946035553Spatrick // 23.6.6, relational operators 3046035553Spatrick template <class T, class U> 3146035553Spatrick constexpr bool operator==(const optional<T>&, const optional<U>&); 3246035553Spatrick template <class T, class U> 3346035553Spatrick constexpr bool operator!=(const optional<T>&, const optional<U>&); 3446035553Spatrick template <class T, class U> 3546035553Spatrick constexpr bool operator<(const optional<T>&, const optional<U>&); 3646035553Spatrick template <class T, class U> 3746035553Spatrick constexpr bool operator>(const optional<T>&, const optional<U>&); 3846035553Spatrick template <class T, class U> 3946035553Spatrick constexpr bool operator<=(const optional<T>&, const optional<U>&); 4046035553Spatrick template <class T, class U> 4146035553Spatrick constexpr bool operator>=(const optional<T>&, const optional<U>&); 4246035553Spatrick 4346035553Spatrick // 23.6.7 comparison with nullopt 4446035553Spatrick template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; 4546035553Spatrick template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; 4646035553Spatrick template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; 4746035553Spatrick template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; 4846035553Spatrick template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; 4946035553Spatrick template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; 5046035553Spatrick template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; 5146035553Spatrick template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; 5246035553Spatrick template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; 5346035553Spatrick template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; 5446035553Spatrick template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; 5546035553Spatrick template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; 5646035553Spatrick 5746035553Spatrick // 23.6.8, comparison with T 5846035553Spatrick template <class T, class U> constexpr bool operator==(const optional<T>&, const U&); 5946035553Spatrick template <class T, class U> constexpr bool operator==(const T&, const optional<U>&); 6046035553Spatrick template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&); 6146035553Spatrick template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&); 6246035553Spatrick template <class T, class U> constexpr bool operator<(const optional<T>&, const U&); 6346035553Spatrick template <class T, class U> constexpr bool operator<(const T&, const optional<U>&); 6446035553Spatrick template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&); 6546035553Spatrick template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&); 6646035553Spatrick template <class T, class U> constexpr bool operator>(const optional<T>&, const U&); 6746035553Spatrick template <class T, class U> constexpr bool operator>(const T&, const optional<U>&); 6846035553Spatrick template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&); 6946035553Spatrick template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&); 7046035553Spatrick 7146035553Spatrick // 23.6.9, specialized algorithms 7276d0caaeSpatrick template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20 7346035553Spatrick template <class T> constexpr optional<see below > make_optional(T&&); 7446035553Spatrick template <class T, class... Args> 7546035553Spatrick constexpr optional<T> make_optional(Args&&... args); 7646035553Spatrick template <class T, class U, class... Args> 7746035553Spatrick constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); 7846035553Spatrick 7946035553Spatrick // 23.6.10, hash support 8046035553Spatrick template <class T> struct hash; 8146035553Spatrick template <class T> struct hash<optional<T>>; 8246035553Spatrick 8346035553Spatrick template <class T> class optional { 8446035553Spatrick public: 8546035553Spatrick using value_type = T; 8646035553Spatrick 8746035553Spatrick // 23.6.3.1, constructors 8846035553Spatrick constexpr optional() noexcept; 8946035553Spatrick constexpr optional(nullopt_t) noexcept; 90*4bdff4beSrobert constexpr optional(const optional &); 91*4bdff4beSrobert constexpr optional(optional &&) noexcept(see below); 9246035553Spatrick template <class... Args> constexpr explicit optional(in_place_t, Args &&...); 9346035553Spatrick template <class U, class... Args> 9446035553Spatrick constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...); 9546035553Spatrick template <class U = T> 96*4bdff4beSrobert constexpr explicit(see-below) optional(U &&); 9746035553Spatrick template <class U> 98*4bdff4beSrobert explicit(see-below) optional(const optional<U> &); // constexpr in C++20 9946035553Spatrick template <class U> 100*4bdff4beSrobert explicit(see-below) optional(optional<U> &&); // constexpr in C++20 10146035553Spatrick 10246035553Spatrick // 23.6.3.2, destructor 10376d0caaeSpatrick ~optional(); // constexpr in C++20 10446035553Spatrick 10546035553Spatrick // 23.6.3.3, assignment 10676d0caaeSpatrick optional &operator=(nullopt_t) noexcept; // constexpr in C++20 107*4bdff4beSrobert constexpr optional &operator=(const optional &); 108*4bdff4beSrobert constexpr optional &operator=(optional &&) noexcept(see below); 10976d0caaeSpatrick template <class U = T> optional &operator=(U &&); // constexpr in C++20 11076d0caaeSpatrick template <class U> optional &operator=(const optional<U> &); // constexpr in C++20 11176d0caaeSpatrick template <class U> optional &operator=(optional<U> &&); // constexpr in C++20 11276d0caaeSpatrick template <class... Args> T& emplace(Args &&...); // constexpr in C++20 11346035553Spatrick template <class U, class... Args> 11476d0caaeSpatrick T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20 11546035553Spatrick 11646035553Spatrick // 23.6.3.4, swap 11776d0caaeSpatrick void swap(optional &) noexcept(see below ); // constexpr in C++20 11846035553Spatrick 11946035553Spatrick // 23.6.3.5, observers 12046035553Spatrick constexpr T const *operator->() const; 12146035553Spatrick constexpr T *operator->(); 12246035553Spatrick constexpr T const &operator*() const &; 12346035553Spatrick constexpr T &operator*() &; 12446035553Spatrick constexpr T &&operator*() &&; 12546035553Spatrick constexpr const T &&operator*() const &&; 12646035553Spatrick constexpr explicit operator bool() const noexcept; 12746035553Spatrick constexpr bool has_value() const noexcept; 12846035553Spatrick constexpr T const &value() const &; 12946035553Spatrick constexpr T &value() &; 13046035553Spatrick constexpr T &&value() &&; 13146035553Spatrick constexpr const T &&value() const &&; 13246035553Spatrick template <class U> constexpr T value_or(U &&) const &; 13346035553Spatrick template <class U> constexpr T value_or(U &&) &&; 13446035553Spatrick 135*4bdff4beSrobert // [optional.monadic], monadic operations 136*4bdff4beSrobert template<class F> constexpr auto and_then(F&& f) &; // since C++23 137*4bdff4beSrobert template<class F> constexpr auto and_then(F&& f) &&; // since C++23 138*4bdff4beSrobert template<class F> constexpr auto and_then(F&& f) const&; // since C++23 139*4bdff4beSrobert template<class F> constexpr auto and_then(F&& f) const&&; // since C++23 140*4bdff4beSrobert template<class F> constexpr auto transform(F&& f) &; // since C++23 141*4bdff4beSrobert template<class F> constexpr auto transform(F&& f) &&; // since C++23 142*4bdff4beSrobert template<class F> constexpr auto transform(F&& f) const&; // since C++23 143*4bdff4beSrobert template<class F> constexpr auto transform(F&& f) const&&; // since C++23 144*4bdff4beSrobert template<class F> constexpr optional or_else(F&& f) &&; // since C++23 145*4bdff4beSrobert template<class F> constexpr optional or_else(F&& f) const&; // since C++23 146*4bdff4beSrobert 14746035553Spatrick // 23.6.3.6, modifiers 14876d0caaeSpatrick void reset() noexcept; // constexpr in C++20 14946035553Spatrick 15046035553Spatrick private: 15146035553Spatrick T *val; // exposition only 15246035553Spatrick }; 15346035553Spatrick 15446035553Spatricktemplate<class T> 15546035553Spatrick optional(T) -> optional<T>; 15646035553Spatrick 15746035553Spatrick} // namespace std 15846035553Spatrick 15946035553Spatrick*/ 16046035553Spatrick 161*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler 16276d0caaeSpatrick#include <__availability> 163*4bdff4beSrobert#include <__concepts/invocable.h> 16446035553Spatrick#include <__config> 165*4bdff4beSrobert#include <__functional/hash.h> 166*4bdff4beSrobert#include <__functional/invoke.h> 167*4bdff4beSrobert#include <__functional/unary_function.h> 168*4bdff4beSrobert#include <__memory/construct_at.h> 169*4bdff4beSrobert#include <__tuple_dir/sfinae_helpers.h> 170*4bdff4beSrobert#include <__utility/forward.h> 171*4bdff4beSrobert#include <__utility/in_place.h> 172*4bdff4beSrobert#include <__utility/move.h> 173*4bdff4beSrobert#include <__utility/swap.h> 17446035553Spatrick#include <initializer_list> 17546035553Spatrick#include <new> 17646035553Spatrick#include <stdexcept> 17746035553Spatrick#include <type_traits> 17846035553Spatrick#include <version> 17946035553Spatrick 180*4bdff4beSrobert// standard-mandated includes 181*4bdff4beSrobert 182*4bdff4beSrobert// [optional.syn] 183*4bdff4beSrobert#include <compare> 184*4bdff4beSrobert 18546035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18646035553Spatrick# pragma GCC system_header 18746035553Spatrick#endif 18846035553Spatrick 18946035553Spatricknamespace std // purposefully not using versioning namespace 19046035553Spatrick{ 19146035553Spatrick 19246035553Spatrickclass _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access 19346035553Spatrick : public exception 19446035553Spatrick{ 19546035553Spatrickpublic: 19646035553Spatrick // Get the key function ~bad_optional_access() into the dylib 197*4bdff4beSrobert ~bad_optional_access() _NOEXCEPT override; 198*4bdff4beSrobert const char* what() const _NOEXCEPT override; 19946035553Spatrick}; 20046035553Spatrick 201*4bdff4beSrobert} // namespace std 20246035553Spatrick 20346035553Spatrick#if _LIBCPP_STD_VER > 14 20446035553Spatrick 20546035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD 20646035553Spatrick 20746035553Spatrick_LIBCPP_NORETURN 20846035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 20946035553Spatrick_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 21046035553Spatrickvoid __throw_bad_optional_access() { 21146035553Spatrick#ifndef _LIBCPP_NO_EXCEPTIONS 21246035553Spatrick throw bad_optional_access(); 21346035553Spatrick#else 21446035553Spatrick _VSTD::abort(); 21546035553Spatrick#endif 21646035553Spatrick} 21746035553Spatrick 21846035553Spatrickstruct nullopt_t 21946035553Spatrick{ 22046035553Spatrick struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; }; 22146035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {} 22246035553Spatrick}; 22346035553Spatrick 224*4bdff4beSrobertinline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}}; 225*4bdff4beSrobert 226*4bdff4beSrobertstruct __optional_construct_from_invoke_tag {}; 22746035553Spatrick 22846035553Spatricktemplate <class _Tp, bool = is_trivially_destructible<_Tp>::value> 22946035553Spatrickstruct __optional_destruct_base; 23046035553Spatrick 23146035553Spatricktemplate <class _Tp> 23246035553Spatrickstruct __optional_destruct_base<_Tp, false> 23346035553Spatrick{ 23446035553Spatrick typedef _Tp value_type; 23546035553Spatrick static_assert(is_object_v<value_type>, 23646035553Spatrick "instantiation of optional with a non-object type is undefined behavior"); 23746035553Spatrick union 23846035553Spatrick { 23946035553Spatrick char __null_state_; 24046035553Spatrick value_type __val_; 24146035553Spatrick }; 24246035553Spatrick bool __engaged_; 24346035553Spatrick 24446035553Spatrick _LIBCPP_INLINE_VISIBILITY 245*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base() 24646035553Spatrick { 24746035553Spatrick if (__engaged_) 24846035553Spatrick __val_.~value_type(); 24946035553Spatrick } 25046035553Spatrick 25146035553Spatrick _LIBCPP_INLINE_VISIBILITY 25246035553Spatrick constexpr __optional_destruct_base() noexcept 25346035553Spatrick : __null_state_(), 25446035553Spatrick __engaged_(false) {} 25546035553Spatrick 25646035553Spatrick template <class... _Args> 25746035553Spatrick _LIBCPP_INLINE_VISIBILITY 25846035553Spatrick constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) 25946035553Spatrick : __val_(_VSTD::forward<_Args>(__args)...), 26046035553Spatrick __engaged_(true) {} 26146035553Spatrick 262*4bdff4beSrobert#if _LIBCPP_STD_VER > 20 263*4bdff4beSrobert template <class _Fp, class... _Args> 264*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 265*4bdff4beSrobert constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) 266*4bdff4beSrobert : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {} 267*4bdff4beSrobert#endif 268*4bdff4beSrobert 26946035553Spatrick _LIBCPP_INLINE_VISIBILITY 270*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept 27146035553Spatrick { 27246035553Spatrick if (__engaged_) 27346035553Spatrick { 27446035553Spatrick __val_.~value_type(); 27546035553Spatrick __engaged_ = false; 27646035553Spatrick } 27746035553Spatrick } 27846035553Spatrick}; 27946035553Spatrick 28046035553Spatricktemplate <class _Tp> 28146035553Spatrickstruct __optional_destruct_base<_Tp, true> 28246035553Spatrick{ 28346035553Spatrick typedef _Tp value_type; 28446035553Spatrick static_assert(is_object_v<value_type>, 28546035553Spatrick "instantiation of optional with a non-object type is undefined behavior"); 28646035553Spatrick union 28746035553Spatrick { 28846035553Spatrick char __null_state_; 28946035553Spatrick value_type __val_; 29046035553Spatrick }; 29146035553Spatrick bool __engaged_; 29246035553Spatrick 29346035553Spatrick _LIBCPP_INLINE_VISIBILITY 29446035553Spatrick constexpr __optional_destruct_base() noexcept 29546035553Spatrick : __null_state_(), 29646035553Spatrick __engaged_(false) {} 29746035553Spatrick 29846035553Spatrick template <class... _Args> 29946035553Spatrick _LIBCPP_INLINE_VISIBILITY 30046035553Spatrick constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) 30146035553Spatrick : __val_(_VSTD::forward<_Args>(__args)...), 30246035553Spatrick __engaged_(true) {} 30346035553Spatrick 304*4bdff4beSrobert#if _LIBCPP_STD_VER > 20 305*4bdff4beSrobert template <class _Fp, class... _Args> 306*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 307*4bdff4beSrobert constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) 308*4bdff4beSrobert : __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {} 309*4bdff4beSrobert#endif 310*4bdff4beSrobert 31146035553Spatrick _LIBCPP_INLINE_VISIBILITY 312*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept 31346035553Spatrick { 31446035553Spatrick if (__engaged_) 31546035553Spatrick { 31646035553Spatrick __engaged_ = false; 31746035553Spatrick } 31846035553Spatrick } 31946035553Spatrick}; 32046035553Spatrick 32146035553Spatricktemplate <class _Tp, bool = is_reference<_Tp>::value> 32246035553Spatrickstruct __optional_storage_base : __optional_destruct_base<_Tp> 32346035553Spatrick{ 32446035553Spatrick using __base = __optional_destruct_base<_Tp>; 32546035553Spatrick using value_type = _Tp; 32646035553Spatrick using __base::__base; 32746035553Spatrick 32846035553Spatrick _LIBCPP_INLINE_VISIBILITY 32946035553Spatrick constexpr bool has_value() const noexcept 33046035553Spatrick { 33146035553Spatrick return this->__engaged_; 33246035553Spatrick } 33346035553Spatrick 33446035553Spatrick _LIBCPP_INLINE_VISIBILITY 33546035553Spatrick constexpr value_type& __get() & noexcept 33646035553Spatrick { 33746035553Spatrick return this->__val_; 33846035553Spatrick } 33946035553Spatrick _LIBCPP_INLINE_VISIBILITY 34046035553Spatrick constexpr const value_type& __get() const& noexcept 34146035553Spatrick { 34246035553Spatrick return this->__val_; 34346035553Spatrick } 34446035553Spatrick _LIBCPP_INLINE_VISIBILITY 34546035553Spatrick constexpr value_type&& __get() && noexcept 34646035553Spatrick { 34746035553Spatrick return _VSTD::move(this->__val_); 34846035553Spatrick } 34946035553Spatrick _LIBCPP_INLINE_VISIBILITY 35046035553Spatrick constexpr const value_type&& __get() const&& noexcept 35146035553Spatrick { 35246035553Spatrick return _VSTD::move(this->__val_); 35346035553Spatrick } 35446035553Spatrick 35546035553Spatrick template <class... _Args> 35646035553Spatrick _LIBCPP_INLINE_VISIBILITY 357*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) 35846035553Spatrick { 35946035553Spatrick _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); 36076d0caaeSpatrick#if _LIBCPP_STD_VER > 17 36176d0caaeSpatrick _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...); 36276d0caaeSpatrick#else 36346035553Spatrick ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); 36476d0caaeSpatrick#endif 36546035553Spatrick this->__engaged_ = true; 36646035553Spatrick } 36746035553Spatrick 36846035553Spatrick template <class _That> 36946035553Spatrick _LIBCPP_INLINE_VISIBILITY 370*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) 37146035553Spatrick { 37246035553Spatrick if (__opt.has_value()) 37346035553Spatrick __construct(_VSTD::forward<_That>(__opt).__get()); 37446035553Spatrick } 37546035553Spatrick 37646035553Spatrick template <class _That> 37746035553Spatrick _LIBCPP_INLINE_VISIBILITY 378*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) 37946035553Spatrick { 38046035553Spatrick if (this->__engaged_ == __opt.has_value()) 38146035553Spatrick { 38246035553Spatrick if (this->__engaged_) 38346035553Spatrick this->__val_ = _VSTD::forward<_That>(__opt).__get(); 38446035553Spatrick } 38546035553Spatrick else 38646035553Spatrick { 38746035553Spatrick if (this->__engaged_) 38846035553Spatrick this->reset(); 38946035553Spatrick else 39046035553Spatrick __construct(_VSTD::forward<_That>(__opt).__get()); 39146035553Spatrick } 39246035553Spatrick } 39346035553Spatrick}; 39446035553Spatrick 395*4bdff4beSrobert// optional<T&> is currently required to be ill-formed. However, it may 396*4bdff4beSrobert// be allowed in the future. For this reason, it has already been implemented 397*4bdff4beSrobert// to ensure we can make the change in an ABI-compatible manner. 39846035553Spatricktemplate <class _Tp> 39946035553Spatrickstruct __optional_storage_base<_Tp, true> 40046035553Spatrick{ 40146035553Spatrick using value_type = _Tp; 40246035553Spatrick using __raw_type = remove_reference_t<_Tp>; 40346035553Spatrick __raw_type* __value_; 40446035553Spatrick 40546035553Spatrick template <class _Up> 40646035553Spatrick static constexpr bool __can_bind_reference() { 407*4bdff4beSrobert using _RawUp = __libcpp_remove_reference_t<_Up>; 40846035553Spatrick using _UpPtr = _RawUp*; 409*4bdff4beSrobert using _RawTp = __libcpp_remove_reference_t<_Tp>; 41046035553Spatrick using _TpPtr = _RawTp*; 41146035553Spatrick using _CheckLValueArg = integral_constant<bool, 41246035553Spatrick (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) 41346035553Spatrick || is_same<_RawUp, reference_wrapper<_RawTp>>::value 414*4bdff4beSrobert || is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value 41546035553Spatrick >; 41646035553Spatrick return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) 41746035553Spatrick || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value && 41846035553Spatrick is_convertible<_UpPtr, _TpPtr>::value); 41946035553Spatrick } 42046035553Spatrick 42146035553Spatrick _LIBCPP_INLINE_VISIBILITY 42246035553Spatrick constexpr __optional_storage_base() noexcept 42346035553Spatrick : __value_(nullptr) {} 42446035553Spatrick 42546035553Spatrick template <class _UArg> 42646035553Spatrick _LIBCPP_INLINE_VISIBILITY 42746035553Spatrick constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) 42846035553Spatrick : __value_(_VSTD::addressof(__uarg)) 42946035553Spatrick { 43046035553Spatrick static_assert(__can_bind_reference<_UArg>(), 43146035553Spatrick "Attempted to construct a reference element in tuple from a " 43246035553Spatrick "possible temporary"); 43346035553Spatrick } 43446035553Spatrick 43546035553Spatrick _LIBCPP_INLINE_VISIBILITY 436*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; } 43746035553Spatrick 43846035553Spatrick _LIBCPP_INLINE_VISIBILITY 43946035553Spatrick constexpr bool has_value() const noexcept 44046035553Spatrick { return __value_ != nullptr; } 44146035553Spatrick 44246035553Spatrick _LIBCPP_INLINE_VISIBILITY 44346035553Spatrick constexpr value_type& __get() const& noexcept 44446035553Spatrick { return *__value_; } 44546035553Spatrick 44646035553Spatrick _LIBCPP_INLINE_VISIBILITY 44746035553Spatrick constexpr value_type&& __get() const&& noexcept 44846035553Spatrick { return _VSTD::forward<value_type>(*__value_); } 44946035553Spatrick 45046035553Spatrick template <class _UArg> 45146035553Spatrick _LIBCPP_INLINE_VISIBILITY 452*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) 45346035553Spatrick { 45446035553Spatrick _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); 45546035553Spatrick static_assert(__can_bind_reference<_UArg>(), 45646035553Spatrick "Attempted to construct a reference element in tuple from a " 45746035553Spatrick "possible temporary"); 45846035553Spatrick __value_ = _VSTD::addressof(__val); 45946035553Spatrick } 46046035553Spatrick 46146035553Spatrick template <class _That> 46246035553Spatrick _LIBCPP_INLINE_VISIBILITY 463*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) 46446035553Spatrick { 46546035553Spatrick if (__opt.has_value()) 46646035553Spatrick __construct(_VSTD::forward<_That>(__opt).__get()); 46746035553Spatrick } 46846035553Spatrick 46946035553Spatrick template <class _That> 47046035553Spatrick _LIBCPP_INLINE_VISIBILITY 471*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) 47246035553Spatrick { 47346035553Spatrick if (has_value() == __opt.has_value()) 47446035553Spatrick { 47546035553Spatrick if (has_value()) 47646035553Spatrick *__value_ = _VSTD::forward<_That>(__opt).__get(); 47746035553Spatrick } 47846035553Spatrick else 47946035553Spatrick { 48046035553Spatrick if (has_value()) 48146035553Spatrick reset(); 48246035553Spatrick else 48346035553Spatrick __construct(_VSTD::forward<_That>(__opt).__get()); 48446035553Spatrick } 48546035553Spatrick } 48646035553Spatrick}; 48746035553Spatrick 48846035553Spatricktemplate <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value> 48946035553Spatrickstruct __optional_copy_base : __optional_storage_base<_Tp> 49046035553Spatrick{ 49146035553Spatrick using __optional_storage_base<_Tp>::__optional_storage_base; 49246035553Spatrick}; 49346035553Spatrick 49446035553Spatricktemplate <class _Tp> 49546035553Spatrickstruct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> 49646035553Spatrick{ 49746035553Spatrick using __optional_storage_base<_Tp>::__optional_storage_base; 49846035553Spatrick 49946035553Spatrick _LIBCPP_INLINE_VISIBILITY 50046035553Spatrick __optional_copy_base() = default; 50146035553Spatrick 50246035553Spatrick _LIBCPP_INLINE_VISIBILITY 503*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt) 50446035553Spatrick { 50546035553Spatrick this->__construct_from(__opt); 50646035553Spatrick } 50746035553Spatrick 50846035553Spatrick _LIBCPP_INLINE_VISIBILITY 50946035553Spatrick __optional_copy_base(__optional_copy_base&&) = default; 51046035553Spatrick _LIBCPP_INLINE_VISIBILITY 51146035553Spatrick __optional_copy_base& operator=(const __optional_copy_base&) = default; 51246035553Spatrick _LIBCPP_INLINE_VISIBILITY 51346035553Spatrick __optional_copy_base& operator=(__optional_copy_base&&) = default; 51446035553Spatrick}; 51546035553Spatrick 51646035553Spatricktemplate <class _Tp, bool = is_trivially_move_constructible<_Tp>::value> 51746035553Spatrickstruct __optional_move_base : __optional_copy_base<_Tp> 51846035553Spatrick{ 51946035553Spatrick using __optional_copy_base<_Tp>::__optional_copy_base; 52046035553Spatrick}; 52146035553Spatrick 52246035553Spatricktemplate <class _Tp> 52346035553Spatrickstruct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> 52446035553Spatrick{ 52546035553Spatrick using value_type = _Tp; 52646035553Spatrick using __optional_copy_base<_Tp>::__optional_copy_base; 52746035553Spatrick 52846035553Spatrick _LIBCPP_INLINE_VISIBILITY 52946035553Spatrick __optional_move_base() = default; 53046035553Spatrick _LIBCPP_INLINE_VISIBILITY 53146035553Spatrick __optional_move_base(const __optional_move_base&) = default; 53246035553Spatrick 53346035553Spatrick _LIBCPP_INLINE_VISIBILITY 534*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_base(__optional_move_base&& __opt) 53546035553Spatrick noexcept(is_nothrow_move_constructible_v<value_type>) 53646035553Spatrick { 53746035553Spatrick this->__construct_from(_VSTD::move(__opt)); 53846035553Spatrick } 53946035553Spatrick 54046035553Spatrick _LIBCPP_INLINE_VISIBILITY 54146035553Spatrick __optional_move_base& operator=(const __optional_move_base&) = default; 54246035553Spatrick _LIBCPP_INLINE_VISIBILITY 54346035553Spatrick __optional_move_base& operator=(__optional_move_base&&) = default; 54446035553Spatrick}; 54546035553Spatrick 54646035553Spatricktemplate <class _Tp, bool = 54746035553Spatrick is_trivially_destructible<_Tp>::value && 54846035553Spatrick is_trivially_copy_constructible<_Tp>::value && 54946035553Spatrick is_trivially_copy_assignable<_Tp>::value> 55046035553Spatrickstruct __optional_copy_assign_base : __optional_move_base<_Tp> 55146035553Spatrick{ 55246035553Spatrick using __optional_move_base<_Tp>::__optional_move_base; 55346035553Spatrick}; 55446035553Spatrick 55546035553Spatricktemplate <class _Tp> 55646035553Spatrickstruct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> 55746035553Spatrick{ 55846035553Spatrick using __optional_move_base<_Tp>::__optional_move_base; 55946035553Spatrick 56046035553Spatrick _LIBCPP_INLINE_VISIBILITY 56146035553Spatrick __optional_copy_assign_base() = default; 56246035553Spatrick _LIBCPP_INLINE_VISIBILITY 56346035553Spatrick __optional_copy_assign_base(const __optional_copy_assign_base&) = default; 56446035553Spatrick _LIBCPP_INLINE_VISIBILITY 56546035553Spatrick __optional_copy_assign_base(__optional_copy_assign_base&&) = default; 56646035553Spatrick 56746035553Spatrick _LIBCPP_INLINE_VISIBILITY 568*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt) 56946035553Spatrick { 57046035553Spatrick this->__assign_from(__opt); 57146035553Spatrick return *this; 57246035553Spatrick } 57346035553Spatrick 57446035553Spatrick _LIBCPP_INLINE_VISIBILITY 57546035553Spatrick __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default; 57646035553Spatrick}; 57746035553Spatrick 57846035553Spatricktemplate <class _Tp, bool = 57946035553Spatrick is_trivially_destructible<_Tp>::value && 58046035553Spatrick is_trivially_move_constructible<_Tp>::value && 58146035553Spatrick is_trivially_move_assignable<_Tp>::value> 58246035553Spatrickstruct __optional_move_assign_base : __optional_copy_assign_base<_Tp> 58346035553Spatrick{ 58446035553Spatrick using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; 58546035553Spatrick}; 58646035553Spatrick 58746035553Spatricktemplate <class _Tp> 58846035553Spatrickstruct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> 58946035553Spatrick{ 59046035553Spatrick using value_type = _Tp; 59146035553Spatrick using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; 59246035553Spatrick 59346035553Spatrick _LIBCPP_INLINE_VISIBILITY 59446035553Spatrick __optional_move_assign_base() = default; 59546035553Spatrick _LIBCPP_INLINE_VISIBILITY 59646035553Spatrick __optional_move_assign_base(const __optional_move_assign_base& __opt) = default; 59746035553Spatrick _LIBCPP_INLINE_VISIBILITY 59846035553Spatrick __optional_move_assign_base(__optional_move_assign_base&&) = default; 59946035553Spatrick _LIBCPP_INLINE_VISIBILITY 60046035553Spatrick __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default; 60146035553Spatrick 60246035553Spatrick _LIBCPP_INLINE_VISIBILITY 603*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt) 60446035553Spatrick noexcept(is_nothrow_move_assignable_v<value_type> && 60546035553Spatrick is_nothrow_move_constructible_v<value_type>) 60646035553Spatrick { 60746035553Spatrick this->__assign_from(_VSTD::move(__opt)); 60846035553Spatrick return *this; 60946035553Spatrick } 61046035553Spatrick}; 61146035553Spatrick 61246035553Spatricktemplate <class _Tp> 61346035553Spatrickusing __optional_sfinae_ctor_base_t = __sfinae_ctor_base< 61446035553Spatrick is_copy_constructible<_Tp>::value, 61546035553Spatrick is_move_constructible<_Tp>::value 61646035553Spatrick>; 61746035553Spatrick 61846035553Spatricktemplate <class _Tp> 61946035553Spatrickusing __optional_sfinae_assign_base_t = __sfinae_assign_base< 62046035553Spatrick (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value), 62146035553Spatrick (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) 62246035553Spatrick>; 62346035553Spatrick 62446035553Spatricktemplate<class _Tp> 625*4bdff4beSrobertclass optional; 626*4bdff4beSroberttemplate <class _Tp> 627*4bdff4beSrobertstruct __is_std_optional : false_type {}; 628*4bdff4beSroberttemplate <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {}; 629*4bdff4beSrobert 630*4bdff4beSroberttemplate <class _Tp> 63146035553Spatrickclass optional 63246035553Spatrick : private __optional_move_assign_base<_Tp> 63346035553Spatrick , private __optional_sfinae_ctor_base_t<_Tp> 63446035553Spatrick , private __optional_sfinae_assign_base_t<_Tp> 63546035553Spatrick{ 63646035553Spatrick using __base = __optional_move_assign_base<_Tp>; 63746035553Spatrickpublic: 63846035553Spatrick using value_type = _Tp; 63946035553Spatrick 64046035553Spatrickprivate: 64146035553Spatrick // Disable the reference extension using this static assert. 642*4bdff4beSrobert static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>, 64346035553Spatrick "instantiation of optional with in_place_t is ill-formed"); 644*4bdff4beSrobert static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>, 64546035553Spatrick "instantiation of optional with nullopt_t is ill-formed"); 64646035553Spatrick static_assert(!is_reference_v<value_type>, 64746035553Spatrick "instantiation of optional with a reference type is ill-formed"); 64846035553Spatrick static_assert(is_destructible_v<value_type>, 64946035553Spatrick "instantiation of optional with a non-destructible type is ill-formed"); 65046035553Spatrick static_assert(!is_array_v<value_type>, 65146035553Spatrick "instantiation of optional with an array type is ill-formed"); 65246035553Spatrick 65346035553Spatrick // LWG2756: conditionally explicit conversion from _Up 65446035553Spatrick struct _CheckOptionalArgsConstructor { 65546035553Spatrick template <class _Up> 65646035553Spatrick static constexpr bool __enable_implicit() { 65746035553Spatrick return is_constructible_v<_Tp, _Up&&> && 65846035553Spatrick is_convertible_v<_Up&&, _Tp>; 65946035553Spatrick } 66046035553Spatrick 66146035553Spatrick template <class _Up> 66246035553Spatrick static constexpr bool __enable_explicit() { 66346035553Spatrick return is_constructible_v<_Tp, _Up&&> && 66446035553Spatrick !is_convertible_v<_Up&&, _Tp>; 66546035553Spatrick } 66646035553Spatrick }; 66746035553Spatrick template <class _Up> 66846035553Spatrick using _CheckOptionalArgsCtor = _If< 669*4bdff4beSrobert _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && 670*4bdff4beSrobert _IsNotSame<__remove_cvref_t<_Up>, optional>::value, 67146035553Spatrick _CheckOptionalArgsConstructor, 67246035553Spatrick __check_tuple_constructor_fail 67346035553Spatrick >; 67446035553Spatrick template <class _QualUp> 67546035553Spatrick struct _CheckOptionalLikeConstructor { 67646035553Spatrick template <class _Up, class _Opt = optional<_Up>> 67746035553Spatrick using __check_constructible_from_opt = _Or< 67846035553Spatrick is_constructible<_Tp, _Opt&>, 67946035553Spatrick is_constructible<_Tp, _Opt const&>, 68046035553Spatrick is_constructible<_Tp, _Opt&&>, 68146035553Spatrick is_constructible<_Tp, _Opt const&&>, 68246035553Spatrick is_convertible<_Opt&, _Tp>, 68346035553Spatrick is_convertible<_Opt const&, _Tp>, 68446035553Spatrick is_convertible<_Opt&&, _Tp>, 68546035553Spatrick is_convertible<_Opt const&&, _Tp> 68646035553Spatrick >; 68746035553Spatrick template <class _Up, class _Opt = optional<_Up>> 68846035553Spatrick using __check_assignable_from_opt = _Or< 68946035553Spatrick is_assignable<_Tp&, _Opt&>, 69046035553Spatrick is_assignable<_Tp&, _Opt const&>, 69146035553Spatrick is_assignable<_Tp&, _Opt&&>, 69246035553Spatrick is_assignable<_Tp&, _Opt const&&> 69346035553Spatrick >; 69446035553Spatrick template <class _Up, class _QUp = _QualUp> 69546035553Spatrick static constexpr bool __enable_implicit() { 69646035553Spatrick return is_convertible<_QUp, _Tp>::value && 69746035553Spatrick !__check_constructible_from_opt<_Up>::value; 69846035553Spatrick } 69946035553Spatrick template <class _Up, class _QUp = _QualUp> 70046035553Spatrick static constexpr bool __enable_explicit() { 70146035553Spatrick return !is_convertible<_QUp, _Tp>::value && 70246035553Spatrick !__check_constructible_from_opt<_Up>::value; 70346035553Spatrick } 70446035553Spatrick template <class _Up, class _QUp = _QualUp> 70546035553Spatrick static constexpr bool __enable_assign() { 70676d0caaeSpatrick // Construction and assignability of _QUp to _Tp has already been 70746035553Spatrick // checked. 70846035553Spatrick return !__check_constructible_from_opt<_Up>::value && 70946035553Spatrick !__check_assignable_from_opt<_Up>::value; 71046035553Spatrick } 71146035553Spatrick }; 71246035553Spatrick 71346035553Spatrick template <class _Up, class _QualUp> 71446035553Spatrick using _CheckOptionalLikeCtor = _If< 71546035553Spatrick _And< 71646035553Spatrick _IsNotSame<_Up, _Tp>, 71746035553Spatrick is_constructible<_Tp, _QualUp> 71846035553Spatrick >::value, 71946035553Spatrick _CheckOptionalLikeConstructor<_QualUp>, 72046035553Spatrick __check_tuple_constructor_fail 72146035553Spatrick >; 72246035553Spatrick template <class _Up, class _QualUp> 72346035553Spatrick using _CheckOptionalLikeAssign = _If< 72446035553Spatrick _And< 72546035553Spatrick _IsNotSame<_Up, _Tp>, 72646035553Spatrick is_constructible<_Tp, _QualUp>, 72746035553Spatrick is_assignable<_Tp&, _QualUp> 72846035553Spatrick >::value, 72946035553Spatrick _CheckOptionalLikeConstructor<_QualUp>, 73046035553Spatrick __check_tuple_constructor_fail 73146035553Spatrick >; 732*4bdff4beSrobert 73346035553Spatrickpublic: 73446035553Spatrick 73546035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} 73646035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default; 73746035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default; 73846035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} 73946035553Spatrick 740*4bdff4beSrobert template <class _InPlaceT, class... _Args, class = enable_if_t< 74146035553Spatrick _And< 74246035553Spatrick _IsSame<_InPlaceT, in_place_t>, 74346035553Spatrick is_constructible<value_type, _Args...> 74446035553Spatrick >::value 74546035553Spatrick > 74646035553Spatrick > 74746035553Spatrick _LIBCPP_INLINE_VISIBILITY 74846035553Spatrick constexpr explicit optional(_InPlaceT, _Args&&... __args) 74946035553Spatrick : __base(in_place, _VSTD::forward<_Args>(__args)...) {} 75046035553Spatrick 751*4bdff4beSrobert template <class _Up, class... _Args, class = enable_if_t< 75246035553Spatrick is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> 75346035553Spatrick > 75446035553Spatrick _LIBCPP_INLINE_VISIBILITY 75546035553Spatrick constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 75646035553Spatrick : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} 75746035553Spatrick 758*4bdff4beSrobert template <class _Up = value_type, enable_if_t< 75946035553Spatrick _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>() 76046035553Spatrick , int> = 0> 76146035553Spatrick _LIBCPP_INLINE_VISIBILITY 76246035553Spatrick constexpr optional(_Up&& __v) 76346035553Spatrick : __base(in_place, _VSTD::forward<_Up>(__v)) {} 76446035553Spatrick 765*4bdff4beSrobert template <class _Up, enable_if_t< 76646035553Spatrick _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>() 76746035553Spatrick , int> = 0> 76846035553Spatrick _LIBCPP_INLINE_VISIBILITY 76946035553Spatrick constexpr explicit optional(_Up&& __v) 77046035553Spatrick : __base(in_place, _VSTD::forward<_Up>(__v)) {} 77146035553Spatrick 77246035553Spatrick // LWG2756: conditionally explicit conversion from const optional<_Up>& 773*4bdff4beSrobert template <class _Up, enable_if_t< 77446035553Spatrick _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>() 77546035553Spatrick , int> = 0> 77646035553Spatrick _LIBCPP_INLINE_VISIBILITY 777*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) 77846035553Spatrick { 77946035553Spatrick this->__construct_from(__v); 78046035553Spatrick } 781*4bdff4beSrobert template <class _Up, enable_if_t< 78246035553Spatrick _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>() 78346035553Spatrick , int> = 0> 78446035553Spatrick _LIBCPP_INLINE_VISIBILITY 785*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) 78646035553Spatrick { 78746035553Spatrick this->__construct_from(__v); 78846035553Spatrick } 78946035553Spatrick 79046035553Spatrick // LWG2756: conditionally explicit conversion from optional<_Up>&& 791*4bdff4beSrobert template <class _Up, enable_if_t< 79246035553Spatrick _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>() 79346035553Spatrick , int> = 0> 79446035553Spatrick _LIBCPP_INLINE_VISIBILITY 795*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) 79646035553Spatrick { 79746035553Spatrick this->__construct_from(_VSTD::move(__v)); 79846035553Spatrick } 799*4bdff4beSrobert template <class _Up, enable_if_t< 80046035553Spatrick _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>() 80146035553Spatrick , int> = 0> 80246035553Spatrick _LIBCPP_INLINE_VISIBILITY 803*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) 80446035553Spatrick { 80546035553Spatrick this->__construct_from(_VSTD::move(__v)); 80646035553Spatrick } 80746035553Spatrick 808*4bdff4beSrobert#if _LIBCPP_STD_VER > 20 809*4bdff4beSrobert template<class _Fp, class... _Args> 810*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 811*4bdff4beSrobert constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) 812*4bdff4beSrobert : __base(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...) { 813*4bdff4beSrobert } 814*4bdff4beSrobert#endif 815*4bdff4beSrobert 81646035553Spatrick _LIBCPP_INLINE_VISIBILITY 817*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept 81846035553Spatrick { 81946035553Spatrick reset(); 82046035553Spatrick return *this; 82146035553Spatrick } 82246035553Spatrick 823*4bdff4beSrobert constexpr optional& operator=(const optional&) = default; 824*4bdff4beSrobert constexpr optional& operator=(optional&&) = default; 82546035553Spatrick 82646035553Spatrick // LWG2756 82746035553Spatrick template <class _Up = value_type, 828*4bdff4beSrobert class = enable_if_t< 82946035553Spatrick _And< 830*4bdff4beSrobert _IsNotSame<__remove_cvref_t<_Up>, optional>, 83146035553Spatrick _Or< 832*4bdff4beSrobert _IsNotSame<__remove_cvref_t<_Up>, value_type>, 83346035553Spatrick _Not<is_scalar<value_type>> 83446035553Spatrick >, 83546035553Spatrick is_constructible<value_type, _Up>, 83646035553Spatrick is_assignable<value_type&, _Up> 83746035553Spatrick >::value> 83846035553Spatrick > 83946035553Spatrick _LIBCPP_INLINE_VISIBILITY 840*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& 84146035553Spatrick operator=(_Up&& __v) 84246035553Spatrick { 84346035553Spatrick if (this->has_value()) 84446035553Spatrick this->__get() = _VSTD::forward<_Up>(__v); 84546035553Spatrick else 84646035553Spatrick this->__construct(_VSTD::forward<_Up>(__v)); 84746035553Spatrick return *this; 84846035553Spatrick } 84946035553Spatrick 85046035553Spatrick // LWG2756 851*4bdff4beSrobert template <class _Up, enable_if_t< 85246035553Spatrick _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>() 85346035553Spatrick , int> = 0> 85446035553Spatrick _LIBCPP_INLINE_VISIBILITY 855*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& 85646035553Spatrick operator=(const optional<_Up>& __v) 85746035553Spatrick { 85846035553Spatrick this->__assign_from(__v); 85946035553Spatrick return *this; 86046035553Spatrick } 86146035553Spatrick 86246035553Spatrick // LWG2756 863*4bdff4beSrobert template <class _Up, enable_if_t< 86446035553Spatrick _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>() 86546035553Spatrick , int> = 0> 86646035553Spatrick _LIBCPP_INLINE_VISIBILITY 867*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& 86846035553Spatrick operator=(optional<_Up>&& __v) 86946035553Spatrick { 87046035553Spatrick this->__assign_from(_VSTD::move(__v)); 87146035553Spatrick return *this; 87246035553Spatrick } 87346035553Spatrick 87446035553Spatrick template <class... _Args, 875*4bdff4beSrobert class = enable_if_t 87646035553Spatrick < 87746035553Spatrick is_constructible_v<value_type, _Args...> 87846035553Spatrick > 87946035553Spatrick > 88046035553Spatrick _LIBCPP_INLINE_VISIBILITY 881*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & 88246035553Spatrick emplace(_Args&&... __args) 88346035553Spatrick { 88446035553Spatrick reset(); 88546035553Spatrick this->__construct(_VSTD::forward<_Args>(__args)...); 88646035553Spatrick return this->__get(); 88746035553Spatrick } 88846035553Spatrick 88946035553Spatrick template <class _Up, class... _Args, 890*4bdff4beSrobert class = enable_if_t 89146035553Spatrick < 89246035553Spatrick is_constructible_v<value_type, initializer_list<_Up>&, _Args...> 89346035553Spatrick > 89446035553Spatrick > 89546035553Spatrick _LIBCPP_INLINE_VISIBILITY 896*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & 89746035553Spatrick emplace(initializer_list<_Up> __il, _Args&&... __args) 89846035553Spatrick { 89946035553Spatrick reset(); 90046035553Spatrick this->__construct(__il, _VSTD::forward<_Args>(__args)...); 90146035553Spatrick return this->__get(); 90246035553Spatrick } 90346035553Spatrick 90446035553Spatrick _LIBCPP_INLINE_VISIBILITY 905*4bdff4beSrobert _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional& __opt) 90646035553Spatrick noexcept(is_nothrow_move_constructible_v<value_type> && 90746035553Spatrick is_nothrow_swappable_v<value_type>) 90846035553Spatrick { 90946035553Spatrick if (this->has_value() == __opt.has_value()) 91046035553Spatrick { 91146035553Spatrick using _VSTD::swap; 91246035553Spatrick if (this->has_value()) 91346035553Spatrick swap(this->__get(), __opt.__get()); 91446035553Spatrick } 91546035553Spatrick else 91646035553Spatrick { 91746035553Spatrick if (this->has_value()) 91846035553Spatrick { 91946035553Spatrick __opt.__construct(_VSTD::move(this->__get())); 92046035553Spatrick reset(); 92146035553Spatrick } 92246035553Spatrick else 92346035553Spatrick { 92446035553Spatrick this->__construct(_VSTD::move(__opt.__get())); 92546035553Spatrick __opt.reset(); 92646035553Spatrick } 92746035553Spatrick } 92846035553Spatrick } 92946035553Spatrick 93046035553Spatrick _LIBCPP_INLINE_VISIBILITY 93146035553Spatrick constexpr 93246035553Spatrick add_pointer_t<value_type const> 93346035553Spatrick operator->() const 93446035553Spatrick { 93576d0caaeSpatrick _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value"); 93646035553Spatrick return _VSTD::addressof(this->__get()); 93746035553Spatrick } 93846035553Spatrick 93946035553Spatrick _LIBCPP_INLINE_VISIBILITY 94046035553Spatrick constexpr 94146035553Spatrick add_pointer_t<value_type> 94246035553Spatrick operator->() 94346035553Spatrick { 94476d0caaeSpatrick _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value"); 94546035553Spatrick return _VSTD::addressof(this->__get()); 94646035553Spatrick } 94746035553Spatrick 94846035553Spatrick _LIBCPP_INLINE_VISIBILITY 94946035553Spatrick constexpr 95046035553Spatrick const value_type& 95176d0caaeSpatrick operator*() const& noexcept 95246035553Spatrick { 95376d0caaeSpatrick _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); 95446035553Spatrick return this->__get(); 95546035553Spatrick } 95646035553Spatrick 95746035553Spatrick _LIBCPP_INLINE_VISIBILITY 95846035553Spatrick constexpr 95946035553Spatrick value_type& 96076d0caaeSpatrick operator*() & noexcept 96146035553Spatrick { 96276d0caaeSpatrick _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); 96346035553Spatrick return this->__get(); 96446035553Spatrick } 96546035553Spatrick 96646035553Spatrick _LIBCPP_INLINE_VISIBILITY 96746035553Spatrick constexpr 96846035553Spatrick value_type&& 96976d0caaeSpatrick operator*() && noexcept 97046035553Spatrick { 97176d0caaeSpatrick _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); 97246035553Spatrick return _VSTD::move(this->__get()); 97346035553Spatrick } 97446035553Spatrick 97546035553Spatrick _LIBCPP_INLINE_VISIBILITY 97646035553Spatrick constexpr 97746035553Spatrick const value_type&& 97876d0caaeSpatrick operator*() const&& noexcept 97946035553Spatrick { 98076d0caaeSpatrick _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); 98146035553Spatrick return _VSTD::move(this->__get()); 98246035553Spatrick } 98346035553Spatrick 98446035553Spatrick _LIBCPP_INLINE_VISIBILITY 98546035553Spatrick constexpr explicit operator bool() const noexcept { return has_value(); } 98646035553Spatrick 98746035553Spatrick using __base::has_value; 98846035553Spatrick using __base::__get; 98946035553Spatrick 99046035553Spatrick _LIBCPP_INLINE_VISIBILITY 99146035553Spatrick _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 99246035553Spatrick constexpr value_type const& value() const& 99346035553Spatrick { 99446035553Spatrick if (!this->has_value()) 99546035553Spatrick __throw_bad_optional_access(); 99646035553Spatrick return this->__get(); 99746035553Spatrick } 99846035553Spatrick 99946035553Spatrick _LIBCPP_INLINE_VISIBILITY 100046035553Spatrick _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 100146035553Spatrick constexpr value_type& value() & 100246035553Spatrick { 100346035553Spatrick if (!this->has_value()) 100446035553Spatrick __throw_bad_optional_access(); 100546035553Spatrick return this->__get(); 100646035553Spatrick } 100746035553Spatrick 100846035553Spatrick _LIBCPP_INLINE_VISIBILITY 100946035553Spatrick _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 101046035553Spatrick constexpr value_type&& value() && 101146035553Spatrick { 101246035553Spatrick if (!this->has_value()) 101346035553Spatrick __throw_bad_optional_access(); 101446035553Spatrick return _VSTD::move(this->__get()); 101546035553Spatrick } 101646035553Spatrick 101746035553Spatrick _LIBCPP_INLINE_VISIBILITY 101846035553Spatrick _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 101946035553Spatrick constexpr value_type const&& value() const&& 102046035553Spatrick { 102146035553Spatrick if (!this->has_value()) 102246035553Spatrick __throw_bad_optional_access(); 102346035553Spatrick return _VSTD::move(this->__get()); 102446035553Spatrick } 102546035553Spatrick 102646035553Spatrick template <class _Up> 102746035553Spatrick _LIBCPP_INLINE_VISIBILITY 102846035553Spatrick constexpr value_type value_or(_Up&& __v) const& 102946035553Spatrick { 103046035553Spatrick static_assert(is_copy_constructible_v<value_type>, 103146035553Spatrick "optional<T>::value_or: T must be copy constructible"); 103246035553Spatrick static_assert(is_convertible_v<_Up, value_type>, 103346035553Spatrick "optional<T>::value_or: U must be convertible to T"); 103446035553Spatrick return this->has_value() ? this->__get() : 103546035553Spatrick static_cast<value_type>(_VSTD::forward<_Up>(__v)); 103646035553Spatrick } 103746035553Spatrick 103846035553Spatrick template <class _Up> 103946035553Spatrick _LIBCPP_INLINE_VISIBILITY 104046035553Spatrick constexpr value_type value_or(_Up&& __v) && 104146035553Spatrick { 104246035553Spatrick static_assert(is_move_constructible_v<value_type>, 104346035553Spatrick "optional<T>::value_or: T must be move constructible"); 104446035553Spatrick static_assert(is_convertible_v<_Up, value_type>, 104546035553Spatrick "optional<T>::value_or: U must be convertible to T"); 104646035553Spatrick return this->has_value() ? _VSTD::move(this->__get()) : 104746035553Spatrick static_cast<value_type>(_VSTD::forward<_Up>(__v)); 104846035553Spatrick } 104946035553Spatrick 1050*4bdff4beSrobert#if _LIBCPP_STD_VER > 20 1051*4bdff4beSrobert template<class _Func> 1052*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1053*4bdff4beSrobert constexpr auto and_then(_Func&& __f) & { 1054*4bdff4beSrobert using _Up = invoke_result_t<_Func, value_type&>; 1055*4bdff4beSrobert static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, 1056*4bdff4beSrobert "Result of f(value()) must be a specialization of std::optional"); 1057*4bdff4beSrobert if (*this) 1058*4bdff4beSrobert return _VSTD::invoke(_VSTD::forward<_Func>(__f), value()); 1059*4bdff4beSrobert return remove_cvref_t<_Up>(); 1060*4bdff4beSrobert } 1061*4bdff4beSrobert 1062*4bdff4beSrobert template<class _Func> 1063*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1064*4bdff4beSrobert constexpr auto and_then(_Func&& __f) const& { 1065*4bdff4beSrobert using _Up = invoke_result_t<_Func, const value_type&>; 1066*4bdff4beSrobert static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, 1067*4bdff4beSrobert "Result of f(value()) must be a specialization of std::optional"); 1068*4bdff4beSrobert if (*this) 1069*4bdff4beSrobert return _VSTD::invoke(_VSTD::forward<_Func>(__f), value()); 1070*4bdff4beSrobert return remove_cvref_t<_Up>(); 1071*4bdff4beSrobert } 1072*4bdff4beSrobert 1073*4bdff4beSrobert template<class _Func> 1074*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1075*4bdff4beSrobert constexpr auto and_then(_Func&& __f) && { 1076*4bdff4beSrobert using _Up = invoke_result_t<_Func, value_type&&>; 1077*4bdff4beSrobert static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, 1078*4bdff4beSrobert "Result of f(std::move(value())) must be a specialization of std::optional"); 1079*4bdff4beSrobert if (*this) 1080*4bdff4beSrobert return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value())); 1081*4bdff4beSrobert return remove_cvref_t<_Up>(); 1082*4bdff4beSrobert } 1083*4bdff4beSrobert 1084*4bdff4beSrobert template<class _Func> 1085*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 1086*4bdff4beSrobert constexpr auto and_then(_Func&& __f) const&& { 1087*4bdff4beSrobert using _Up = invoke_result_t<_Func, const value_type&&>; 1088*4bdff4beSrobert static_assert(__is_std_optional<remove_cvref_t<_Up>>::value, 1089*4bdff4beSrobert "Result of f(std::move(value())) must be a specialization of std::optional"); 1090*4bdff4beSrobert if (*this) 1091*4bdff4beSrobert return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value())); 1092*4bdff4beSrobert return remove_cvref_t<_Up>(); 1093*4bdff4beSrobert } 1094*4bdff4beSrobert 1095*4bdff4beSrobert template<class _Func> 1096*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1097*4bdff4beSrobert constexpr auto transform(_Func&& __f) & { 1098*4bdff4beSrobert using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>; 1099*4bdff4beSrobert static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); 1100*4bdff4beSrobert static_assert(!is_same_v<_Up, in_place_t>, 1101*4bdff4beSrobert "Result of f(value()) should not be std::in_place_t"); 1102*4bdff4beSrobert static_assert(!is_same_v<_Up, nullopt_t>, 1103*4bdff4beSrobert "Result of f(value()) should not be std::nullopt_t"); 1104*4bdff4beSrobert static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type"); 1105*4bdff4beSrobert if (*this) 1106*4bdff4beSrobert return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value()); 1107*4bdff4beSrobert return optional<_Up>(); 1108*4bdff4beSrobert } 1109*4bdff4beSrobert 1110*4bdff4beSrobert template<class _Func> 1111*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1112*4bdff4beSrobert constexpr auto transform(_Func&& __f) const& { 1113*4bdff4beSrobert using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>; 1114*4bdff4beSrobert static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); 1115*4bdff4beSrobert static_assert(!is_same_v<_Up, in_place_t>, 1116*4bdff4beSrobert "Result of f(value()) should not be std::in_place_t"); 1117*4bdff4beSrobert static_assert(!is_same_v<_Up, nullopt_t>, 1118*4bdff4beSrobert "Result of f(value()) should not be std::nullopt_t"); 1119*4bdff4beSrobert static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type"); 1120*4bdff4beSrobert if (*this) 1121*4bdff4beSrobert return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value()); 1122*4bdff4beSrobert return optional<_Up>(); 1123*4bdff4beSrobert } 1124*4bdff4beSrobert 1125*4bdff4beSrobert template<class _Func> 1126*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1127*4bdff4beSrobert constexpr auto transform(_Func&& __f) && { 1128*4bdff4beSrobert using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>; 1129*4bdff4beSrobert static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array"); 1130*4bdff4beSrobert static_assert(!is_same_v<_Up, in_place_t>, 1131*4bdff4beSrobert "Result of f(std::move(value())) should not be std::in_place_t"); 1132*4bdff4beSrobert static_assert(!is_same_v<_Up, nullopt_t>, 1133*4bdff4beSrobert "Result of f(std::move(value())) should not be std::nullopt_t"); 1134*4bdff4beSrobert static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type"); 1135*4bdff4beSrobert if (*this) 1136*4bdff4beSrobert return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value())); 1137*4bdff4beSrobert return optional<_Up>(); 1138*4bdff4beSrobert } 1139*4bdff4beSrobert 1140*4bdff4beSrobert template<class _Func> 1141*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS 1142*4bdff4beSrobert constexpr auto transform(_Func&& __f) const&& { 1143*4bdff4beSrobert using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>; 1144*4bdff4beSrobert static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array"); 1145*4bdff4beSrobert static_assert(!is_same_v<_Up, in_place_t>, 1146*4bdff4beSrobert "Result of f(std::move(value())) should not be std::in_place_t"); 1147*4bdff4beSrobert static_assert(!is_same_v<_Up, nullopt_t>, 1148*4bdff4beSrobert "Result of f(std::move(value())) should not be std::nullopt_t"); 1149*4bdff4beSrobert static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type"); 1150*4bdff4beSrobert if (*this) 1151*4bdff4beSrobert return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value())); 1152*4bdff4beSrobert return optional<_Up>(); 1153*4bdff4beSrobert } 1154*4bdff4beSrobert 1155*4bdff4beSrobert template<invocable _Func> 1156*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 1157*4bdff4beSrobert constexpr optional or_else(_Func&& __f) const& requires is_copy_constructible_v<value_type> { 1158*4bdff4beSrobert static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>, 1159*4bdff4beSrobert "Result of f() should be the same type as this optional"); 1160*4bdff4beSrobert if (*this) 1161*4bdff4beSrobert return *this; 1162*4bdff4beSrobert return _VSTD::forward<_Func>(__f)(); 1163*4bdff4beSrobert } 1164*4bdff4beSrobert 1165*4bdff4beSrobert template<invocable _Func> 1166*4bdff4beSrobert _LIBCPP_HIDE_FROM_ABI 1167*4bdff4beSrobert constexpr optional or_else(_Func&& __f) && requires is_move_constructible_v<value_type> { 1168*4bdff4beSrobert static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>, 1169*4bdff4beSrobert "Result of f() should be the same type as this optional"); 1170*4bdff4beSrobert if (*this) 1171*4bdff4beSrobert return _VSTD::move(*this); 1172*4bdff4beSrobert return _VSTD::forward<_Func>(__f)(); 1173*4bdff4beSrobert } 1174*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 20 1175*4bdff4beSrobert 117646035553Spatrick using __base::reset; 117746035553Spatrick}; 117846035553Spatrick 1179*4bdff4beSrobert#if _LIBCPP_STD_VER >= 17 1180*4bdff4beSroberttemplate<class _Tp> 1181*4bdff4beSrobert optional(_Tp) -> optional<_Tp>; 118246035553Spatrick#endif 118346035553Spatrick 118446035553Spatrick// Comparisons between optionals 118546035553Spatricktemplate <class _Tp, class _Up> 118646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1187*4bdff4beSrobertenable_if_t< 1188*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() == 1189*4bdff4beSrobert std::declval<const _Up&>()), bool>, 119046035553Spatrick bool 119146035553Spatrick> 119246035553Spatrickoperator==(const optional<_Tp>& __x, const optional<_Up>& __y) 119346035553Spatrick{ 119446035553Spatrick if (static_cast<bool>(__x) != static_cast<bool>(__y)) 119546035553Spatrick return false; 119646035553Spatrick if (!static_cast<bool>(__x)) 119746035553Spatrick return true; 119846035553Spatrick return *__x == *__y; 119946035553Spatrick} 120046035553Spatrick 120146035553Spatricktemplate <class _Tp, class _Up> 120246035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1203*4bdff4beSrobertenable_if_t< 1204*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() != 1205*4bdff4beSrobert std::declval<const _Up&>()), bool>, 120646035553Spatrick bool 120746035553Spatrick> 120846035553Spatrickoperator!=(const optional<_Tp>& __x, const optional<_Up>& __y) 120946035553Spatrick{ 121046035553Spatrick if (static_cast<bool>(__x) != static_cast<bool>(__y)) 121146035553Spatrick return true; 121246035553Spatrick if (!static_cast<bool>(__x)) 121346035553Spatrick return false; 121446035553Spatrick return *__x != *__y; 121546035553Spatrick} 121646035553Spatrick 121746035553Spatricktemplate <class _Tp, class _Up> 121846035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1219*4bdff4beSrobertenable_if_t< 1220*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() < 1221*4bdff4beSrobert std::declval<const _Up&>()), bool>, 122246035553Spatrick bool 122346035553Spatrick> 122446035553Spatrickoperator<(const optional<_Tp>& __x, const optional<_Up>& __y) 122546035553Spatrick{ 122646035553Spatrick if (!static_cast<bool>(__y)) 122746035553Spatrick return false; 122846035553Spatrick if (!static_cast<bool>(__x)) 122946035553Spatrick return true; 123046035553Spatrick return *__x < *__y; 123146035553Spatrick} 123246035553Spatrick 123346035553Spatricktemplate <class _Tp, class _Up> 123446035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1235*4bdff4beSrobertenable_if_t< 1236*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() > 1237*4bdff4beSrobert std::declval<const _Up&>()), bool>, 123846035553Spatrick bool 123946035553Spatrick> 124046035553Spatrickoperator>(const optional<_Tp>& __x, const optional<_Up>& __y) 124146035553Spatrick{ 124246035553Spatrick if (!static_cast<bool>(__x)) 124346035553Spatrick return false; 124446035553Spatrick if (!static_cast<bool>(__y)) 124546035553Spatrick return true; 124646035553Spatrick return *__x > *__y; 124746035553Spatrick} 124846035553Spatrick 124946035553Spatricktemplate <class _Tp, class _Up> 125046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1251*4bdff4beSrobertenable_if_t< 1252*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() <= 1253*4bdff4beSrobert std::declval<const _Up&>()), bool>, 125446035553Spatrick bool 125546035553Spatrick> 125646035553Spatrickoperator<=(const optional<_Tp>& __x, const optional<_Up>& __y) 125746035553Spatrick{ 125846035553Spatrick if (!static_cast<bool>(__x)) 125946035553Spatrick return true; 126046035553Spatrick if (!static_cast<bool>(__y)) 126146035553Spatrick return false; 126246035553Spatrick return *__x <= *__y; 126346035553Spatrick} 126446035553Spatrick 126546035553Spatricktemplate <class _Tp, class _Up> 126646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1267*4bdff4beSrobertenable_if_t< 1268*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() >= 1269*4bdff4beSrobert std::declval<const _Up&>()), bool>, 127046035553Spatrick bool 127146035553Spatrick> 127246035553Spatrickoperator>=(const optional<_Tp>& __x, const optional<_Up>& __y) 127346035553Spatrick{ 127446035553Spatrick if (!static_cast<bool>(__y)) 127546035553Spatrick return true; 127646035553Spatrick if (!static_cast<bool>(__x)) 127746035553Spatrick return false; 127846035553Spatrick return *__x >= *__y; 127946035553Spatrick} 128046035553Spatrick 128146035553Spatrick// Comparisons with nullopt 128246035553Spatricktemplate <class _Tp> 128346035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 128446035553Spatrickbool 128546035553Spatrickoperator==(const optional<_Tp>& __x, nullopt_t) noexcept 128646035553Spatrick{ 128746035553Spatrick return !static_cast<bool>(__x); 128846035553Spatrick} 128946035553Spatrick 129046035553Spatricktemplate <class _Tp> 129146035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 129246035553Spatrickbool 129346035553Spatrickoperator==(nullopt_t, const optional<_Tp>& __x) noexcept 129446035553Spatrick{ 129546035553Spatrick return !static_cast<bool>(__x); 129646035553Spatrick} 129746035553Spatrick 129846035553Spatricktemplate <class _Tp> 129946035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 130046035553Spatrickbool 130146035553Spatrickoperator!=(const optional<_Tp>& __x, nullopt_t) noexcept 130246035553Spatrick{ 130346035553Spatrick return static_cast<bool>(__x); 130446035553Spatrick} 130546035553Spatrick 130646035553Spatricktemplate <class _Tp> 130746035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 130846035553Spatrickbool 130946035553Spatrickoperator!=(nullopt_t, const optional<_Tp>& __x) noexcept 131046035553Spatrick{ 131146035553Spatrick return static_cast<bool>(__x); 131246035553Spatrick} 131346035553Spatrick 131446035553Spatricktemplate <class _Tp> 131546035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 131646035553Spatrickbool 131746035553Spatrickoperator<(const optional<_Tp>&, nullopt_t) noexcept 131846035553Spatrick{ 131946035553Spatrick return false; 132046035553Spatrick} 132146035553Spatrick 132246035553Spatricktemplate <class _Tp> 132346035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 132446035553Spatrickbool 132546035553Spatrickoperator<(nullopt_t, const optional<_Tp>& __x) noexcept 132646035553Spatrick{ 132746035553Spatrick return static_cast<bool>(__x); 132846035553Spatrick} 132946035553Spatrick 133046035553Spatricktemplate <class _Tp> 133146035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 133246035553Spatrickbool 133346035553Spatrickoperator<=(const optional<_Tp>& __x, nullopt_t) noexcept 133446035553Spatrick{ 133546035553Spatrick return !static_cast<bool>(__x); 133646035553Spatrick} 133746035553Spatrick 133846035553Spatricktemplate <class _Tp> 133946035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 134046035553Spatrickbool 134146035553Spatrickoperator<=(nullopt_t, const optional<_Tp>&) noexcept 134246035553Spatrick{ 134346035553Spatrick return true; 134446035553Spatrick} 134546035553Spatrick 134646035553Spatricktemplate <class _Tp> 134746035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 134846035553Spatrickbool 134946035553Spatrickoperator>(const optional<_Tp>& __x, nullopt_t) noexcept 135046035553Spatrick{ 135146035553Spatrick return static_cast<bool>(__x); 135246035553Spatrick} 135346035553Spatrick 135446035553Spatricktemplate <class _Tp> 135546035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 135646035553Spatrickbool 135746035553Spatrickoperator>(nullopt_t, const optional<_Tp>&) noexcept 135846035553Spatrick{ 135946035553Spatrick return false; 136046035553Spatrick} 136146035553Spatrick 136246035553Spatricktemplate <class _Tp> 136346035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 136446035553Spatrickbool 136546035553Spatrickoperator>=(const optional<_Tp>&, nullopt_t) noexcept 136646035553Spatrick{ 136746035553Spatrick return true; 136846035553Spatrick} 136946035553Spatrick 137046035553Spatricktemplate <class _Tp> 137146035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 137246035553Spatrickbool 137346035553Spatrickoperator>=(nullopt_t, const optional<_Tp>& __x) noexcept 137446035553Spatrick{ 137546035553Spatrick return !static_cast<bool>(__x); 137646035553Spatrick} 137746035553Spatrick 137846035553Spatrick// Comparisons with T 137946035553Spatricktemplate <class _Tp, class _Up> 138046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1381*4bdff4beSrobertenable_if_t< 1382*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() == 1383*4bdff4beSrobert std::declval<const _Up&>()), bool>, 138446035553Spatrick bool 138546035553Spatrick> 138646035553Spatrickoperator==(const optional<_Tp>& __x, const _Up& __v) 138746035553Spatrick{ 138846035553Spatrick return static_cast<bool>(__x) ? *__x == __v : false; 138946035553Spatrick} 139046035553Spatrick 139146035553Spatricktemplate <class _Tp, class _Up> 139246035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1393*4bdff4beSrobertenable_if_t< 1394*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() == 1395*4bdff4beSrobert std::declval<const _Up&>()), bool>, 139646035553Spatrick bool 139746035553Spatrick> 139846035553Spatrickoperator==(const _Tp& __v, const optional<_Up>& __x) 139946035553Spatrick{ 140046035553Spatrick return static_cast<bool>(__x) ? __v == *__x : false; 140146035553Spatrick} 140246035553Spatrick 140346035553Spatricktemplate <class _Tp, class _Up> 140446035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1405*4bdff4beSrobertenable_if_t< 1406*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() != 1407*4bdff4beSrobert std::declval<const _Up&>()), bool>, 140846035553Spatrick bool 140946035553Spatrick> 141046035553Spatrickoperator!=(const optional<_Tp>& __x, const _Up& __v) 141146035553Spatrick{ 141246035553Spatrick return static_cast<bool>(__x) ? *__x != __v : true; 141346035553Spatrick} 141446035553Spatrick 141546035553Spatricktemplate <class _Tp, class _Up> 141646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1417*4bdff4beSrobertenable_if_t< 1418*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() != 1419*4bdff4beSrobert std::declval<const _Up&>()), bool>, 142046035553Spatrick bool 142146035553Spatrick> 142246035553Spatrickoperator!=(const _Tp& __v, const optional<_Up>& __x) 142346035553Spatrick{ 142446035553Spatrick return static_cast<bool>(__x) ? __v != *__x : true; 142546035553Spatrick} 142646035553Spatrick 142746035553Spatricktemplate <class _Tp, class _Up> 142846035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1429*4bdff4beSrobertenable_if_t< 1430*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() < 1431*4bdff4beSrobert std::declval<const _Up&>()), bool>, 143246035553Spatrick bool 143346035553Spatrick> 143446035553Spatrickoperator<(const optional<_Tp>& __x, const _Up& __v) 143546035553Spatrick{ 143646035553Spatrick return static_cast<bool>(__x) ? *__x < __v : true; 143746035553Spatrick} 143846035553Spatrick 143946035553Spatricktemplate <class _Tp, class _Up> 144046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1441*4bdff4beSrobertenable_if_t< 1442*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() < 1443*4bdff4beSrobert std::declval<const _Up&>()), bool>, 144446035553Spatrick bool 144546035553Spatrick> 144646035553Spatrickoperator<(const _Tp& __v, const optional<_Up>& __x) 144746035553Spatrick{ 144846035553Spatrick return static_cast<bool>(__x) ? __v < *__x : false; 144946035553Spatrick} 145046035553Spatrick 145146035553Spatricktemplate <class _Tp, class _Up> 145246035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1453*4bdff4beSrobertenable_if_t< 1454*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() <= 1455*4bdff4beSrobert std::declval<const _Up&>()), bool>, 145646035553Spatrick bool 145746035553Spatrick> 145846035553Spatrickoperator<=(const optional<_Tp>& __x, const _Up& __v) 145946035553Spatrick{ 146046035553Spatrick return static_cast<bool>(__x) ? *__x <= __v : true; 146146035553Spatrick} 146246035553Spatrick 146346035553Spatricktemplate <class _Tp, class _Up> 146446035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1465*4bdff4beSrobertenable_if_t< 1466*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() <= 1467*4bdff4beSrobert std::declval<const _Up&>()), bool>, 146846035553Spatrick bool 146946035553Spatrick> 147046035553Spatrickoperator<=(const _Tp& __v, const optional<_Up>& __x) 147146035553Spatrick{ 147246035553Spatrick return static_cast<bool>(__x) ? __v <= *__x : false; 147346035553Spatrick} 147446035553Spatrick 147546035553Spatricktemplate <class _Tp, class _Up> 147646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1477*4bdff4beSrobertenable_if_t< 1478*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() > 1479*4bdff4beSrobert std::declval<const _Up&>()), bool>, 148046035553Spatrick bool 148146035553Spatrick> 148246035553Spatrickoperator>(const optional<_Tp>& __x, const _Up& __v) 148346035553Spatrick{ 148446035553Spatrick return static_cast<bool>(__x) ? *__x > __v : false; 148546035553Spatrick} 148646035553Spatrick 148746035553Spatricktemplate <class _Tp, class _Up> 148846035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1489*4bdff4beSrobertenable_if_t< 1490*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() > 1491*4bdff4beSrobert std::declval<const _Up&>()), bool>, 149246035553Spatrick bool 149346035553Spatrick> 149446035553Spatrickoperator>(const _Tp& __v, const optional<_Up>& __x) 149546035553Spatrick{ 149646035553Spatrick return static_cast<bool>(__x) ? __v > *__x : true; 149746035553Spatrick} 149846035553Spatrick 149946035553Spatricktemplate <class _Tp, class _Up> 150046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1501*4bdff4beSrobertenable_if_t< 1502*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() >= 1503*4bdff4beSrobert std::declval<const _Up&>()), bool>, 150446035553Spatrick bool 150546035553Spatrick> 150646035553Spatrickoperator>=(const optional<_Tp>& __x, const _Up& __v) 150746035553Spatrick{ 150846035553Spatrick return static_cast<bool>(__x) ? *__x >= __v : false; 150946035553Spatrick} 151046035553Spatrick 151146035553Spatricktemplate <class _Tp, class _Up> 151246035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 1513*4bdff4beSrobertenable_if_t< 1514*4bdff4beSrobert is_convertible_v<decltype(std::declval<const _Tp&>() >= 1515*4bdff4beSrobert std::declval<const _Up&>()), bool>, 151646035553Spatrick bool 151746035553Spatrick> 151846035553Spatrickoperator>=(const _Tp& __v, const optional<_Up>& __x) 151946035553Spatrick{ 152046035553Spatrick return static_cast<bool>(__x) ? __v >= *__x : true; 152146035553Spatrick} 152246035553Spatrick 152346035553Spatrick 152446035553Spatricktemplate <class _Tp> 1525*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 1526*4bdff4beSrobertenable_if_t< 152746035553Spatrick is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, 152846035553Spatrick void 152946035553Spatrick> 153046035553Spatrickswap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) 153146035553Spatrick{ 153246035553Spatrick __x.swap(__y); 153346035553Spatrick} 153446035553Spatrick 153546035553Spatricktemplate <class _Tp> 153646035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 153746035553Spatrickoptional<decay_t<_Tp>> make_optional(_Tp&& __v) 153846035553Spatrick{ 153946035553Spatrick return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v)); 154046035553Spatrick} 154146035553Spatrick 154246035553Spatricktemplate <class _Tp, class... _Args> 154346035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 154446035553Spatrickoptional<_Tp> make_optional(_Args&&... __args) 154546035553Spatrick{ 154646035553Spatrick return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); 154746035553Spatrick} 154846035553Spatrick 154946035553Spatricktemplate <class _Tp, class _Up, class... _Args> 155046035553Spatrick_LIBCPP_INLINE_VISIBILITY constexpr 155146035553Spatrickoptional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) 155246035553Spatrick{ 155346035553Spatrick return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...); 155446035553Spatrick} 155546035553Spatrick 155646035553Spatricktemplate <class _Tp> 155746035553Spatrickstruct _LIBCPP_TEMPLATE_VIS hash< 155846035553Spatrick __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> 155946035553Spatrick> 156046035553Spatrick{ 156176d0caaeSpatrick#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) 156276d0caaeSpatrick _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type; 156376d0caaeSpatrick _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; 156476d0caaeSpatrick#endif 156546035553Spatrick 156646035553Spatrick _LIBCPP_INLINE_VISIBILITY 156776d0caaeSpatrick size_t operator()(const optional<_Tp>& __opt) const 156846035553Spatrick { 156946035553Spatrick return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0; 157046035553Spatrick } 157146035553Spatrick}; 157246035553Spatrick 157346035553Spatrick_LIBCPP_END_NAMESPACE_STD 157446035553Spatrick 157546035553Spatrick#endif // _LIBCPP_STD_VER > 14 157646035553Spatrick 1577*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 1578*4bdff4beSrobert# include <atomic> 1579*4bdff4beSrobert# include <climits> 1580*4bdff4beSrobert# include <concepts> 1581*4bdff4beSrobert# include <ctime> 1582*4bdff4beSrobert# include <iterator> 1583*4bdff4beSrobert# include <memory> 1584*4bdff4beSrobert# include <ratio> 1585*4bdff4beSrobert# include <tuple> 1586*4bdff4beSrobert# include <typeinfo> 1587*4bdff4beSrobert# include <utility> 1588*4bdff4beSrobert# include <variant> 1589*4bdff4beSrobert#endif 159046035553Spatrick 159146035553Spatrick#endif // _LIBCPP_OPTIONAL 1592