Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/c++/v1/__cxx03/optional is written in an unsupported language. File is not indexed.

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___CXX03_OPTIONAL
0011 #define _LIBCPP___CXX03_OPTIONAL
0012 
0013 /*
0014     optional synopsis
0015 
0016 // C++1z
0017 
0018 namespace std {
0019   // [optional.optional], class template optional
0020   template <class T>
0021     class optional;
0022 
0023   template<class T>
0024     concept is-derived-from-optional = requires(const T& t) {       // exposition only
0025       []<class U>(const optional<U>&){ }(t);
0026     };
0027 
0028   // [optional.nullopt], no-value state indicator
0029   struct nullopt_t{see below };
0030   inline constexpr nullopt_t nullopt(unspecified );
0031 
0032   // [optional.bad.access], class bad_optional_access
0033   class bad_optional_access;
0034 
0035   // [optional.relops], relational operators
0036   template <class T, class U>
0037     constexpr bool operator==(const optional<T>&, const optional<U>&);
0038   template <class T, class U>
0039     constexpr bool operator!=(const optional<T>&, const optional<U>&);
0040   template <class T, class U>
0041     constexpr bool operator<(const optional<T>&, const optional<U>&);
0042   template <class T, class U>
0043     constexpr bool operator>(const optional<T>&, const optional<U>&);
0044   template <class T, class U>
0045     constexpr bool operator<=(const optional<T>&, const optional<U>&);
0046   template <class T, class U>
0047     constexpr bool operator>=(const optional<T>&, const optional<U>&);
0048   template<class T, three_way_comparable_with<T> U>
0049     constexpr compare_three_way_result_t<T, U>
0050       operator<=>(const optional<T>&, const optional<U>&); // since C++20
0051 
0052   // [optional.nullops], comparison with nullopt
0053   template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
0054   template<class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; // until C++17
0055   template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; // until C++17
0056   template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; // until C++17
0057   template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;  // until C++17
0058   template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;  // until C++17
0059   template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; // until C++17
0060   template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; // until C++17
0061   template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;  // until C++17
0062   template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;  // until C++17
0063   template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; // until C++17
0064   template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; // until C++17
0065   template<class T>
0066     constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept;     // since C++20
0067 
0068   // [optional.comp.with.t], comparison with T
0069   template<class T, class U> constexpr bool operator==(const optional<T>&, const U&);
0070   template<class T, class U> constexpr bool operator==(const T&, const optional<U>&);
0071   template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
0072   template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
0073   template<class T, class U> constexpr bool operator<(const optional<T>&, const U&);
0074   template<class T, class U> constexpr bool operator<(const T&, const optional<U>&);
0075   template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
0076   template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
0077   template<class T, class U> constexpr bool operator>(const optional<T>&, const U&);
0078   template<class T, class U> constexpr bool operator>(const T&, const optional<U>&);
0079   template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
0080   template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
0081   template<class T, class U>
0082       requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U>
0083     constexpr compare_three_way_result_t<T, U>
0084       operator<=>(const optional<T>&, const U&);                                       // since C++20
0085 
0086   // [optional.specalg], specialized algorithms
0087   template<class T>
0088     void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
0089 
0090   template<class T>
0091     constexpr optional<see below > make_optional(T&&);
0092   template<class T, class... Args>
0093     constexpr optional<T> make_optional(Args&&... args);
0094   template<class T, class U, class... Args>
0095     constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
0096 
0097   // [optional.hash], hash support
0098   template<class T> struct hash;
0099   template<class T> struct hash<optional<T>>;
0100 
0101   template<class T>
0102   class optional {
0103   public:
0104     using value_type = T;
0105 
0106     // [optional.ctor], constructors
0107     constexpr optional() noexcept;
0108     constexpr optional(nullopt_t) noexcept;
0109     constexpr optional(const optional &);
0110     constexpr optional(optional &&) noexcept(see below);
0111     template<class... Args>
0112       constexpr explicit optional(in_place_t, Args &&...);
0113     template<class U, class... Args>
0114       constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
0115     template<class U = T>
0116       constexpr explicit(see-below) optional(U &&);
0117     template<class U>
0118       explicit(see-below) optional(const optional<U> &);                          // constexpr in C++20
0119     template<class U>
0120       explicit(see-below) optional(optional<U> &&);                               // constexpr in C++20
0121 
0122     // [optional.dtor], destructor
0123     ~optional(); // constexpr in C++20
0124 
0125     // [optional.assign], assignment
0126     optional &operator=(nullopt_t) noexcept;                                      // constexpr in C++20
0127     constexpr optional &operator=(const optional &);
0128     constexpr optional &operator=(optional &&) noexcept(see below);
0129     template<class U = T> optional &operator=(U &&);                              // constexpr in C++20
0130     template<class U> optional &operator=(const optional<U> &);                   // constexpr in C++20
0131     template<class U> optional &operator=(optional<U> &&);                        // constexpr in C++20
0132     template<class... Args> T& emplace(Args &&...);                               // constexpr in C++20
0133     template<class U, class... Args> T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
0134 
0135     // [optional.swap], swap
0136     void swap(optional &) noexcept(see below ); // constexpr in C++20
0137 
0138     // [optional.observe], observers
0139     constexpr T const *operator->() const noexcept;
0140     constexpr T *operator->() noexcept;
0141     constexpr T const &operator*() const & noexcept;
0142     constexpr T &operator*() & noexcept;
0143     constexpr T &&operator*() && noexcept;
0144     constexpr const T &&operator*() const && noexcept;
0145     constexpr explicit operator bool() const noexcept;
0146     constexpr bool has_value() const noexcept;
0147     constexpr T const &value() const &;
0148     constexpr T &value() &;
0149     constexpr T &&value() &&;
0150     constexpr const T &&value() const &&;
0151     template<class U> constexpr T value_or(U &&) const &;
0152     template<class U> constexpr T value_or(U &&) &&;
0153 
0154     // [optional.monadic], monadic operations
0155     template<class F> constexpr auto and_then(F&& f) &;         // since C++23
0156     template<class F> constexpr auto and_then(F&& f) &&;        // since C++23
0157     template<class F> constexpr auto and_then(F&& f) const&;    // since C++23
0158     template<class F> constexpr auto and_then(F&& f) const&&;   // since C++23
0159     template<class F> constexpr auto transform(F&& f) &;        // since C++23
0160     template<class F> constexpr auto transform(F&& f) &&;       // since C++23
0161     template<class F> constexpr auto transform(F&& f) const&;   // since C++23
0162     template<class F> constexpr auto transform(F&& f) const&&;  // since C++23
0163     template<class F> constexpr optional or_else(F&& f) &&;     // since C++23
0164     template<class F> constexpr optional or_else(F&& f) const&; // since C++23
0165 
0166     // [optional.mod], modifiers
0167     void reset() noexcept;                                      // constexpr in C++20
0168 
0169   private:
0170     T *val;         // exposition only
0171   };
0172 
0173   template<class T>
0174     optional(T) -> optional<T>;
0175 
0176 } // namespace std
0177 
0178 */
0179 
0180 #include <__cxx03/__assert>
0181 #include <__cxx03/__compare/compare_three_way_result.h>
0182 #include <__cxx03/__compare/three_way_comparable.h>
0183 #include <__cxx03/__concepts/invocable.h>
0184 #include <__cxx03/__config>
0185 #include <__cxx03/__exception/exception.h>
0186 #include <__cxx03/__functional/hash.h>
0187 #include <__cxx03/__functional/invoke.h>
0188 #include <__cxx03/__functional/unary_function.h>
0189 #include <__cxx03/__fwd/functional.h>
0190 #include <__cxx03/__memory/addressof.h>
0191 #include <__cxx03/__memory/construct_at.h>
0192 #include <__cxx03/__tuple/sfinae_helpers.h>
0193 #include <__cxx03/__type_traits/add_pointer.h>
0194 #include <__cxx03/__type_traits/conditional.h>
0195 #include <__cxx03/__type_traits/conjunction.h>
0196 #include <__cxx03/__type_traits/decay.h>
0197 #include <__cxx03/__type_traits/disjunction.h>
0198 #include <__cxx03/__type_traits/is_array.h>
0199 #include <__cxx03/__type_traits/is_assignable.h>
0200 #include <__cxx03/__type_traits/is_constructible.h>
0201 #include <__cxx03/__type_traits/is_convertible.h>
0202 #include <__cxx03/__type_traits/is_destructible.h>
0203 #include <__cxx03/__type_traits/is_nothrow_assignable.h>
0204 #include <__cxx03/__type_traits/is_nothrow_constructible.h>
0205 #include <__cxx03/__type_traits/is_object.h>
0206 #include <__cxx03/__type_traits/is_reference.h>
0207 #include <__cxx03/__type_traits/is_scalar.h>
0208 #include <__cxx03/__type_traits/is_swappable.h>
0209 #include <__cxx03/__type_traits/is_trivially_assignable.h>
0210 #include <__cxx03/__type_traits/is_trivially_constructible.h>
0211 #include <__cxx03/__type_traits/is_trivially_destructible.h>
0212 #include <__cxx03/__type_traits/is_trivially_relocatable.h>
0213 #include <__cxx03/__type_traits/negation.h>
0214 #include <__cxx03/__type_traits/remove_const.h>
0215 #include <__cxx03/__type_traits/remove_cvref.h>
0216 #include <__cxx03/__type_traits/remove_reference.h>
0217 #include <__cxx03/__utility/declval.h>
0218 #include <__cxx03/__utility/forward.h>
0219 #include <__cxx03/__utility/in_place.h>
0220 #include <__cxx03/__utility/move.h>
0221 #include <__cxx03/__utility/swap.h>
0222 #include <__cxx03/__verbose_abort>
0223 #include <__cxx03/initializer_list>
0224 #include <__cxx03/new>
0225 #include <__cxx03/version>
0226 
0227 // standard-mandated includes
0228 
0229 // [optional.syn]
0230 #include <__cxx03/compare>
0231 
0232 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0233 #  pragma GCC system_header
0234 #endif
0235 
0236 _LIBCPP_PUSH_MACROS
0237 #include <__cxx03/__undef_macros>
0238 
0239 namespace std // purposefully not using versioning namespace
0240 {
0241 
0242 class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access : public exception {
0243 public:
0244   _LIBCPP_HIDE_FROM_ABI bad_optional_access() _NOEXCEPT                                      = default;
0245   _LIBCPP_HIDE_FROM_ABI bad_optional_access(const bad_optional_access&) _NOEXCEPT            = default;
0246   _LIBCPP_HIDE_FROM_ABI bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default;
0247   // Get the key function ~bad_optional_access() into the dylib
0248   ~bad_optional_access() _NOEXCEPT override;
0249   const char* what() const _NOEXCEPT override;
0250 };
0251 
0252 } // namespace std
0253 
0254 #if _LIBCPP_STD_VER >= 17
0255 
0256 _LIBCPP_BEGIN_NAMESPACE_STD
0257 
0258 _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS void
0259 __throw_bad_optional_access() {
0260 #  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
0261   throw bad_optional_access();
0262 #  else
0263   _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
0264 #  endif
0265 }
0266 
0267 struct nullopt_t {
0268   struct __secret_tag {
0269     explicit __secret_tag() = default;
0270   };
0271   _LIBCPP_HIDE_FROM_ABI constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
0272 };
0273 
0274 inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
0275 
0276 struct __optional_construct_from_invoke_tag {};
0277 
0278 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
0279 struct __optional_destruct_base;
0280 
0281 template <class _Tp>
0282 struct __optional_destruct_base<_Tp, false> {
0283   typedef _Tp value_type;
0284   static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
0285   union {
0286     char __null_state_;
0287     value_type __val_;
0288   };
0289   bool __engaged_;
0290 
0291   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base() {
0292     if (__engaged_)
0293       __val_.~value_type();
0294   }
0295 
0296   _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {}
0297 
0298   template <class... _Args>
0299   _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
0300       : __val_(std::forward<_Args>(__args)...), __engaged_(true) {}
0301 
0302 #  if _LIBCPP_STD_VER >= 23
0303   template <class _Fp, class... _Args>
0304   _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(
0305       __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
0306       : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {}
0307 #  endif
0308 
0309   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept {
0310     if (__engaged_) {
0311       __val_.~value_type();
0312       __engaged_ = false;
0313     }
0314   }
0315 };
0316 
0317 template <class _Tp>
0318 struct __optional_destruct_base<_Tp, true> {
0319   typedef _Tp value_type;
0320   static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
0321   union {
0322     char __null_state_;
0323     value_type __val_;
0324   };
0325   bool __engaged_;
0326 
0327   _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {}
0328 
0329   template <class... _Args>
0330   _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
0331       : __val_(std::forward<_Args>(__args)...), __engaged_(true) {}
0332 
0333 #  if _LIBCPP_STD_VER >= 23
0334   template <class _Fp, class... _Args>
0335   _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base(
0336       __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
0337       : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {}
0338 #  endif
0339 
0340   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept {
0341     if (__engaged_) {
0342       __engaged_ = false;
0343     }
0344   }
0345 };
0346 
0347 template <class _Tp, bool = is_reference<_Tp>::value>
0348 struct __optional_storage_base : __optional_destruct_base<_Tp> {
0349   using __base     = __optional_destruct_base<_Tp>;
0350   using value_type = _Tp;
0351   using __base::__base;
0352 
0353   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; }
0354 
0355   _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() & noexcept { return this->__val_; }
0356   _LIBCPP_HIDE_FROM_ABI constexpr const value_type& __get() const& noexcept { return this->__val_; }
0357   _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() && noexcept { return std::move(this->__val_); }
0358   _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& __get() const&& noexcept { return std::move(this->__val_); }
0359 
0360   template <class... _Args>
0361   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) {
0362     _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
0363     std::__construct_at(std::addressof(this->__val_), std::forward<_Args>(__args)...);
0364     this->__engaged_ = true;
0365   }
0366 
0367   template <class _That>
0368   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) {
0369     if (__opt.has_value())
0370       __construct(std::forward<_That>(__opt).__get());
0371   }
0372 
0373   template <class _That>
0374   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) {
0375     if (this->__engaged_ == __opt.has_value()) {
0376       if (this->__engaged_)
0377         this->__val_ = std::forward<_That>(__opt).__get();
0378     } else {
0379       if (this->__engaged_)
0380         this->reset();
0381       else
0382         __construct(std::forward<_That>(__opt).__get());
0383     }
0384   }
0385 };
0386 
0387 // optional<T&> is currently required to be ill-formed. However, it may
0388 // be allowed in the future. For this reason, it has already been implemented
0389 // to ensure we can make the change in an ABI-compatible manner.
0390 template <class _Tp>
0391 struct __optional_storage_base<_Tp, true> {
0392   using value_type = _Tp;
0393   using __raw_type = remove_reference_t<_Tp>;
0394   __raw_type* __value_;
0395 
0396   template <class _Up>
0397   static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
0398     using _RawUp = __libcpp_remove_reference_t<_Up>;
0399     using _UpPtr = _RawUp*;
0400     using _RawTp = __libcpp_remove_reference_t<_Tp>;
0401     using _TpPtr = _RawTp*;
0402     using _CheckLValueArg =
0403         integral_constant<bool,
0404                           (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) ||
0405                               is_same<_RawUp, reference_wrapper<_RawTp>>::value ||
0406                               is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value >;
0407     return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) ||
0408            (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
0409             is_convertible<_UpPtr, _TpPtr>::value);
0410   }
0411 
0412   _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {}
0413 
0414   template <class _UArg>
0415   _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
0416       : __value_(std::addressof(__uarg)) {
0417     static_assert(__can_bind_reference<_UArg>(),
0418                   "Attempted to construct a reference element in tuple from a "
0419                   "possible temporary");
0420   }
0421 
0422   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }
0423 
0424   _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __value_ != nullptr; }
0425 
0426   _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() const& noexcept { return *__value_; }
0427 
0428   _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() const&& noexcept { return std::forward<value_type>(*__value_); }
0429 
0430   template <class _UArg>
0431   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) {
0432     _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
0433     static_assert(__can_bind_reference<_UArg>(),
0434                   "Attempted to construct a reference element in tuple from a "
0435                   "possible temporary");
0436     __value_ = std::addressof(__val);
0437   }
0438 
0439   template <class _That>
0440   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) {
0441     if (__opt.has_value())
0442       __construct(std::forward<_That>(__opt).__get());
0443   }
0444 
0445   template <class _That>
0446   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) {
0447     if (has_value() == __opt.has_value()) {
0448       if (has_value())
0449         *__value_ = std::forward<_That>(__opt).__get();
0450     } else {
0451       if (has_value())
0452         reset();
0453       else
0454         __construct(std::forward<_That>(__opt).__get());
0455     }
0456   }
0457 };
0458 
0459 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
0460 struct __optional_copy_base : __optional_storage_base<_Tp> {
0461   using __optional_storage_base<_Tp>::__optional_storage_base;
0462 };
0463 
0464 template <class _Tp>
0465 struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> {
0466   using __optional_storage_base<_Tp>::__optional_storage_base;
0467 
0468   _LIBCPP_HIDE_FROM_ABI __optional_copy_base() = default;
0469 
0470   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt) {
0471     this->__construct_from(__opt);
0472   }
0473 
0474   _LIBCPP_HIDE_FROM_ABI __optional_copy_base(__optional_copy_base&&)                 = default;
0475   _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(const __optional_copy_base&) = default;
0476   _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&)      = default;
0477 };
0478 
0479 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
0480 struct __optional_move_base : __optional_copy_base<_Tp> {
0481   using __optional_copy_base<_Tp>::__optional_copy_base;
0482 };
0483 
0484 template <class _Tp>
0485 struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> {
0486   using value_type = _Tp;
0487   using __optional_copy_base<_Tp>::__optional_copy_base;
0488 
0489   _LIBCPP_HIDE_FROM_ABI __optional_move_base()                            = default;
0490   _LIBCPP_HIDE_FROM_ABI __optional_move_base(const __optional_move_base&) = default;
0491 
0492   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
0493   __optional_move_base(__optional_move_base&& __opt) noexcept(is_nothrow_move_constructible_v<value_type>) {
0494     this->__construct_from(std::move(__opt));
0495   }
0496 
0497   _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(const __optional_move_base&) = default;
0498   _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(__optional_move_base&&)      = default;
0499 };
0500 
0501 template <class _Tp,
0502           bool = is_trivially_destructible<_Tp>::value && is_trivially_copy_constructible<_Tp>::value &&
0503                  is_trivially_copy_assignable<_Tp>::value>
0504 struct __optional_copy_assign_base : __optional_move_base<_Tp> {
0505   using __optional_move_base<_Tp>::__optional_move_base;
0506 };
0507 
0508 template <class _Tp>
0509 struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> {
0510   using __optional_move_base<_Tp>::__optional_move_base;
0511 
0512   _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base()                                   = default;
0513   _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
0514   _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(__optional_copy_assign_base&&)      = default;
0515 
0516   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base&
0517   operator=(const __optional_copy_assign_base& __opt) {
0518     this->__assign_from(__opt);
0519     return *this;
0520   }
0521 
0522   _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
0523 };
0524 
0525 template <class _Tp,
0526           bool = is_trivially_destructible<_Tp>::value && is_trivially_move_constructible<_Tp>::value &&
0527                  is_trivially_move_assignable<_Tp>::value>
0528 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> {
0529   using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
0530 };
0531 
0532 template <class _Tp>
0533 struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> {
0534   using value_type = _Tp;
0535   using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
0536 
0537   _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base()                                              = default;
0538   _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(const __optional_move_assign_base& __opt)      = default;
0539   _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(__optional_move_assign_base&&)                 = default;
0540   _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
0541 
0542   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base&
0543   operator=(__optional_move_assign_base&& __opt) noexcept(
0544       is_nothrow_move_assignable_v<value_type> && is_nothrow_move_constructible_v<value_type>) {
0545     this->__assign_from(std::move(__opt));
0546     return *this;
0547   }
0548 };
0549 
0550 template <class _Tp>
0551 using __optional_sfinae_ctor_base_t =
0552     __sfinae_ctor_base< is_copy_constructible<_Tp>::value, is_move_constructible<_Tp>::value >;
0553 
0554 template <class _Tp>
0555 using __optional_sfinae_assign_base_t =
0556     __sfinae_assign_base< (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
0557                           (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) >;
0558 
0559 template <class _Tp>
0560 class optional;
0561 
0562 #  if _LIBCPP_STD_VER >= 20
0563 
0564 template <class _Tp>
0565 concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
0566 
0567 #  endif // _LIBCPP_STD_VER >= 20
0568 
0569 template <class _Tp>
0570 struct __is_std_optional : false_type {};
0571 template <class _Tp>
0572 struct __is_std_optional<optional<_Tp>> : true_type {};
0573 
0574 template <class _Tp>
0575 class _LIBCPP_DECLSPEC_EMPTY_BASES optional
0576     : private __optional_move_assign_base<_Tp>,
0577       private __optional_sfinae_ctor_base_t<_Tp>,
0578       private __optional_sfinae_assign_base_t<_Tp> {
0579   using __base = __optional_move_assign_base<_Tp>;
0580 
0581 public:
0582   using value_type = _Tp;
0583 
0584   using __trivially_relocatable = conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
0585 
0586 private:
0587   // Disable the reference extension using this static assert.
0588   static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
0589                 "instantiation of optional with in_place_t is ill-formed");
0590   static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
0591                 "instantiation of optional with nullopt_t is ill-formed");
0592   static_assert(!is_reference_v<value_type>, "instantiation of optional with a reference type is ill-formed");
0593   static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed");
0594   static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed");
0595 
0596   // LWG2756: conditionally explicit conversion from _Up
0597   struct _CheckOptionalArgsConstructor {
0598     template <class _Up>
0599     _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
0600       return is_constructible_v<_Tp, _Up&&> && is_convertible_v<_Up&&, _Tp>;
0601     }
0602 
0603     template <class _Up>
0604     _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
0605       return is_constructible_v<_Tp, _Up&&> && !is_convertible_v<_Up&&, _Tp>;
0606     }
0607   };
0608   template <class _Up>
0609   using _CheckOptionalArgsCtor =
0610       _If< _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && _IsNotSame<__remove_cvref_t<_Up>, optional>::value &&
0611                (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value),
0612            _CheckOptionalArgsConstructor,
0613            __check_tuple_constructor_fail >;
0614   template <class _QualUp>
0615   struct _CheckOptionalLikeConstructor {
0616     template <class _Up, class _Opt = optional<_Up>>
0617     using __check_constructible_from_opt =
0618         _Or< is_constructible<_Tp, _Opt&>,
0619              is_constructible<_Tp, _Opt const&>,
0620              is_constructible<_Tp, _Opt&&>,
0621              is_constructible<_Tp, _Opt const&&>,
0622              is_convertible<_Opt&, _Tp>,
0623              is_convertible<_Opt const&, _Tp>,
0624              is_convertible<_Opt&&, _Tp>,
0625              is_convertible<_Opt const&&, _Tp> >;
0626     template <class _Up, class _Opt = optional<_Up>>
0627     using __check_assignable_from_opt =
0628         _Or< is_assignable<_Tp&, _Opt&>,
0629              is_assignable<_Tp&, _Opt const&>,
0630              is_assignable<_Tp&, _Opt&&>,
0631              is_assignable<_Tp&, _Opt const&&> >;
0632     template <class _Up, class _QUp = _QualUp>
0633     _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
0634       return is_convertible<_QUp, _Tp>::value &&
0635              (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
0636     }
0637     template <class _Up, class _QUp = _QualUp>
0638     _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
0639       return !is_convertible<_QUp, _Tp>::value &&
0640              (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
0641     }
0642     template <class _Up, class _QUp = _QualUp>
0643     _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() {
0644       // Construction and assignability of _QUp to _Tp has already been
0645       // checked.
0646       return !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value;
0647     }
0648   };
0649 
0650   template <class _Up, class _QualUp>
0651   using _CheckOptionalLikeCtor =
0652       _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp> >::value,
0653            _CheckOptionalLikeConstructor<_QualUp>,
0654            __check_tuple_constructor_fail >;
0655   template <class _Up, class _QualUp>
0656   using _CheckOptionalLikeAssign =
0657       _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp>, is_assignable<_Tp&, _QualUp> >::value,
0658            _CheckOptionalLikeConstructor<_QualUp>,
0659            __check_tuple_constructor_fail >;
0660 
0661 public:
0662   _LIBCPP_HIDE_FROM_ABI constexpr optional() noexcept {}
0663   _LIBCPP_HIDE_FROM_ABI constexpr optional(const optional&) = default;
0664   _LIBCPP_HIDE_FROM_ABI constexpr optional(optional&&)      = default;
0665   _LIBCPP_HIDE_FROM_ABI constexpr optional(nullopt_t) noexcept {}
0666 
0667   template <
0668       class _InPlaceT,
0669       class... _Args,
0670       class = enable_if_t< _And< _IsSame<_InPlaceT, in_place_t>, is_constructible<value_type, _Args...> >::value > >
0671   _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args)
0672       : __base(in_place, std::forward<_Args>(__args)...) {}
0673 
0674   template <class _Up,
0675             class... _Args,
0676             class = enable_if_t< is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> >
0677   _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
0678       : __base(in_place, __il, std::forward<_Args>(__args)...) {}
0679 
0680   template <class _Up                                                                         = value_type,
0681             enable_if_t< _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
0682   _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
0683 
0684   template <class _Up, enable_if_t< _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
0685   _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
0686 
0687   // LWG2756: conditionally explicit conversion from const optional<_Up>&
0688   template <class _Up,
0689             enable_if_t< _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
0690   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) {
0691     this->__construct_from(__v);
0692   }
0693   template <class _Up,
0694             enable_if_t< _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
0695   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) {
0696     this->__construct_from(__v);
0697   }
0698 
0699   // LWG2756: conditionally explicit conversion from optional<_Up>&&
0700   template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0>
0701   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) {
0702     this->__construct_from(std::move(__v));
0703   }
0704   template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0>
0705   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) {
0706     this->__construct_from(std::move(__v));
0707   }
0708 
0709 #  if _LIBCPP_STD_VER >= 23
0710   template <class _Tag,
0711             class _Fp,
0712             class... _Args,
0713             __enable_if_t<_IsSame<_Tag, __optional_construct_from_invoke_tag>::value, int> = 0>
0714   _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Tag, _Fp&& __f, _Args&&... __args)
0715       : __base(__optional_construct_from_invoke_tag{}, std::forward<_Fp>(__f), std::forward<_Args>(__args)...) {}
0716 #  endif
0717 
0718   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept {
0719     reset();
0720     return *this;
0721   }
0722 
0723   _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default;
0724   _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&)      = default;
0725 
0726   // LWG2756
0727   template <
0728       class _Up = value_type,
0729       class     = enable_if_t< _And< _IsNotSame<__remove_cvref_t<_Up>, optional>,
0730                                      _Or< _IsNotSame<__remove_cvref_t<_Up>, value_type>, _Not<is_scalar<value_type>> >,
0731                                      is_constructible<value_type, _Up>,
0732                                      is_assignable<value_type&, _Up> >::value> >
0733   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) {
0734     if (this->has_value())
0735       this->__get() = std::forward<_Up>(__v);
0736     else
0737       this->__construct(std::forward<_Up>(__v));
0738     return *this;
0739   }
0740 
0741   // LWG2756
0742   template <class _Up,
0743             enable_if_t< _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>(), int> = 0>
0744   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(const optional<_Up>& __v) {
0745     this->__assign_from(__v);
0746     return *this;
0747   }
0748 
0749   // LWG2756
0750   template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_assign<_Up>(), int> = 0>
0751   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(optional<_Up>&& __v) {
0752     this->__assign_from(std::move(__v));
0753     return *this;
0754   }
0755 
0756   template <class... _Args, class = enable_if_t< is_constructible_v<value_type, _Args...> > >
0757   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
0758     reset();
0759     this->__construct(std::forward<_Args>(__args)...);
0760     return this->__get();
0761   }
0762 
0763   template <class _Up,
0764             class... _Args,
0765             class = enable_if_t< is_constructible_v<value_type, initializer_list<_Up>&, _Args...> > >
0766   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
0767     reset();
0768     this->__construct(__il, std::forward<_Args>(__args)...);
0769     return this->__get();
0770   }
0771 
0772   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
0773   swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>) {
0774     if (this->has_value() == __opt.has_value()) {
0775       using std::swap;
0776       if (this->has_value())
0777         swap(this->__get(), __opt.__get());
0778     } else {
0779       if (this->has_value()) {
0780         __opt.__construct(std::move(this->__get()));
0781         reset();
0782       } else {
0783         this->__construct(std::move(__opt.__get()));
0784         __opt.reset();
0785       }
0786     }
0787   }
0788 
0789   _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept {
0790     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
0791     return std::addressof(this->__get());
0792   }
0793 
0794   _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept {
0795     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
0796     return std::addressof(this->__get());
0797   }
0798 
0799   _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept {
0800     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
0801     return this->__get();
0802   }
0803 
0804   _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept {
0805     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
0806     return this->__get();
0807   }
0808 
0809   _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept {
0810     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
0811     return std::move(this->__get());
0812   }
0813 
0814   _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept {
0815     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
0816     return std::move(this->__get());
0817   }
0818 
0819   _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return has_value(); }
0820 
0821   using __base::__get;
0822   using __base::has_value;
0823 
0824   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const& value() const& {
0825     if (!this->has_value())
0826       __throw_bad_optional_access();
0827     return this->__get();
0828   }
0829 
0830   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type& value() & {
0831     if (!this->has_value())
0832       __throw_bad_optional_access();
0833     return this->__get();
0834   }
0835 
0836   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type&& value() && {
0837     if (!this->has_value())
0838       __throw_bad_optional_access();
0839     return std::move(this->__get());
0840   }
0841 
0842   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const&& value() const&& {
0843     if (!this->has_value())
0844       __throw_bad_optional_access();
0845     return std::move(this->__get());
0846   }
0847 
0848   template <class _Up>
0849   _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) const& {
0850     static_assert(is_copy_constructible_v<value_type>, "optional<T>::value_or: T must be copy constructible");
0851     static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
0852     return this->has_value() ? this->__get() : static_cast<value_type>(std::forward<_Up>(__v));
0853   }
0854 
0855   template <class _Up>
0856   _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) && {
0857     static_assert(is_move_constructible_v<value_type>, "optional<T>::value_or: T must be move constructible");
0858     static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
0859     return this->has_value() ? std::move(this->__get()) : static_cast<value_type>(std::forward<_Up>(__v));
0860   }
0861 
0862 #  if _LIBCPP_STD_VER >= 23
0863   template <class _Func>
0864   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) & {
0865     using _Up = invoke_result_t<_Func, value_type&>;
0866     static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
0867                   "Result of f(value()) must be a specialization of std::optional");
0868     if (*this)
0869       return std::invoke(std::forward<_Func>(__f), value());
0870     return remove_cvref_t<_Up>();
0871   }
0872 
0873   template <class _Func>
0874   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) const& {
0875     using _Up = invoke_result_t<_Func, const value_type&>;
0876     static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
0877                   "Result of f(value()) must be a specialization of std::optional");
0878     if (*this)
0879       return std::invoke(std::forward<_Func>(__f), value());
0880     return remove_cvref_t<_Up>();
0881   }
0882 
0883   template <class _Func>
0884   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) && {
0885     using _Up = invoke_result_t<_Func, value_type&&>;
0886     static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
0887                   "Result of f(std::move(value())) must be a specialization of std::optional");
0888     if (*this)
0889       return std::invoke(std::forward<_Func>(__f), std::move(value()));
0890     return remove_cvref_t<_Up>();
0891   }
0892 
0893   template <class _Func>
0894   _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
0895     using _Up = invoke_result_t<_Func, const value_type&&>;
0896     static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
0897                   "Result of f(std::move(value())) must be a specialization of std::optional");
0898     if (*this)
0899       return std::invoke(std::forward<_Func>(__f), std::move(value()));
0900     return remove_cvref_t<_Up>();
0901   }
0902 
0903   template <class _Func>
0904   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) & {
0905     using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
0906     static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
0907     static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
0908     static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
0909     static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
0910     if (*this)
0911       return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
0912     return optional<_Up>();
0913   }
0914 
0915   template <class _Func>
0916   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) const& {
0917     using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
0918     static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
0919     static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
0920     static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
0921     static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
0922     if (*this)
0923       return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
0924     return optional<_Up>();
0925   }
0926 
0927   template <class _Func>
0928   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) && {
0929     using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
0930     static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
0931     static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
0932     static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
0933     static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
0934     if (*this)
0935       return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
0936     return optional<_Up>();
0937   }
0938 
0939   template <class _Func>
0940   _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) const&& {
0941     using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
0942     static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
0943     static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
0944     static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
0945     static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
0946     if (*this)
0947       return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
0948     return optional<_Up>();
0949   }
0950 
0951   template <invocable _Func>
0952   _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
0953     requires is_copy_constructible_v<value_type>
0954   {
0955     static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
0956                   "Result of f() should be the same type as this optional");
0957     if (*this)
0958       return *this;
0959     return std::forward<_Func>(__f)();
0960   }
0961 
0962   template <invocable _Func>
0963   _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
0964     requires is_move_constructible_v<value_type>
0965   {
0966     static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
0967                   "Result of f() should be the same type as this optional");
0968     if (*this)
0969       return std::move(*this);
0970     return std::forward<_Func>(__f)();
0971   }
0972 #  endif // _LIBCPP_STD_VER >= 23
0973 
0974   using __base::reset;
0975 };
0976 
0977 #  if _LIBCPP_STD_VER >= 17
0978 template <class _Tp>
0979 optional(_Tp) -> optional<_Tp>;
0980 #  endif
0981 
0982 // Comparisons between optionals
0983 template <class _Tp, class _Up>
0984 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
0985     is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
0986     bool >
0987 operator==(const optional<_Tp>& __x, const optional<_Up>& __y) {
0988   if (static_cast<bool>(__x) != static_cast<bool>(__y))
0989     return false;
0990   if (!static_cast<bool>(__x))
0991     return true;
0992   return *__x == *__y;
0993 }
0994 
0995 template <class _Tp, class _Up>
0996 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
0997     is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
0998     bool >
0999 operator!=(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 
1007 template <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 >
1011 operator<(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 
1019 template <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 >
1023 operator>(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 
1031 template <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 >
1035 operator<=(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 
1043 template <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 >
1047 operator>=(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 
1057 template <class _Tp, three_way_comparable_with<_Tp> _Up>
1058 _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1059 operator<=>(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
1068 template <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 
1075 template <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 
1080 template <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 
1085 template <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 
1090 template <class _Tp>
1091 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>&, nullopt_t) noexcept {
1092   return false;
1093 }
1094 
1095 template <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 
1100 template <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 
1105 template <class _Tp>
1106 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(nullopt_t, const optional<_Tp>&) noexcept {
1107   return true;
1108 }
1109 
1110 template <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 
1115 template <class _Tp>
1116 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(nullopt_t, const optional<_Tp>&) noexcept {
1117   return false;
1118 }
1119 
1120 template <class _Tp>
1121 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>&, nullopt_t) noexcept {
1122   return true;
1123 }
1124 
1125 template <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 
1132 template <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
1140 template <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 >
1144 operator==(const optional<_Tp>& __x, const _Up& __v) {
1145   return static_cast<bool>(__x) ? *__x == __v : false;
1146 }
1147 
1148 template <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 >
1152 operator==(const _Tp& __v, const optional<_Up>& __x) {
1153   return static_cast<bool>(__x) ? __v == *__x : false;
1154 }
1155 
1156 template <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 >
1160 operator!=(const optional<_Tp>& __x, const _Up& __v) {
1161   return static_cast<bool>(__x) ? *__x != __v : true;
1162 }
1163 
1164 template <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 >
1168 operator!=(const _Tp& __v, const optional<_Up>& __x) {
1169   return static_cast<bool>(__x) ? __v != *__x : true;
1170 }
1171 
1172 template <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 >
1176 operator<(const optional<_Tp>& __x, const _Up& __v) {
1177   return static_cast<bool>(__x) ? *__x < __v : true;
1178 }
1179 
1180 template <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 >
1184 operator<(const _Tp& __v, const optional<_Up>& __x) {
1185   return static_cast<bool>(__x) ? __v < *__x : false;
1186 }
1187 
1188 template <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 >
1192 operator<=(const optional<_Tp>& __x, const _Up& __v) {
1193   return static_cast<bool>(__x) ? *__x <= __v : true;
1194 }
1195 
1196 template <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 >
1200 operator<=(const _Tp& __v, const optional<_Up>& __x) {
1201   return static_cast<bool>(__x) ? __v <= *__x : false;
1202 }
1203 
1204 template <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 >
1208 operator>(const optional<_Tp>& __x, const _Up& __v) {
1209   return static_cast<bool>(__x) ? *__x > __v : false;
1210 }
1211 
1212 template <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 >
1216 operator>(const _Tp& __v, const optional<_Up>& __x) {
1217   return static_cast<bool>(__x) ? __v > *__x : true;
1218 }
1219 
1220 template <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 >
1224 operator>=(const optional<_Tp>& __x, const _Up& __v) {
1225   return static_cast<bool>(__x) ? *__x >= __v : false;
1226 }
1227 
1228 template <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 >
1232 operator>=(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 
1238 template <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>
1241 operator<=>(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 
1247 template <class _Tp>
1248 inline _LIBCPP_HIDE_FROM_ABI
1249 _LIBCPP_CONSTEXPR_SINCE_CXX20 enable_if_t< is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, void >
1250 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) {
1251   __x.swap(__y);
1252 }
1253 
1254 template <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 
1259 template <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 
1264 template <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 
1269 template <class _Tp>
1270 struct _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 <__cxx03/atomic>
1289 #  include <__cxx03/climits>
1290 #  include <__cxx03/concepts>
1291 #  include <__cxx03/ctime>
1292 #  include <__cxx03/iterator>
1293 #  include <__cxx03/limits>
1294 #  include <__cxx03/memory>
1295 #  include <__cxx03/ratio>
1296 #  include <__cxx03/stdexcept>
1297 #  include <__cxx03/tuple>
1298 #  include <__cxx03/type_traits>
1299 #  include <__cxx03/typeinfo>
1300 #  include <__cxx03/utility>
1301 #  include <__cxx03/variant>
1302 #endif
1303 
1304 #endif // _LIBCPP___CXX03_OPTIONAL