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