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