zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob 73da0a8a (53440B) - Raw


      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 
     18 namespace 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 
    245 namespace std // purposefully not using versioning namespace
    246 {
    247 
    248 class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access : public exception {
    249 public:
    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 
    273 struct 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 
    280 inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
    281 
    282 struct __optional_construct_from_invoke_tag {};
    283 
    284 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
    285 struct __optional_destruct_base;
    286 
    287 template <class _Tp>
    288 struct __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 
    323 template <class _Tp>
    324 struct __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 
    353 template <class _Tp, bool = is_reference<_Tp>::value>
    354 struct __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.
    396 template <class _Tp>
    397 struct __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 
    465 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
    466 struct __optional_copy_base : __optional_storage_base<_Tp> {
    467   using __optional_storage_base<_Tp>::__optional_storage_base;
    468 };
    469 
    470 template <class _Tp>
    471 struct __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 
    485 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
    486 struct __optional_move_base : __optional_copy_base<_Tp> {
    487   using __optional_copy_base<_Tp>::__optional_copy_base;
    488 };
    489 
    490 template <class _Tp>
    491 struct __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 
    507 template <class _Tp,
    508           bool = is_trivially_destructible<_Tp>::value && is_trivially_copy_constructible<_Tp>::value &&
    509                  is_trivially_copy_assignable<_Tp>::value>
    510 struct __optional_copy_assign_base : __optional_move_base<_Tp> {
    511   using __optional_move_base<_Tp>::__optional_move_base;
    512 };
    513 
    514 template <class _Tp>
    515 struct __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 
    531 template <class _Tp,
    532           bool = is_trivially_destructible<_Tp>::value && is_trivially_move_constructible<_Tp>::value &&
    533                  is_trivially_move_assignable<_Tp>::value>
    534 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> {
    535   using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
    536 };
    537 
    538 template <class _Tp>
    539 struct __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 
    556 template <class _Tp>
    557 using __optional_sfinae_ctor_base_t =
    558     __sfinae_ctor_base< is_copy_constructible<_Tp>::value, is_move_constructible<_Tp>::value >;
    559 
    560 template <class _Tp>
    561 using __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 
    565 template <class _Tp>
    566 class optional;
    567 
    568 #  if _LIBCPP_STD_VER >= 20
    569 
    570 template <class _Tp>
    571 concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
    572 
    573 #  endif // _LIBCPP_STD_VER >= 20
    574 
    575 template <class _Tp>
    576 struct __is_std_optional : false_type {};
    577 template <class _Tp>
    578 struct __is_std_optional<optional<_Tp>> : true_type {};
    579 
    580 template <class _Tp>
    581 class _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 
    587 public:
    588   using value_type = _Tp;
    589 
    590 private:
    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 
    665 public:
    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
    979 template <class _Tp>
    980 optional(_Tp) -> optional<_Tp>;
    981 #  endif
    982 
    983 // Comparisons between optionals
    984 template <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 >
    988 operator==(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 
    996 template <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 >
   1000 operator!=(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 
   1008 template <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 >
   1012 operator<(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 
   1020 template <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 >
   1024 operator>(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 
   1032 template <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 >
   1036 operator<=(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 
   1044 template <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 >
   1048 operator>=(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 
   1058 template <class _Tp, three_way_comparable_with<_Tp> _Up>
   1059 _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
   1060 operator<=>(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
   1069 template <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 
   1076 template <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 
   1081 template <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 
   1086 template <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 
   1091 template <class _Tp>
   1092 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>&, nullopt_t) noexcept {
   1093   return false;
   1094 }
   1095 
   1096 template <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 
   1101 template <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 
   1106 template <class _Tp>
   1107 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(nullopt_t, const optional<_Tp>&) noexcept {
   1108   return true;
   1109 }
   1110 
   1111 template <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 
   1116 template <class _Tp>
   1117 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(nullopt_t, const optional<_Tp>&) noexcept {
   1118   return false;
   1119 }
   1120 
   1121 template <class _Tp>
   1122 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>&, nullopt_t) noexcept {
   1123   return true;
   1124 }
   1125 
   1126 template <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 
   1133 template <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
   1141 template <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 >
   1145 operator==(const optional<_Tp>& __x, const _Up& __v) {
   1146   return static_cast<bool>(__x) ? *__x == __v : false;
   1147 }
   1148 
   1149 template <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 >
   1153 operator==(const _Tp& __v, const optional<_Up>& __x) {
   1154   return static_cast<bool>(__x) ? __v == *__x : false;
   1155 }
   1156 
   1157 template <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 >
   1161 operator!=(const optional<_Tp>& __x, const _Up& __v) {
   1162   return static_cast<bool>(__x) ? *__x != __v : true;
   1163 }
   1164 
   1165 template <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 >
   1169 operator!=(const _Tp& __v, const optional<_Up>& __x) {
   1170   return static_cast<bool>(__x) ? __v != *__x : true;
   1171 }
   1172 
   1173 template <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 >
   1177 operator<(const optional<_Tp>& __x, const _Up& __v) {
   1178   return static_cast<bool>(__x) ? *__x < __v : true;
   1179 }
   1180 
   1181 template <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 >
   1185 operator<(const _Tp& __v, const optional<_Up>& __x) {
   1186   return static_cast<bool>(__x) ? __v < *__x : false;
   1187 }
   1188 
   1189 template <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 >
   1193 operator<=(const optional<_Tp>& __x, const _Up& __v) {
   1194   return static_cast<bool>(__x) ? *__x <= __v : true;
   1195 }
   1196 
   1197 template <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 >
   1201 operator<=(const _Tp& __v, const optional<_Up>& __x) {
   1202   return static_cast<bool>(__x) ? __v <= *__x : false;
   1203 }
   1204 
   1205 template <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 >
   1209 operator>(const optional<_Tp>& __x, const _Up& __v) {
   1210   return static_cast<bool>(__x) ? *__x > __v : false;
   1211 }
   1212 
   1213 template <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 >
   1217 operator>(const _Tp& __v, const optional<_Up>& __x) {
   1218   return static_cast<bool>(__x) ? __v > *__x : true;
   1219 }
   1220 
   1221 template <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 >
   1225 operator>=(const optional<_Tp>& __x, const _Up& __v) {
   1226   return static_cast<bool>(__x) ? *__x >= __v : false;
   1227 }
   1228 
   1229 template <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 >
   1233 operator>=(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 
   1239 template <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>
   1242 operator<=>(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 
   1248 template <class _Tp>
   1249 inline _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 
   1255 template <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 
   1260 template <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 
   1265 template <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 
   1270 template <class _Tp>
   1271 struct _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