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