xref: /freebsd/contrib/llvm-project/libcxx/include/optional (revision 9c77fb6aaa366cbabc80ee1b834bcfe4df135491)
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
1324