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