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