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