master
1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
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
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_OPTIONAL
11#define _LIBCPP_OPTIONAL
12
13/*
14 optional synopsis
15
16// C++1z
17
18namespace std {
19 // [optional.optional], class template optional
20 template <class T>
21 class optional;
22
23 template<class T>
24 concept is-derived-from-optional = requires(const T& t) { // exposition only
25 []<class U>(const optional<U>&){ }(t);
26 };
27
28 // [optional.nullopt], no-value state indicator
29 struct nullopt_t{see below };
30 inline constexpr nullopt_t nullopt(unspecified );
31
32 // [optional.bad.access], class bad_optional_access
33 class bad_optional_access;
34
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
51
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
65 template<class T>
66 constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // since C++20
67
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
85
86 // [optional.specalg], specialized algorithms
87 template<class T>
88 void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
89
90 template<class T>
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);
96
97 // [optional.hash], hash support
98 template<class T> struct hash;
99 template<class T> struct hash<optional<T>>;
100
101 template<class T>
102 class optional {
103 public:
104 using value_type = T;
105
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 &&);
117 template<class U>
118 explicit(see-below) optional(const optional<U> &); // constexpr in C++20
119 template<class U>
120 explicit(see-below) optional(optional<U> &&); // constexpr in C++20
121
122 // [optional.dtor], destructor
123 ~optional(); // constexpr in C++20
124
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
134
135 // [optional.swap], swap
136 void swap(optional &) noexcept(see below ); // constexpr in C++20
137
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 &&) &&;
153
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
165
166 // [optional.mod], modifiers
167 void reset() noexcept; // constexpr in C++20
168
169 private:
170 T *val; // exposition only
171 };
172
173 template<class T>
174 optional(T) -> optional<T>;
175
176} // namespace std
177
178*/
179
180#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
181# include <__cxx03/__config>
182#else
183# include <__assert>
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>
188# include <__config>
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_core_convertible.h>
209# include <__type_traits/is_destructible.h>
210# include <__type_traits/is_nothrow_assignable.h>
211# include <__type_traits/is_nothrow_constructible.h>
212# include <__type_traits/is_object.h>
213# include <__type_traits/is_reference.h>
214# include <__type_traits/is_replaceable.h>
215# include <__type_traits/is_same.h>
216# include <__type_traits/is_scalar.h>
217# include <__type_traits/is_swappable.h>
218# include <__type_traits/is_trivially_assignable.h>
219# include <__type_traits/is_trivially_constructible.h>
220# include <__type_traits/is_trivially_destructible.h>
221# include <__type_traits/is_trivially_relocatable.h>
222# include <__type_traits/negation.h>
223# include <__type_traits/remove_const.h>
224# include <__type_traits/remove_cv.h>
225# include <__type_traits/remove_cvref.h>
226# include <__type_traits/remove_reference.h>
227# include <__utility/declval.h>
228# include <__utility/forward.h>
229# include <__utility/in_place.h>
230# include <__utility/move.h>
231# include <__utility/swap.h>
232# include <__verbose_abort>
233# include <initializer_list>
234# include <version>
235
236// standard-mandated includes
237
238// [optional.syn]
239# include <compare>
240
241# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
242# pragma GCC system_header
243# endif
244
245_LIBCPP_PUSH_MACROS
246# include <__undef_macros>
247
248namespace std // purposefully not using versioning namespace
249{
250
251class _LIBCPP_EXPORTED_FROM_ABI bad_optional_access : public exception {
252public:
253 _LIBCPP_HIDE_FROM_ABI bad_optional_access() _NOEXCEPT = default;
254 _LIBCPP_HIDE_FROM_ABI bad_optional_access(const bad_optional_access&) _NOEXCEPT = default;
255 _LIBCPP_HIDE_FROM_ABI bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default;
256 // Get the key function ~bad_optional_access() into the dylib
257 ~bad_optional_access() _NOEXCEPT override;
258 const char* what() const _NOEXCEPT override;
259};
260
261} // namespace std
262
263# if _LIBCPP_STD_VER >= 17
264
265_LIBCPP_BEGIN_NAMESPACE_STD
266
267[[noreturn]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_optional_access() {
268# if _LIBCPP_HAS_EXCEPTIONS
269 throw bad_optional_access();
270# else
271 _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
272# endif
273}
274
275struct nullopt_t {
276 struct __secret_tag {
277 explicit __secret_tag() = default;
278 };
279 _LIBCPP_HIDE_FROM_ABI constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
280};
281
282inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
283
284struct __optional_construct_from_invoke_tag {};
285
286template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
287struct __optional_destruct_base;
288
289template <class _Tp>
290struct __optional_destruct_base<_Tp, false> {
291 typedef _Tp value_type;
292 static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
293 union {
294 char __null_state_;
295 remove_cv_t<value_type> __val_;
296 };
297 bool __engaged_;
298
299 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base() {
300 if (__engaged_)
301 __val_.~value_type();
302 }
303
304 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {}
305
306 template <class... _Args>
307 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
308 : __val_(std::forward<_Args>(__args)...), __engaged_(true) {}
309
310# if _LIBCPP_STD_VER >= 23
311 template <class _Fp, class... _Args>
312 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(
313 __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
314 : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {}
315# endif
316
317 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept {
318 if (__engaged_) {
319 __val_.~value_type();
320 __engaged_ = false;
321 }
322 }
323};
324
325template <class _Tp>
326struct __optional_destruct_base<_Tp, true> {
327 typedef _Tp value_type;
328 static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
329 union {
330 char __null_state_;
331 remove_cv_t<value_type> __val_;
332 };
333 bool __engaged_;
334
335 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {}
336
337 template <class... _Args>
338 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
339 : __val_(std::forward<_Args>(__args)...), __engaged_(true) {}
340
341# if _LIBCPP_STD_VER >= 23
342 template <class _Fp, class... _Args>
343 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base(
344 __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
345 : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {}
346# endif
347
348 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept {
349 if (__engaged_) {
350 __engaged_ = false;
351 }
352 }
353};
354
355template <class _Tp, bool = is_reference<_Tp>::value>
356struct __optional_storage_base : __optional_destruct_base<_Tp> {
357 using __base _LIBCPP_NODEBUG = __optional_destruct_base<_Tp>;
358 using value_type = _Tp;
359 using __base::__base;
360
361 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; }
362
363 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() & noexcept { return this->__val_; }
364 _LIBCPP_HIDE_FROM_ABI constexpr const value_type& __get() const& noexcept { return this->__val_; }
365 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() && noexcept { return std::move(this->__val_); }
366 _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& __get() const&& noexcept { return std::move(this->__val_); }
367
368 template <class... _Args>
369 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) {
370 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
371 std::__construct_at(std::addressof(this->__val_), std::forward<_Args>(__args)...);
372 this->__engaged_ = true;
373 }
374
375 template <class _That>
376 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) {
377 if (__opt.has_value())
378 __construct(std::forward<_That>(__opt).__get());
379 }
380
381 template <class _That>
382 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) {
383 if (this->__engaged_ == __opt.has_value()) {
384 if (this->__engaged_)
385 static_cast<_Tp&>(this->__val_) = std::forward<_That>(__opt).__get();
386 } else {
387 if (this->__engaged_)
388 this->reset();
389 else
390 __construct(std::forward<_That>(__opt).__get());
391 }
392 }
393};
394
395// optional<T&> is currently required to be ill-formed. However, it may
396// be allowed in the future. For this reason, it has already been implemented
397// to ensure we can make the change in an ABI-compatible manner.
398template <class _Tp>
399struct __optional_storage_base<_Tp, true> {
400 using value_type = _Tp;
401 using __raw_type _LIBCPP_NODEBUG = remove_reference_t<_Tp>;
402 __raw_type* __value_;
403
404 template <class _Up>
405 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
406 using _RawUp = __libcpp_remove_reference_t<_Up>;
407 using _UpPtr = _RawUp*;
408 using _RawTp = __libcpp_remove_reference_t<_Tp>;
409 using _TpPtr = _RawTp*;
410 using _CheckLValueArg =
411 integral_constant<bool,
412 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) ||
413 is_same<_RawUp, reference_wrapper<_RawTp>>::value ||
414 is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value >;
415 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) ||
416 (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
417 is_convertible<_UpPtr, _TpPtr>::value);
418 }
419
420 _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {}
421
422 template <class _UArg>
423 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
424 : __value_(std::addressof(__uarg)) {
425 static_assert(__can_bind_reference<_UArg>(),
426 "Attempted to construct a reference element in tuple from a "
427 "possible temporary");
428 }
429
430 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }
431
432 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __value_ != nullptr; }
433
434 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() const& noexcept { return *__value_; }
435
436 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() const&& noexcept { return std::forward<value_type>(*__value_); }
437
438 template <class _UArg>
439 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) {
440 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
441 static_assert(__can_bind_reference<_UArg>(),
442 "Attempted to construct a reference element in tuple from a "
443 "possible temporary");
444 __value_ = std::addressof(__val);
445 }
446
447 template <class _That>
448 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) {
449 if (__opt.has_value())
450 __construct(std::forward<_That>(__opt).__get());
451 }
452
453 template <class _That>
454 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) {
455 if (has_value() == __opt.has_value()) {
456 if (has_value())
457 *__value_ = std::forward<_That>(__opt).__get();
458 } else {
459 if (has_value())
460 reset();
461 else
462 __construct(std::forward<_That>(__opt).__get());
463 }
464 }
465};
466
467template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
468struct __optional_copy_base : __optional_storage_base<_Tp> {
469 using __optional_storage_base<_Tp>::__optional_storage_base;
470};
471
472template <class _Tp>
473struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> {
474 using __optional_storage_base<_Tp>::__optional_storage_base;
475
476 _LIBCPP_HIDE_FROM_ABI __optional_copy_base() = default;
477
478 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt) {
479 this->__construct_from(__opt);
480 }
481
482 _LIBCPP_HIDE_FROM_ABI __optional_copy_base(__optional_copy_base&&) = default;
483 _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(const __optional_copy_base&) = default;
484 _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&) = default;
485};
486
487template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
488struct __optional_move_base : __optional_copy_base<_Tp> {
489 using __optional_copy_base<_Tp>::__optional_copy_base;
490};
491
492template <class _Tp>
493struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> {
494 using value_type = _Tp;
495 using __optional_copy_base<_Tp>::__optional_copy_base;
496
497 _LIBCPP_HIDE_FROM_ABI __optional_move_base() = default;
498 _LIBCPP_HIDE_FROM_ABI __optional_move_base(const __optional_move_base&) = default;
499
500 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
501 __optional_move_base(__optional_move_base&& __opt) noexcept(is_nothrow_move_constructible_v<value_type>) {
502 this->__construct_from(std::move(__opt));
503 }
504
505 _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(const __optional_move_base&) = default;
506 _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(__optional_move_base&&) = default;
507};
508
509template <class _Tp,
510 bool = is_trivially_destructible<_Tp>::value && is_trivially_copy_constructible<_Tp>::value &&
511 is_trivially_copy_assignable<_Tp>::value>
512struct __optional_copy_assign_base : __optional_move_base<_Tp> {
513 using __optional_move_base<_Tp>::__optional_move_base;
514};
515
516template <class _Tp>
517struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> {
518 using __optional_move_base<_Tp>::__optional_move_base;
519
520 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base() = default;
521 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
522 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
523
524 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base&
525 operator=(const __optional_copy_assign_base& __opt) {
526 this->__assign_from(__opt);
527 return *this;
528 }
529
530 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
531};
532
533template <class _Tp,
534 bool = is_trivially_destructible<_Tp>::value && is_trivially_move_constructible<_Tp>::value &&
535 is_trivially_move_assignable<_Tp>::value>
536struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> {
537 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
538};
539
540template <class _Tp>
541struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> {
542 using value_type = _Tp;
543 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
544
545 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base() = default;
546 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
547 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(__optional_move_assign_base&&) = default;
548 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
549
550 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base&
551 operator=(__optional_move_assign_base&& __opt) noexcept(
552 is_nothrow_move_assignable_v<value_type> && is_nothrow_move_constructible_v<value_type>) {
553 this->__assign_from(std::move(__opt));
554 return *this;
555 }
556};
557
558template <class _Tp>
559using __optional_sfinae_ctor_base_t _LIBCPP_NODEBUG =
560 __sfinae_ctor_base< is_copy_constructible<_Tp>::value, is_move_constructible<_Tp>::value >;
561
562template <class _Tp>
563using __optional_sfinae_assign_base_t _LIBCPP_NODEBUG =
564 __sfinae_assign_base< (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
565 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) >;
566
567template <class _Tp>
568class optional;
569
570# if _LIBCPP_STD_VER >= 20
571
572template <class _Tp>
573concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
574
575# endif // _LIBCPP_STD_VER >= 20
576
577template <class _Tp>
578struct __is_std_optional : false_type {};
579template <class _Tp>
580struct __is_std_optional<optional<_Tp>> : true_type {};
581
582template <class _Tp>
583class _LIBCPP_DECLSPEC_EMPTY_BASES optional
584 : private __optional_move_assign_base<_Tp>,
585 private __optional_sfinae_ctor_base_t<_Tp>,
586 private __optional_sfinae_assign_base_t<_Tp> {
587 using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
588
589public:
590 using value_type = _Tp;
591
592 using __trivially_relocatable _LIBCPP_NODEBUG =
593 conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
594 using __replaceable _LIBCPP_NODEBUG = conditional_t<__is_replaceable_v<_Tp>, optional, void>;
595
596private:
597 // Disable the reference extension using this static assert.
598 static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
599 "instantiation of optional with in_place_t is ill-formed");
600 static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
601 "instantiation of optional with nullopt_t is ill-formed");
602 static_assert(!is_reference_v<value_type>, "instantiation of optional with a reference type is ill-formed");
603 static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed");
604 static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed");
605
606 // LWG2756: conditionally explicit conversion from _Up
607 struct _CheckOptionalArgsConstructor {
608 template <class _Up>
609 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
610 return is_constructible_v<_Tp, _Up&&> && is_convertible_v<_Up&&, _Tp>;
611 }
612
613 template <class _Up>
614 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
615 return is_constructible_v<_Tp, _Up&&> && !is_convertible_v<_Up&&, _Tp>;
616 }
617 };
618 template <class _Up>
619 using _CheckOptionalArgsCtor _LIBCPP_NODEBUG =
620 _If< _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && _IsNotSame<__remove_cvref_t<_Up>, optional>::value &&
621 (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value),
622 _CheckOptionalArgsConstructor,
623 __check_tuple_constructor_fail >;
624 template <class _QualUp>
625 struct _CheckOptionalLikeConstructor {
626 template <class _Up, class _Opt = optional<_Up>>
627 using __check_constructible_from_opt _LIBCPP_NODEBUG =
628 _Or< is_constructible<_Tp, _Opt&>,
629 is_constructible<_Tp, _Opt const&>,
630 is_constructible<_Tp, _Opt&&>,
631 is_constructible<_Tp, _Opt const&&>,
632 is_convertible<_Opt&, _Tp>,
633 is_convertible<_Opt const&, _Tp>,
634 is_convertible<_Opt&&, _Tp>,
635 is_convertible<_Opt const&&, _Tp> >;
636 template <class _Up, class _Opt = optional<_Up>>
637 using __check_assignable_from_opt _LIBCPP_NODEBUG =
638 _Or< is_assignable<_Tp&, _Opt&>,
639 is_assignable<_Tp&, _Opt const&>,
640 is_assignable<_Tp&, _Opt&&>,
641 is_assignable<_Tp&, _Opt const&&> >;
642 template <class _Up, class _QUp = _QualUp>
643 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
644 return is_convertible<_QUp, _Tp>::value &&
645 (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
646 }
647 template <class _Up, class _QUp = _QualUp>
648 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
649 return !is_convertible<_QUp, _Tp>::value &&
650 (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
651 }
652 template <class _Up, class _QUp = _QualUp>
653 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() {
654 // Construction and assignability of _QUp to _Tp has already been
655 // checked.
656 return !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value;
657 }
658 };
659
660 template <class _Up, class _QualUp>
661 using _CheckOptionalLikeCtor _LIBCPP_NODEBUG =
662 _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp> >::value,
663 _CheckOptionalLikeConstructor<_QualUp>,
664 __check_tuple_constructor_fail >;
665 template <class _Up, class _QualUp>
666 using _CheckOptionalLikeAssign _LIBCPP_NODEBUG =
667 _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp>, is_assignable<_Tp&, _QualUp> >::value,
668 _CheckOptionalLikeConstructor<_QualUp>,
669 __check_tuple_constructor_fail >;
670
671public:
672 _LIBCPP_HIDE_FROM_ABI constexpr optional() noexcept {}
673 _LIBCPP_HIDE_FROM_ABI constexpr optional(const optional&) = default;
674 _LIBCPP_HIDE_FROM_ABI constexpr optional(optional&&) = default;
675 _LIBCPP_HIDE_FROM_ABI constexpr optional(nullopt_t) noexcept {}
676
677 template <class _InPlaceT,
678 class... _Args,
679 enable_if_t<_And<_IsSame<_InPlaceT, in_place_t>, is_constructible<value_type, _Args...>>::value, int> = 0>
680 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args)
681 : __base(in_place, std::forward<_Args>(__args)...) {}
682
683 template <class _Up,
684 class... _Args,
685 enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0>
686 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
687 : __base(in_place, __il, std::forward<_Args>(__args)...) {}
688
689 template <class _Up = value_type,
690 enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
691 _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
692
693 template <class _Up, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
694 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
695
696 // LWG2756: conditionally explicit conversion from const optional<_Up>&
697 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
698 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) {
699 this->__construct_from(__v);
700 }
701 template <class _Up, 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);
704 }
705
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));
710 }
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));
714 }
715
716# if _LIBCPP_STD_VER >= 23
717 template <class _Tag,
718 class _Fp,
719 class... _Args,
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)...) {}
723# endif
724
725 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept {
726 reset();
727 return *this;
728 }
729
730 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default;
731 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
732
733 // LWG2756
734 template <class _Up = value_type,
735 enable_if_t<_And<_IsNotSame<__remove_cvref_t<_Up>, optional>,
736 _Or<_IsNotSame<__remove_cvref_t<_Up>, value_type>, _Not<is_scalar<value_type>>>,
737 is_constructible<value_type, _Up>,
738 is_assignable<value_type&, _Up>>::value,
739 int> = 0>
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);
743 else
744 this->__construct(std::forward<_Up>(__v));
745 return *this;
746 }
747
748 // LWG2756
749 template <class _Up, enable_if_t<_CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>(), int> = 0>
750 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(const optional<_Up>& __v) {
751 this->__assign_from(__v);
752 return *this;
753 }
754
755 // LWG2756
756 template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_assign<_Up>(), int> = 0>
757 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(optional<_Up>&& __v) {
758 this->__assign_from(std::move(__v));
759 return *this;
760 }
761
762 template <class... _Args, enable_if_t<is_constructible_v<value_type, _Args...>, int> = 0>
763 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
764 reset();
765 this->__construct(std::forward<_Args>(__args)...);
766 return this->__get();
767 }
768
769 template <class _Up,
770 class... _Args,
771 enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0>
772 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
773 reset();
774 this->__construct(__il, std::forward<_Args>(__args)...);
775 return this->__get();
776 }
777
778 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
779 swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>) {
780 if (this->has_value() == __opt.has_value()) {
781 using std::swap;
782 if (this->has_value())
783 swap(this->__get(), __opt.__get());
784 } else {
785 if (this->has_value()) {
786 __opt.__construct(std::move(this->__get()));
787 reset();
788 } else {
789 this->__construct(std::move(__opt.__get()));
790 __opt.reset();
791 }
792 }
793 }
794
795 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept {
796 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
797 return std::addressof(this->__get());
798 }
799
800 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept {
801 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
802 return std::addressof(this->__get());
803 }
804
805 _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept {
806 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
807 return this->__get();
808 }
809
810 _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept {
811 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
812 return this->__get();
813 }
814
815 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept {
816 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
817 return std::move(this->__get());
818 }
819
820 _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept {
821 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
822 return std::move(this->__get());
823 }
824
825 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return has_value(); }
826
827 using __base::__get;
828 using __base::has_value;
829
830 _LIBCPP_HIDE_FROM_ABI constexpr value_type const& value() const& {
831 if (!this->has_value())
832 std::__throw_bad_optional_access();
833 return this->__get();
834 }
835
836 _LIBCPP_HIDE_FROM_ABI constexpr value_type& value() & {
837 if (!this->has_value())
838 std::__throw_bad_optional_access();
839 return this->__get();
840 }
841
842 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& value() && {
843 if (!this->has_value())
844 std::__throw_bad_optional_access();
845 return std::move(this->__get());
846 }
847
848 _LIBCPP_HIDE_FROM_ABI constexpr value_type const&& value() const&& {
849 if (!this->has_value())
850 std::__throw_bad_optional_access();
851 return std::move(this->__get());
852 }
853
854 template <class _Up>
855 _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) const& {
856 static_assert(is_copy_constructible_v<value_type>, "optional<T>::value_or: T must be copy constructible");
857 static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
858 return this->has_value() ? this->__get() : static_cast<value_type>(std::forward<_Up>(__v));
859 }
860
861 template <class _Up>
862 _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) && {
863 static_assert(is_move_constructible_v<value_type>, "optional<T>::value_or: T must be move constructible");
864 static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
865 return this->has_value() ? std::move(this->__get()) : static_cast<value_type>(std::forward<_Up>(__v));
866 }
867
868# if _LIBCPP_STD_VER >= 23
869 template <class _Func>
870 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
871 using _Up = invoke_result_t<_Func, value_type&>;
872 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
873 "Result of f(value()) must be a specialization of std::optional");
874 if (*this)
875 return std::invoke(std::forward<_Func>(__f), value());
876 return remove_cvref_t<_Up>();
877 }
878
879 template <class _Func>
880 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
881 using _Up = invoke_result_t<_Func, const value_type&>;
882 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
883 "Result of f(value()) must be a specialization of std::optional");
884 if (*this)
885 return std::invoke(std::forward<_Func>(__f), value());
886 return remove_cvref_t<_Up>();
887 }
888
889 template <class _Func>
890 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
891 using _Up = invoke_result_t<_Func, value_type&&>;
892 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
893 "Result of f(std::move(value())) must be a specialization of std::optional");
894 if (*this)
895 return std::invoke(std::forward<_Func>(__f), std::move(value()));
896 return remove_cvref_t<_Up>();
897 }
898
899 template <class _Func>
900 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
901 using _Up = invoke_result_t<_Func, const value_type&&>;
902 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
903 "Result of f(std::move(value())) must be a specialization of std::optional");
904 if (*this)
905 return std::invoke(std::forward<_Func>(__f), std::move(value()));
906 return remove_cvref_t<_Up>();
907 }
908
909 template <class _Func>
910 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
911 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
912 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
913 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
914 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
915 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
916 if (*this)
917 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
918 return optional<_Up>();
919 }
920
921 template <class _Func>
922 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
923 using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
924 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
925 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
926 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
927 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
928 if (*this)
929 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
930 return optional<_Up>();
931 }
932
933 template <class _Func>
934 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
935 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
936 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
937 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
938 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
939 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
940 if (*this)
941 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
942 return optional<_Up>();
943 }
944
945 template <class _Func>
946 _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
947 using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
948 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
949 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
950 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
951 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
952 if (*this)
953 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
954 return optional<_Up>();
955 }
956
957 template <invocable _Func>
958 _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
959 requires is_copy_constructible_v<value_type>
960 {
961 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
962 "Result of f() should be the same type as this optional");
963 if (*this)
964 return *this;
965 return std::forward<_Func>(__f)();
966 }
967
968 template <invocable _Func>
969 _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
970 requires is_move_constructible_v<value_type>
971 {
972 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
973 "Result of f() should be the same type as this optional");
974 if (*this)
975 return std::move(*this);
976 return std::forward<_Func>(__f)();
977 }
978# endif // _LIBCPP_STD_VER >= 23
979
980 using __base::reset;
981};
982
983template <class _Tp>
984optional(_Tp) -> optional<_Tp>;
985
986// [optional.relops] Relational operators
987
988template <
989 class _Tp,
990 class _Up,
991 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
992 int> = 0>
993_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y) {
994 if (static_cast<bool>(__x) != static_cast<bool>(__y))
995 return false;
996 if (!static_cast<bool>(__x))
997 return true;
998 return *__x == *__y;
999}
1000
1001template <
1002 class _Tp,
1003 class _Up,
1004 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
1005 int> = 0>
1006_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1007 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1008 return true;
1009 if (!static_cast<bool>(__x))
1010 return false;
1011 return *__x != *__y;
1012}
1013
1014template < class _Tp,
1015 class _Up,
1016 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
1017 int> = 0>
1018_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const optional<_Up>& __y) {
1019 if (!static_cast<bool>(__y))
1020 return false;
1021 if (!static_cast<bool>(__x))
1022 return true;
1023 return *__x < *__y;
1024}
1025
1026template < class _Tp,
1027 class _Up,
1028 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
1029 int> = 0>
1030_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1031 if (!static_cast<bool>(__x))
1032 return false;
1033 if (!static_cast<bool>(__y))
1034 return true;
1035 return *__x > *__y;
1036}
1037
1038template <
1039 class _Tp,
1040 class _Up,
1041 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
1042 int> = 0>
1043_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1044 if (!static_cast<bool>(__x))
1045 return true;
1046 if (!static_cast<bool>(__y))
1047 return false;
1048 return *__x <= *__y;
1049}
1050
1051template <
1052 class _Tp,
1053 class _Up,
1054 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
1055 int> = 0>
1056_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1057 if (!static_cast<bool>(__y))
1058 return true;
1059 if (!static_cast<bool>(__x))
1060 return false;
1061 return *__x >= *__y;
1062}
1063
1064# if _LIBCPP_STD_VER >= 20
1065
1066template <class _Tp, three_way_comparable_with<_Tp> _Up>
1067_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1068operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1069 if (__x && __y)
1070 return *__x <=> *__y;
1071 return __x.has_value() <=> __y.has_value();
1072}
1073
1074# endif // _LIBCPP_STD_VER >= 20
1075
1076// [optional.nullops] Comparison with nullopt
1077
1078template <class _Tp>
1079_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept {
1080 return !static_cast<bool>(__x);
1081}
1082
1083# if _LIBCPP_STD_VER <= 17
1084
1085template <class _Tp>
1086_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(nullopt_t, const optional<_Tp>& __x) noexcept {
1087 return !static_cast<bool>(__x);
1088}
1089
1090template <class _Tp>
1091_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, nullopt_t) noexcept {
1092 return static_cast<bool>(__x);
1093}
1094
1095template <class _Tp>
1096_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(nullopt_t, const optional<_Tp>& __x) noexcept {
1097 return static_cast<bool>(__x);
1098}
1099
1100template <class _Tp>
1101_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>&, nullopt_t) noexcept {
1102 return false;
1103}
1104
1105template <class _Tp>
1106_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(nullopt_t, const optional<_Tp>& __x) noexcept {
1107 return static_cast<bool>(__x);
1108}
1109
1110template <class _Tp>
1111_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, nullopt_t) noexcept {
1112 return !static_cast<bool>(__x);
1113}
1114
1115template <class _Tp>
1116_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(nullopt_t, const optional<_Tp>&) noexcept {
1117 return true;
1118}
1119
1120template <class _Tp>
1121_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, nullopt_t) noexcept {
1122 return static_cast<bool>(__x);
1123}
1124
1125template <class _Tp>
1126_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(nullopt_t, const optional<_Tp>&) noexcept {
1127 return false;
1128}
1129
1130template <class _Tp>
1131_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>&, nullopt_t) noexcept {
1132 return true;
1133}
1134
1135template <class _Tp>
1136_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(nullopt_t, const optional<_Tp>& __x) noexcept {
1137 return !static_cast<bool>(__x);
1138}
1139
1140# else // _LIBCPP_STD_VER <= 17
1141
1142template <class _Tp>
1143_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept {
1144 return __x.has_value() <=> false;
1145}
1146
1147# endif // _LIBCPP_STD_VER <= 17
1148
1149// [optional.comp.with.t] Comparison with T
1150
1151template <
1152 class _Tp,
1153 class _Up,
1154 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
1155 int> = 0>
1156_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const _Up& __v) {
1157 return static_cast<bool>(__x) ? *__x == __v : false;
1158}
1159
1160template <
1161 class _Tp,
1162 class _Up,
1163 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
1164 int> = 0>
1165_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __v, const optional<_Up>& __x) {
1166 return static_cast<bool>(__x) ? __v == *__x : false;
1167}
1168
1169template <
1170 class _Tp,
1171 class _Up,
1172 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
1173 int> = 0>
1174_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const _Up& __v) {
1175 return static_cast<bool>(__x) ? *__x != __v : true;
1176}
1177
1178template <
1179 class _Tp,
1180 class _Up,
1181 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
1182 int> = 0>
1183_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __v, const optional<_Up>& __x) {
1184 return static_cast<bool>(__x) ? __v != *__x : true;
1185}
1186
1187template < class _Tp,
1188 class _Up,
1189 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
1190 int> = 0>
1191_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const _Up& __v) {
1192 return static_cast<bool>(__x) ? *__x < __v : true;
1193}
1194
1195template < class _Tp,
1196 class _Up,
1197 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
1198 int> = 0>
1199_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __v, const optional<_Up>& __x) {
1200 return static_cast<bool>(__x) ? __v < *__x : false;
1201}
1202
1203template <
1204 class _Tp,
1205 class _Up,
1206 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
1207 int> = 0>
1208_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const _Up& __v) {
1209 return static_cast<bool>(__x) ? *__x <= __v : true;
1210}
1211
1212template <
1213 class _Tp,
1214 class _Up,
1215 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
1216 int> = 0>
1217_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_Up>& __x) {
1218 return static_cast<bool>(__x) ? __v <= *__x : false;
1219}
1220
1221template < class _Tp,
1222 class _Up,
1223 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
1224 int> = 0>
1225_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const _Up& __v) {
1226 return static_cast<bool>(__x) ? *__x > __v : false;
1227}
1228
1229template < class _Tp,
1230 class _Up,
1231 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
1232 int> = 0>
1233_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __v, const optional<_Up>& __x) {
1234 return static_cast<bool>(__x) ? __v > *__x : true;
1235}
1236
1237template <
1238 class _Tp,
1239 class _Up,
1240 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
1241 int> = 0>
1242_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const _Up& __v) {
1243 return static_cast<bool>(__x) ? *__x >= __v : false;
1244}
1245
1246template <
1247 class _Tp,
1248 class _Up,
1249 enable_if_t<__is_core_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
1250 int> = 0>
1251_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __v, const optional<_Up>& __x) {
1252 return static_cast<bool>(__x) ? __v >= *__x : true;
1253}
1254
1255# if _LIBCPP_STD_VER >= 20
1256
1257template <class _Tp, class _Up>
1258 requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up>
1259_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1260operator<=>(const optional<_Tp>& __x, const _Up& __v) {
1261 return __x.has_value() ? *__x <=> __v : strong_ordering::less;
1262}
1263
1264# endif // _LIBCPP_STD_VER >= 20
1265
1266template <class _Tp, enable_if_t< is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, int> = 0>
1267inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
1268swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) {
1269 __x.swap(__y);
1270}
1271
1272template <class _Tp>
1273_LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) {
1274 return optional<decay_t<_Tp>>(std::forward<_Tp>(__v));
1275}
1276
1277template <class _Tp, class... _Args>
1278_LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) {
1279 return optional<_Tp>(in_place, std::forward<_Args>(__args)...);
1280}
1281
1282template <class _Tp, class _Up, class... _Args>
1283_LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) {
1284 return optional<_Tp>(in_place, __il, std::forward<_Args>(__args)...);
1285}
1286
1287template <class _Tp>
1288struct hash< __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> > {
1289# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1290 _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
1291 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1292# endif
1293
1294 _LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const {
1295 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1296 }
1297};
1298
1299_LIBCPP_END_NAMESPACE_STD
1300
1301# endif // _LIBCPP_STD_VER >= 17
1302
1303_LIBCPP_POP_MACROS
1304
1305# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1306# include <atomic>
1307# include <climits>
1308# include <concepts>
1309# include <ctime>
1310# include <iterator>
1311# include <limits>
1312# include <memory>
1313# include <ratio>
1314# include <stdexcept>
1315# include <tuple>
1316# include <type_traits>
1317# include <typeinfo>
1318# include <utility>
1319# include <variant>
1320# endif
1321#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
1322
1323#endif // _LIBCPP_OPTIONAL