2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_OPTIONAL
11 #define _LIBCPP_OPTIONAL
19 // [optional.optional], class template optional
24 concept is-derived-from-optional = requires(const T& t) { // exposition only
25 []<class U>(const optional<U>&){ }(t);
28 // [optional.nullopt], no-value state indicator
29 struct nullopt_t{see below };
30 inline constexpr nullopt_t nullopt(unspecified );
32 // [optional.bad.access], class bad_optional_access
33 class bad_optional_access;
35 // [optional.relops], relational operators
36 template <class T, class U>
37 constexpr bool operator==(const optional<T>&, const optional<U>&);
38 template <class T, class U>
39 constexpr bool operator!=(const optional<T>&, const optional<U>&);
40 template <class T, class U>
41 constexpr bool operator<(const optional<T>&, const optional<U>&);
42 template <class T, class U>
43 constexpr bool operator>(const optional<T>&, const optional<U>&);
44 template <class T, class U>
45 constexpr bool operator<=(const optional<T>&, const optional<U>&);
46 template <class T, class U>
47 constexpr bool operator>=(const optional<T>&, const optional<U>&);
48 template<class T, three_way_comparable_with<T> U>
49 constexpr compare_three_way_result_t<T, U>
50 operator<=>(const optional<T>&, const optional<U>&); // since C++20
52 // [optional.nullops], comparison with nullopt
53 template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
54 template<class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; // until C++17
55 template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; // until C++17
56 template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; // until C++17
57 template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; // until C++17
58 template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; // until C++17
59 template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; // until C++17
60 template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; // until C++17
61 template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; // until C++17
62 template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; // until C++17
63 template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; // until C++17
64 template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; // until C++17
66 constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // since C++20
68 // [optional.comp.with.t], comparison with T
69 template<class T, class U> constexpr bool operator==(const optional<T>&, const U&);
70 template<class T, class U> constexpr bool operator==(const T&, const optional<U>&);
71 template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
72 template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
73 template<class T, class U> constexpr bool operator<(const optional<T>&, const U&);
74 template<class T, class U> constexpr bool operator<(const T&, const optional<U>&);
75 template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
76 template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
77 template<class T, class U> constexpr bool operator>(const optional<T>&, const U&);
78 template<class T, class U> constexpr bool operator>(const T&, const optional<U>&);
79 template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
80 template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
81 template<class T, class U>
82 requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U>
83 constexpr compare_three_way_result_t<T, U>
84 operator<=>(const optional<T>&, const U&); // since C++20
86 // [optional.specalg], specialized algorithms
88 void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
91 constexpr optional<see below > make_optional(T&&);
92 template<class T, class... Args>
93 constexpr optional<T> make_optional(Args&&... args);
94 template<class T, class U, class... Args>
95 constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
97 // [optional.hash], hash support
98 template<class T> struct hash;
99 template<class T> struct hash<optional<T>>;
104 using value_type = T;
106 // [optional.ctor], constructors
107 constexpr optional() noexcept;
108 constexpr optional(nullopt_t) noexcept;
109 constexpr optional(const optional &);
110 constexpr optional(optional &&) noexcept(see below);
111 template<class... Args>
112 constexpr explicit optional(in_place_t, Args &&...);
113 template<class U, class... Args>
114 constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
115 template<class U = T>
116 constexpr explicit(see-below) optional(U &&);
118 explicit(see-below) optional(const optional<U> &); // constexpr in C++20
120 explicit(see-below) optional(optional<U> &&); // constexpr in C++20
122 // [optional.dtor], destructor
123 ~optional(); // constexpr in C++20
125 // [optional.assign], assignment
126 optional &operator=(nullopt_t) noexcept; // constexpr in C++20
127 constexpr optional &operator=(const optional &);
128 constexpr optional &operator=(optional &&) noexcept(see below);
129 template<class U = T> optional &operator=(U &&); // constexpr in C++20
130 template<class U> optional &operator=(const optional<U> &); // constexpr in C++20
131 template<class U> optional &operator=(optional<U> &&); // constexpr in C++20
132 template<class... Args> T& emplace(Args &&...); // constexpr in C++20
133 template<class U, class... Args> T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
135 // [optional.swap], swap
136 void swap(optional &) noexcept(see below ); // constexpr in C++20
138 // [optional.observe], observers
139 constexpr T const *operator->() const noexcept;
140 constexpr T *operator->() noexcept;
141 constexpr T const &operator*() const & noexcept;
142 constexpr T &operator*() & noexcept;
143 constexpr T &&operator*() && noexcept;
144 constexpr const T &&operator*() const && noexcept;
145 constexpr explicit operator bool() const noexcept;
146 constexpr bool has_value() const noexcept;
147 constexpr T const &value() const &;
148 constexpr T &value() &;
149 constexpr T &&value() &&;
150 constexpr const T &&value() const &&;
151 template<class U> constexpr T value_or(U &&) const &;
152 template<class U> constexpr T value_or(U &&) &&;
154 // [optional.monadic], monadic operations
155 template<class F> constexpr auto and_then(F&& f) &; // since C++23
156 template<class F> constexpr auto and_then(F&& f) &&; // since C++23
157 template<class F> constexpr auto and_then(F&& f) const&; // since C++23
158 template<class F> constexpr auto and_then(F&& f) const&&; // since C++23
159 template<class F> constexpr auto transform(F&& f) &; // since C++23
160 template<class F> constexpr auto transform(F&& f) &&; // since C++23
161 template<class F> constexpr auto transform(F&& f) const&; // since C++23
162 template<class F> constexpr auto transform(F&& f) const&&; // since C++23
163 template<class F> constexpr optional or_else(F&& f) &&; // since C++23
164 template<class F> constexpr optional or_else(F&& f) const&; // since C++23
166 // [optional.mod], modifiers
167 void reset() noexcept; // constexpr in C++20
170 T *val; // exposition only
174 optional(T) -> optional<T>;
180 #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
181 # include <__cxx03/optional>
184 # include <__compare/compare_three_way_result.h>
185 # include <__compare/ordering.h>
186 # include <__compare/three_way_comparable.h>
187 # include <__concepts/invocable.h>
189 # include <__exception/exception.h>
190 # include <__functional/hash.h>
191 # include <__functional/invoke.h>
192 # include <__functional/unary_function.h>
193 # include <__fwd/functional.h>
194 # include <__memory/addressof.h>
195 # include <__memory/construct_at.h>
196 # include <__tuple/sfinae_helpers.h>
197 # include <__type_traits/add_pointer.h>
198 # include <__type_traits/conditional.h>
199 # include <__type_traits/conjunction.h>
200 # include <__type_traits/decay.h>
201 # include <__type_traits/disjunction.h>
202 # include <__type_traits/enable_if.h>
203 # include <__type_traits/invoke.h>
204 # include <__type_traits/is_array.h>
205 # include <__type_traits/is_assignable.h>
206 # include <__type_traits/is_constructible.h>
207 # include <__type_traits/is_convertible.h>
208 # include <__type_traits/is_destructible.h>
209 # include <__type_traits/is_nothrow_assignable.h>
210 # include <__type_traits/is_nothrow_constructible.h>
211 # include <__type_traits/is_object.h>
212 # include <__type_traits/is_reference.h>
213 # include <__type_traits/is_same.h>
214 # include <__type_traits/is_scalar.h>
215 # include <__type_traits/is_swappable.h>
216 # include <__type_traits/is_trivially_assignable.h>
217 # include <__type_traits/is_trivially_constructible.h>
218 # include <__type_traits/is_trivially_destructible.h>
219 # include <__type_traits/is_trivially_relocatable.h>
220 # include <__type_traits/negation.h>
221 # include <__type_traits/remove_const.h>
222 # include <__type_traits/remove_cv.h>
223 # include <__type_traits/remove_cvref.h>
224 # include <__type_traits/remove_reference.h>
225 # include <__utility/declval.h>
226 # include <__utility/forward.h>
227 # include <__utility/in_place.h>
228 # include <__utility/move.h>
229 # include <__utility/swap.h>
230 # include <__verbose_abort>
231 # include <initializer_list>
234 // standard-mandated includes
239 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
240 # pragma GCC system_header
244 # include <__undef_macros>
246 namespace std // purposefully not using versioning namespace
249 class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access : public exception {
251 _LIBCPP_HIDE_FROM_ABI bad_optional_access() _NOEXCEPT = default;
252 _LIBCPP_HIDE_FROM_ABI bad_optional_access(const bad_optional_access&) _NOEXCEPT = default;
253 _LIBCPP_HIDE_FROM_ABI bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default;
254 // Get the key function ~bad_optional_access() into the dylib
255 ~bad_optional_access() _NOEXCEPT override;
256 const char* what() const _NOEXCEPT override;
261 # if _LIBCPP_STD_VER >= 17
263 _LIBCPP_BEGIN_NAMESPACE_STD
265 [[noreturn]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS void
266 __throw_bad_optional_access() {
267 # if _LIBCPP_HAS_EXCEPTIONS
268 throw bad_optional_access();
270 _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
275 struct __secret_tag {
276 explicit __secret_tag() = default;
278 _LIBCPP_HIDE_FROM_ABI constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
281 inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
283 struct __optional_construct_from_invoke_tag {};
285 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
286 struct __optional_destruct_base;
289 struct __optional_destruct_base<_Tp, false> {
290 typedef _Tp value_type;
291 static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
294 remove_cv_t<value_type> __val_;
298 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base() {
300 __val_.~value_type();
303 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {}
305 template <class... _Args>
306 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
307 : __val_(std::forward<_Args>(__args)...), __engaged_(true) {}
309 # if _LIBCPP_STD_VER >= 23
310 template <class _Fp, class... _Args>
311 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(
312 __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
313 : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {}
316 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept {
318 __val_.~value_type();
325 struct __optional_destruct_base<_Tp, true> {
326 typedef _Tp value_type;
327 static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
330 remove_cv_t<value_type> __val_;
334 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {}
336 template <class... _Args>
337 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
338 : __val_(std::forward<_Args>(__args)...), __engaged_(true) {}
340 # if _LIBCPP_STD_VER >= 23
341 template <class _Fp, class... _Args>
342 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base(
343 __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
344 : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {}
347 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept {
354 template <class _Tp, bool = is_reference<_Tp>::value>
355 struct __optional_storage_base : __optional_destruct_base<_Tp> {
356 using __base = __optional_destruct_base<_Tp>;
357 using value_type = _Tp;
358 using __base::__base;
360 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; }
362 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() & noexcept { return this->__val_; }
363 _LIBCPP_HIDE_FROM_ABI constexpr const value_type& __get() const& noexcept { return this->__val_; }
364 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() && noexcept { return std::move(this->__val_); }
365 _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& __get() const&& noexcept { return std::move(this->__val_); }
367 template <class... _Args>
368 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) {
369 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
370 std::__construct_at(std::addressof(this->__val_), std::forward<_Args>(__args)...);
371 this->__engaged_ = true;
374 template <class _That>
375 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) {
376 if (__opt.has_value())
377 __construct(std::forward<_That>(__opt).__get());
380 template <class _That>
381 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) {
382 if (this->__engaged_ == __opt.has_value()) {
383 if (this->__engaged_)
384 static_cast<_Tp&>(this->__val_) = std::forward<_That>(__opt).__get();
386 if (this->__engaged_)
389 __construct(std::forward<_That>(__opt).__get());
394 // optional<T&> is currently required to be ill-formed. However, it may
395 // be allowed in the future. For this reason, it has already been implemented
396 // to ensure we can make the change in an ABI-compatible manner.
398 struct __optional_storage_base<_Tp, true> {
399 using value_type = _Tp;
400 using __raw_type = remove_reference_t<_Tp>;
401 __raw_type* __value_;
404 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
405 using _RawUp = __libcpp_remove_reference_t<_Up>;
406 using _UpPtr = _RawUp*;
407 using _RawTp = __libcpp_remove_reference_t<_Tp>;
408 using _TpPtr = _RawTp*;
409 using _CheckLValueArg =
410 integral_constant<bool,
411 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) ||
412 is_same<_RawUp, reference_wrapper<_RawTp>>::value ||
413 is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value >;
414 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) ||
415 (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
416 is_convertible<_UpPtr, _TpPtr>::value);
419 _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {}
421 template <class _UArg>
422 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
423 : __value_(std::addressof(__uarg)) {
424 static_assert(__can_bind_reference<_UArg>(),
425 "Attempted to construct a reference element in tuple from a "
426 "possible temporary");
429 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }
431 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __value_ != nullptr; }
433 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() const& noexcept { return *__value_; }
435 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() const&& noexcept { return std::forward<value_type>(*__value_); }
437 template <class _UArg>
438 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) {
439 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
440 static_assert(__can_bind_reference<_UArg>(),
441 "Attempted to construct a reference element in tuple from a "
442 "possible temporary");
443 __value_ = std::addressof(__val);
446 template <class _That>
447 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) {
448 if (__opt.has_value())
449 __construct(std::forward<_That>(__opt).__get());
452 template <class _That>
453 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) {
454 if (has_value() == __opt.has_value()) {
456 *__value_ = std::forward<_That>(__opt).__get();
461 __construct(std::forward<_That>(__opt).__get());
466 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
467 struct __optional_copy_base : __optional_storage_base<_Tp> {
468 using __optional_storage_base<_Tp>::__optional_storage_base;
472 struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> {
473 using __optional_storage_base<_Tp>::__optional_storage_base;
475 _LIBCPP_HIDE_FROM_ABI __optional_copy_base() = default;
477 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt) {
478 this->__construct_from(__opt);
481 _LIBCPP_HIDE_FROM_ABI __optional_copy_base(__optional_copy_base&&) = default;
482 _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(const __optional_copy_base&) = default;
483 _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&) = default;
486 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
487 struct __optional_move_base : __optional_copy_base<_Tp> {
488 using __optional_copy_base<_Tp>::__optional_copy_base;
492 struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> {
493 using value_type = _Tp;
494 using __optional_copy_base<_Tp>::__optional_copy_base;
496 _LIBCPP_HIDE_FROM_ABI __optional_move_base() = default;
497 _LIBCPP_HIDE_FROM_ABI __optional_move_base(const __optional_move_base&) = default;
499 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
500 __optional_move_base(__optional_move_base&& __opt) noexcept(is_nothrow_move_constructible_v<value_type>) {
501 this->__construct_from(std::move(__opt));
504 _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(const __optional_move_base&) = default;
505 _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(__optional_move_base&&) = default;
509 bool = is_trivially_destructible<_Tp>::value && is_trivially_copy_constructible<_Tp>::value &&
510 is_trivially_copy_assignable<_Tp>::value>
511 struct __optional_copy_assign_base : __optional_move_base<_Tp> {
512 using __optional_move_base<_Tp>::__optional_move_base;
516 struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> {
517 using __optional_move_base<_Tp>::__optional_move_base;
519 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base() = default;
520 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
521 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
523 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base&
524 operator=(const __optional_copy_assign_base& __opt) {
525 this->__assign_from(__opt);
529 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
533 bool = is_trivially_destructible<_Tp>::value && is_trivially_move_constructible<_Tp>::value &&
534 is_trivially_move_assignable<_Tp>::value>
535 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> {
536 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
540 struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> {
541 using value_type = _Tp;
542 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
544 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base() = default;
545 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
546 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(__optional_move_assign_base&&) = default;
547 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
549 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base&
550 operator=(__optional_move_assign_base&& __opt) noexcept(
551 is_nothrow_move_assignable_v<value_type> && is_nothrow_move_constructible_v<value_type>) {
552 this->__assign_from(std::move(__opt));
558 using __optional_sfinae_ctor_base_t =
559 __sfinae_ctor_base< is_copy_constructible<_Tp>::value, is_move_constructible<_Tp>::value >;
562 using __optional_sfinae_assign_base_t =
563 __sfinae_assign_base< (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
564 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) >;
569 # if _LIBCPP_STD_VER >= 20
572 concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
574 # endif // _LIBCPP_STD_VER >= 20
577 struct __is_std_optional : false_type {};
579 struct __is_std_optional<optional<_Tp>> : true_type {};
582 class _LIBCPP_DECLSPEC_EMPTY_BASES optional
583 : private __optional_move_assign_base<_Tp>,
584 private __optional_sfinae_ctor_base_t<_Tp>,
585 private __optional_sfinae_assign_base_t<_Tp> {
586 using __base = __optional_move_assign_base<_Tp>;
589 using value_type = _Tp;
591 using __trivially_relocatable = conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
594 // Disable the reference extension using this static assert.
595 static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
596 "instantiation of optional with in_place_t is ill-formed");
597 static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
598 "instantiation of optional with nullopt_t is ill-formed");
599 static_assert(!is_reference_v<value_type>, "instantiation of optional with a reference type is ill-formed");
600 static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed");
601 static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed");
603 // LWG2756: conditionally explicit conversion from _Up
604 struct _CheckOptionalArgsConstructor {
606 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
607 return is_constructible_v<_Tp, _Up&&> && is_convertible_v<_Up&&, _Tp>;
611 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
612 return is_constructible_v<_Tp, _Up&&> && !is_convertible_v<_Up&&, _Tp>;
616 using _CheckOptionalArgsCtor =
617 _If< _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && _IsNotSame<__remove_cvref_t<_Up>, optional>::value &&
618 (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value),
619 _CheckOptionalArgsConstructor,
620 __check_tuple_constructor_fail >;
621 template <class _QualUp>
622 struct _CheckOptionalLikeConstructor {
623 template <class _Up, class _Opt = optional<_Up>>
624 using __check_constructible_from_opt =
625 _Or< is_constructible<_Tp, _Opt&>,
626 is_constructible<_Tp, _Opt const&>,
627 is_constructible<_Tp, _Opt&&>,
628 is_constructible<_Tp, _Opt const&&>,
629 is_convertible<_Opt&, _Tp>,
630 is_convertible<_Opt const&, _Tp>,
631 is_convertible<_Opt&&, _Tp>,
632 is_convertible<_Opt const&&, _Tp> >;
633 template <class _Up, class _Opt = optional<_Up>>
634 using __check_assignable_from_opt =
635 _Or< is_assignable<_Tp&, _Opt&>,
636 is_assignable<_Tp&, _Opt const&>,
637 is_assignable<_Tp&, _Opt&&>,
638 is_assignable<_Tp&, _Opt const&&> >;
639 template <class _Up, class _QUp = _QualUp>
640 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
641 return is_convertible<_QUp, _Tp>::value &&
642 (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
644 template <class _Up, class _QUp = _QualUp>
645 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
646 return !is_convertible<_QUp, _Tp>::value &&
647 (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
649 template <class _Up, class _QUp = _QualUp>
650 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() {
651 // Construction and assignability of _QUp to _Tp has already been
653 return !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value;
657 template <class _Up, class _QualUp>
658 using _CheckOptionalLikeCtor =
659 _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp> >::value,
660 _CheckOptionalLikeConstructor<_QualUp>,
661 __check_tuple_constructor_fail >;
662 template <class _Up, class _QualUp>
663 using _CheckOptionalLikeAssign =
664 _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp>, is_assignable<_Tp&, _QualUp> >::value,
665 _CheckOptionalLikeConstructor<_QualUp>,
666 __check_tuple_constructor_fail >;
669 _LIBCPP_HIDE_FROM_ABI constexpr optional() noexcept {}
670 _LIBCPP_HIDE_FROM_ABI constexpr optional(const optional&) = default;
671 _LIBCPP_HIDE_FROM_ABI constexpr optional(optional&&) = default;
672 _LIBCPP_HIDE_FROM_ABI constexpr optional(nullopt_t) noexcept {}
677 class = enable_if_t< _And< _IsSame<_InPlaceT, in_place_t>, is_constructible<value_type, _Args...> >::value > >
678 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args)
679 : __base(in_place, std::forward<_Args>(__args)...) {}
683 class = enable_if_t< is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> >
684 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
685 : __base(in_place, __il, std::forward<_Args>(__args)...) {}
687 template <class _Up = value_type,
688 enable_if_t< _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
689 _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
691 template <class _Up, enable_if_t< _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
692 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
694 // LWG2756: conditionally explicit conversion from const optional<_Up>&
696 enable_if_t< _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
697 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) {
698 this->__construct_from(__v);
701 enable_if_t< _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
702 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) {
703 this->__construct_from(__v);
706 // LWG2756: conditionally explicit conversion from optional<_Up>&&
707 template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0>
708 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) {
709 this->__construct_from(std::move(__v));
711 template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0>
712 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) {
713 this->__construct_from(std::move(__v));
716 # if _LIBCPP_STD_VER >= 23
717 template <class _Tag,
720 __enable_if_t<_IsSame<_Tag, __optional_construct_from_invoke_tag>::value, int> = 0>
721 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Tag, _Fp&& __f, _Args&&... __args)
722 : __base(__optional_construct_from_invoke_tag{}, std::forward<_Fp>(__f), std::forward<_Args>(__args)...) {}
725 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept {
730 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default;
731 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
735 class _Up = value_type,
736 class = enable_if_t< _And< _IsNotSame<__remove_cvref_t<_Up>, optional>,
737 _Or< _IsNotSame<__remove_cvref_t<_Up>, value_type>, _Not<is_scalar<value_type>> >,
738 is_constructible<value_type, _Up>,
739 is_assignable<value_type&, _Up> >::value> >
740 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) {
741 if (this->has_value())
742 this->__get() = std::forward<_Up>(__v);
744 this->__construct(std::forward<_Up>(__v));
750 enable_if_t< _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>(), int> = 0>
751 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(const optional<_Up>& __v) {
752 this->__assign_from(__v);
757 template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_assign<_Up>(), int> = 0>
758 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(optional<_Up>&& __v) {
759 this->__assign_from(std::move(__v));
763 template <class... _Args, class = enable_if_t< is_constructible_v<value_type, _Args...> > >
764 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
766 this->__construct(std::forward<_Args>(__args)...);
767 return this->__get();
772 class = enable_if_t< is_constructible_v<value_type, initializer_list<_Up>&, _Args...> > >
773 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
775 this->__construct(__il, std::forward<_Args>(__args)...);
776 return this->__get();
779 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
780 swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>) {
781 if (this->has_value() == __opt.has_value()) {
783 if (this->has_value())
784 swap(this->__get(), __opt.__get());
786 if (this->has_value()) {
787 __opt.__construct(std::move(this->__get()));
790 this->__construct(std::move(__opt.__get()));
796 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept {
797 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
798 return std::addressof(this->__get());
801 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept {
802 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
803 return std::addressof(this->__get());
806 _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept {
807 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
808 return this->__get();
811 _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept {
812 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
813 return this->__get();
816 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept {
817 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
818 return std::move(this->__get());
821 _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept {
822 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
823 return std::move(this->__get());
826 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return has_value(); }
829 using __base::has_value;
831 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const& value() const& {
832 if (!this->has_value())
833 __throw_bad_optional_access();
834 return this->__get();
837 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type& value() & {
838 if (!this->has_value())
839 __throw_bad_optional_access();
840 return this->__get();
843 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type&& value() && {
844 if (!this->has_value())
845 __throw_bad_optional_access();
846 return std::move(this->__get());
849 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const&& value() const&& {
850 if (!this->has_value())
851 __throw_bad_optional_access();
852 return std::move(this->__get());
856 _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) const& {
857 static_assert(is_copy_constructible_v<value_type>, "optional<T>::value_or: T must be copy constructible");
858 static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
859 return this->has_value() ? this->__get() : static_cast<value_type>(std::forward<_Up>(__v));
863 _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) && {
864 static_assert(is_move_constructible_v<value_type>, "optional<T>::value_or: T must be move constructible");
865 static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
866 return this->has_value() ? std::move(this->__get()) : static_cast<value_type>(std::forward<_Up>(__v));
869 # if _LIBCPP_STD_VER >= 23
870 template <class _Func>
871 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) & {
872 using _Up = invoke_result_t<_Func, value_type&>;
873 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
874 "Result of f(value()) must be a specialization of std::optional");
876 return std::invoke(std::forward<_Func>(__f), value());
877 return remove_cvref_t<_Up>();
880 template <class _Func>
881 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) const& {
882 using _Up = invoke_result_t<_Func, const value_type&>;
883 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
884 "Result of f(value()) must be a specialization of std::optional");
886 return std::invoke(std::forward<_Func>(__f), value());
887 return remove_cvref_t<_Up>();
890 template <class _Func>
891 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) && {
892 using _Up = invoke_result_t<_Func, value_type&&>;
893 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
894 "Result of f(std::move(value())) must be a specialization of std::optional");
896 return std::invoke(std::forward<_Func>(__f), std::move(value()));
897 return remove_cvref_t<_Up>();
900 template <class _Func>
901 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
902 using _Up = invoke_result_t<_Func, const value_type&&>;
903 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
904 "Result of f(std::move(value())) must be a specialization of std::optional");
906 return std::invoke(std::forward<_Func>(__f), std::move(value()));
907 return remove_cvref_t<_Up>();
910 template <class _Func>
911 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) & {
912 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
913 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
914 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
915 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
916 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
918 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
919 return optional<_Up>();
922 template <class _Func>
923 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) const& {
924 using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
925 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
926 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
927 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
928 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
930 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
931 return optional<_Up>();
934 template <class _Func>
935 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) && {
936 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
937 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
938 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
939 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
940 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
942 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
943 return optional<_Up>();
946 template <class _Func>
947 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) const&& {
948 using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
949 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
950 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
951 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
952 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
954 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
955 return optional<_Up>();
958 template <invocable _Func>
959 _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
960 requires is_copy_constructible_v<value_type>
962 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
963 "Result of f() should be the same type as this optional");
966 return std::forward<_Func>(__f)();
969 template <invocable _Func>
970 _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
971 requires is_move_constructible_v<value_type>
973 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
974 "Result of f() should be the same type as this optional");
976 return std::move(*this);
977 return std::forward<_Func>(__f)();
979 # endif // _LIBCPP_STD_VER >= 23
984 # if _LIBCPP_STD_VER >= 17
986 optional(_Tp) -> optional<_Tp>;
989 // Comparisons between optionals
990 template <class _Tp, class _Up>
991 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
992 is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
994 operator==(const optional<_Tp>& __x, const optional<_Up>& __y) {
995 if (static_cast<bool>(__x) != static_cast<bool>(__y))
997 if (!static_cast<bool>(__x))
1002 template <class _Tp, class _Up>
1003 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1004 is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
1006 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1007 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1009 if (!static_cast<bool>(__x))
1011 return *__x != *__y;
1014 template <class _Tp, class _Up>
1015 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1016 is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
1018 operator<(const optional<_Tp>& __x, const optional<_Up>& __y) {
1019 if (!static_cast<bool>(__y))
1021 if (!static_cast<bool>(__x))
1026 template <class _Tp, class _Up>
1027 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1028 is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
1030 operator>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1031 if (!static_cast<bool>(__x))
1033 if (!static_cast<bool>(__y))
1038 template <class _Tp, class _Up>
1039 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1040 is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
1042 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1043 if (!static_cast<bool>(__x))
1045 if (!static_cast<bool>(__y))
1047 return *__x <= *__y;
1050 template <class _Tp, class _Up>
1051 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1052 is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
1054 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1055 if (!static_cast<bool>(__y))
1057 if (!static_cast<bool>(__x))
1059 return *__x >= *__y;
1062 # if _LIBCPP_STD_VER >= 20
1064 template <class _Tp, three_way_comparable_with<_Tp> _Up>
1065 _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1066 operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1068 return *__x <=> *__y;
1069 return __x.has_value() <=> __y.has_value();
1072 # endif // _LIBCPP_STD_VER >= 20
1074 // Comparisons with nullopt
1075 template <class _Tp>
1076 _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept {
1077 return !static_cast<bool>(__x);
1080 # if _LIBCPP_STD_VER <= 17
1082 template <class _Tp>
1083 _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(nullopt_t, const optional<_Tp>& __x) noexcept {
1084 return !static_cast<bool>(__x);
1087 template <class _Tp>
1088 _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, nullopt_t) noexcept {
1089 return static_cast<bool>(__x);
1092 template <class _Tp>
1093 _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(nullopt_t, const optional<_Tp>& __x) noexcept {
1094 return static_cast<bool>(__x);
1097 template <class _Tp>
1098 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>&, nullopt_t) noexcept {
1102 template <class _Tp>
1103 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(nullopt_t, const optional<_Tp>& __x) noexcept {
1104 return static_cast<bool>(__x);
1107 template <class _Tp>
1108 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, nullopt_t) noexcept {
1109 return !static_cast<bool>(__x);
1112 template <class _Tp>
1113 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(nullopt_t, const optional<_Tp>&) noexcept {
1117 template <class _Tp>
1118 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, nullopt_t) noexcept {
1119 return static_cast<bool>(__x);
1122 template <class _Tp>
1123 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(nullopt_t, const optional<_Tp>&) noexcept {
1127 template <class _Tp>
1128 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>&, nullopt_t) noexcept {
1132 template <class _Tp>
1133 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(nullopt_t, const optional<_Tp>& __x) noexcept {
1134 return !static_cast<bool>(__x);
1137 # else // _LIBCPP_STD_VER <= 17
1139 template <class _Tp>
1140 _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept {
1141 return __x.has_value() <=> false;
1144 # endif // _LIBCPP_STD_VER <= 17
1146 // Comparisons with T
1147 template <class _Tp, class _Up>
1148 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1149 is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
1151 operator==(const optional<_Tp>& __x, const _Up& __v) {
1152 return static_cast<bool>(__x) ? *__x == __v : false;
1155 template <class _Tp, class _Up>
1156 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1157 is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
1159 operator==(const _Tp& __v, const optional<_Up>& __x) {
1160 return static_cast<bool>(__x) ? __v == *__x : false;
1163 template <class _Tp, class _Up>
1164 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1165 is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
1167 operator!=(const optional<_Tp>& __x, const _Up& __v) {
1168 return static_cast<bool>(__x) ? *__x != __v : true;
1171 template <class _Tp, class _Up>
1172 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1173 is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
1175 operator!=(const _Tp& __v, const optional<_Up>& __x) {
1176 return static_cast<bool>(__x) ? __v != *__x : true;
1179 template <class _Tp, class _Up>
1180 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1181 is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
1183 operator<(const optional<_Tp>& __x, const _Up& __v) {
1184 return static_cast<bool>(__x) ? *__x < __v : true;
1187 template <class _Tp, class _Up>
1188 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1189 is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
1191 operator<(const _Tp& __v, const optional<_Up>& __x) {
1192 return static_cast<bool>(__x) ? __v < *__x : false;
1195 template <class _Tp, class _Up>
1196 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1197 is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
1199 operator<=(const optional<_Tp>& __x, const _Up& __v) {
1200 return static_cast<bool>(__x) ? *__x <= __v : true;
1203 template <class _Tp, class _Up>
1204 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1205 is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
1207 operator<=(const _Tp& __v, const optional<_Up>& __x) {
1208 return static_cast<bool>(__x) ? __v <= *__x : false;
1211 template <class _Tp, class _Up>
1212 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1213 is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
1215 operator>(const optional<_Tp>& __x, const _Up& __v) {
1216 return static_cast<bool>(__x) ? *__x > __v : false;
1219 template <class _Tp, class _Up>
1220 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1221 is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
1223 operator>(const _Tp& __v, const optional<_Up>& __x) {
1224 return static_cast<bool>(__x) ? __v > *__x : true;
1227 template <class _Tp, class _Up>
1228 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1229 is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
1231 operator>=(const optional<_Tp>& __x, const _Up& __v) {
1232 return static_cast<bool>(__x) ? *__x >= __v : false;
1235 template <class _Tp, class _Up>
1236 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1237 is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
1239 operator>=(const _Tp& __v, const optional<_Up>& __x) {
1240 return static_cast<bool>(__x) ? __v >= *__x : true;
1243 # if _LIBCPP_STD_VER >= 20
1245 template <class _Tp, class _Up>
1246 requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up>
1247 _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1248 operator<=>(const optional<_Tp>& __x, const _Up& __v) {
1249 return __x.has_value() ? *__x <=> __v : strong_ordering::less;
1252 # endif // _LIBCPP_STD_VER >= 20
1254 template <class _Tp>
1255 inline _LIBCPP_HIDE_FROM_ABI
1256 _LIBCPP_CONSTEXPR_SINCE_CXX20 enable_if_t< is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, void >
1257 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) {
1261 template <class _Tp>
1262 _LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) {
1263 return optional<decay_t<_Tp>>(std::forward<_Tp>(__v));
1266 template <class _Tp, class... _Args>
1267 _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) {
1268 return optional<_Tp>(in_place, std::forward<_Args>(__args)...);
1271 template <class _Tp, class _Up, class... _Args>
1272 _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) {
1273 return optional<_Tp>(in_place, __il, std::forward<_Args>(__args)...);
1276 template <class _Tp>
1277 struct _LIBCPP_TEMPLATE_VIS hash< __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> > {
1278 # if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1279 _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
1280 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1283 _LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const {
1284 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1288 _LIBCPP_END_NAMESPACE_STD
1290 # endif // _LIBCPP_STD_VER >= 17
1294 # if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1297 # include <concepts>
1299 # include <iterator>
1303 # include <stdexcept>
1305 # include <type_traits>
1306 # include <typeinfo>
1310 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
1312 #endif // _LIBCPP_OPTIONAL