Warning, /include/c++/v1/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_OPTIONAL
0011 #define _LIBCPP_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 #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
0181 # include <__cxx03/optional>
0182 #else
0183 # include <__assert>
0184 # include <__compare/compare_three_way_result.h>
0185 # include <__compare/ordering.h>
0186 # include <__compare/three_way_comparable.h>
0187 # include <__concepts/invocable.h>
0188 # include <__config>
0189 # include <__exception/exception.h>
0190 # include <__functional/hash.h>
0191 # include <__functional/invoke.h>
0192 # include <__functional/unary_function.h>
0193 # include <__fwd/functional.h>
0194 # include <__memory/addressof.h>
0195 # include <__memory/construct_at.h>
0196 # include <__tuple/sfinae_helpers.h>
0197 # include <__type_traits/add_pointer.h>
0198 # include <__type_traits/conditional.h>
0199 # include <__type_traits/conjunction.h>
0200 # include <__type_traits/decay.h>
0201 # include <__type_traits/disjunction.h>
0202 # include <__type_traits/enable_if.h>
0203 # include <__type_traits/invoke.h>
0204 # include <__type_traits/is_array.h>
0205 # include <__type_traits/is_assignable.h>
0206 # include <__type_traits/is_constructible.h>
0207 # include <__type_traits/is_convertible.h>
0208 # include <__type_traits/is_destructible.h>
0209 # include <__type_traits/is_nothrow_assignable.h>
0210 # include <__type_traits/is_nothrow_constructible.h>
0211 # include <__type_traits/is_object.h>
0212 # include <__type_traits/is_reference.h>
0213 # include <__type_traits/is_same.h>
0214 # include <__type_traits/is_scalar.h>
0215 # include <__type_traits/is_swappable.h>
0216 # include <__type_traits/is_trivially_assignable.h>
0217 # include <__type_traits/is_trivially_constructible.h>
0218 # include <__type_traits/is_trivially_destructible.h>
0219 # include <__type_traits/is_trivially_relocatable.h>
0220 # include <__type_traits/negation.h>
0221 # include <__type_traits/remove_const.h>
0222 # include <__type_traits/remove_cv.h>
0223 # include <__type_traits/remove_cvref.h>
0224 # include <__type_traits/remove_reference.h>
0225 # include <__utility/declval.h>
0226 # include <__utility/forward.h>
0227 # include <__utility/in_place.h>
0228 # include <__utility/move.h>
0229 # include <__utility/swap.h>
0230 # include <__verbose_abort>
0231 # include <initializer_list>
0232 # include <version>
0233
0234 // standard-mandated includes
0235
0236 // [optional.syn]
0237 # include <compare>
0238
0239 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0240 # pragma GCC system_header
0241 # endif
0242
0243 _LIBCPP_PUSH_MACROS
0244 # include <__undef_macros>
0245
0246 namespace std // purposefully not using versioning namespace
0247 {
0248
0249 class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access : public exception {
0250 public:
0251 _LIBCPP_HIDE_FROM_ABI bad_optional_access() _NOEXCEPT = default;
0252 _LIBCPP_HIDE_FROM_ABI bad_optional_access(const bad_optional_access&) _NOEXCEPT = default;
0253 _LIBCPP_HIDE_FROM_ABI bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default;
0254 // Get the key function ~bad_optional_access() into the dylib
0255 ~bad_optional_access() _NOEXCEPT override;
0256 const char* what() const _NOEXCEPT override;
0257 };
0258
0259 } // namespace std
0260
0261 # if _LIBCPP_STD_VER >= 17
0262
0263 _LIBCPP_BEGIN_NAMESPACE_STD
0264
0265 [[noreturn]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS void
0266 __throw_bad_optional_access() {
0267 # if _LIBCPP_HAS_EXCEPTIONS
0268 throw bad_optional_access();
0269 # else
0270 _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode");
0271 # endif
0272 }
0273
0274 struct nullopt_t {
0275 struct __secret_tag {
0276 explicit __secret_tag() = default;
0277 };
0278 _LIBCPP_HIDE_FROM_ABI constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
0279 };
0280
0281 inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
0282
0283 struct __optional_construct_from_invoke_tag {};
0284
0285 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
0286 struct __optional_destruct_base;
0287
0288 template <class _Tp>
0289 struct __optional_destruct_base<_Tp, false> {
0290 typedef _Tp value_type;
0291 static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
0292 union {
0293 char __null_state_;
0294 remove_cv_t<value_type> __val_;
0295 };
0296 bool __engaged_;
0297
0298 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base() {
0299 if (__engaged_)
0300 __val_.~value_type();
0301 }
0302
0303 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {}
0304
0305 template <class... _Args>
0306 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
0307 : __val_(std::forward<_Args>(__args)...), __engaged_(true) {}
0308
0309 # if _LIBCPP_STD_VER >= 23
0310 template <class _Fp, class... _Args>
0311 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(
0312 __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
0313 : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {}
0314 # endif
0315
0316 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept {
0317 if (__engaged_) {
0318 __val_.~value_type();
0319 __engaged_ = false;
0320 }
0321 }
0322 };
0323
0324 template <class _Tp>
0325 struct __optional_destruct_base<_Tp, true> {
0326 typedef _Tp value_type;
0327 static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
0328 union {
0329 char __null_state_;
0330 remove_cv_t<value_type> __val_;
0331 };
0332 bool __engaged_;
0333
0334 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {}
0335
0336 template <class... _Args>
0337 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
0338 : __val_(std::forward<_Args>(__args)...), __engaged_(true) {}
0339
0340 # if _LIBCPP_STD_VER >= 23
0341 template <class _Fp, class... _Args>
0342 _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base(
0343 __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
0344 : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {}
0345 # endif
0346
0347 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept {
0348 if (__engaged_) {
0349 __engaged_ = false;
0350 }
0351 }
0352 };
0353
0354 template <class _Tp, bool = is_reference<_Tp>::value>
0355 struct __optional_storage_base : __optional_destruct_base<_Tp> {
0356 using __base _LIBCPP_NODEBUG = __optional_destruct_base<_Tp>;
0357 using value_type = _Tp;
0358 using __base::__base;
0359
0360 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; }
0361
0362 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() & noexcept { return this->__val_; }
0363 _LIBCPP_HIDE_FROM_ABI constexpr const value_type& __get() const& noexcept { return this->__val_; }
0364 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() && noexcept { return std::move(this->__val_); }
0365 _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& __get() const&& noexcept { return std::move(this->__val_); }
0366
0367 template <class... _Args>
0368 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) {
0369 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
0370 std::__construct_at(std::addressof(this->__val_), std::forward<_Args>(__args)...);
0371 this->__engaged_ = true;
0372 }
0373
0374 template <class _That>
0375 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) {
0376 if (__opt.has_value())
0377 __construct(std::forward<_That>(__opt).__get());
0378 }
0379
0380 template <class _That>
0381 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) {
0382 if (this->__engaged_ == __opt.has_value()) {
0383 if (this->__engaged_)
0384 static_cast<_Tp&>(this->__val_) = std::forward<_That>(__opt).__get();
0385 } else {
0386 if (this->__engaged_)
0387 this->reset();
0388 else
0389 __construct(std::forward<_That>(__opt).__get());
0390 }
0391 }
0392 };
0393
0394 // optional<T&> is currently required to be ill-formed. However, it may
0395 // be allowed in the future. For this reason, it has already been implemented
0396 // to ensure we can make the change in an ABI-compatible manner.
0397 template <class _Tp>
0398 struct __optional_storage_base<_Tp, true> {
0399 using value_type = _Tp;
0400 using __raw_type _LIBCPP_NODEBUG = remove_reference_t<_Tp>;
0401 __raw_type* __value_;
0402
0403 template <class _Up>
0404 static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
0405 using _RawUp = __libcpp_remove_reference_t<_Up>;
0406 using _UpPtr = _RawUp*;
0407 using _RawTp = __libcpp_remove_reference_t<_Tp>;
0408 using _TpPtr = _RawTp*;
0409 using _CheckLValueArg =
0410 integral_constant<bool,
0411 (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) ||
0412 is_same<_RawUp, reference_wrapper<_RawTp>>::value ||
0413 is_same<_RawUp, reference_wrapper<__remove_const_t<_RawTp>>>::value >;
0414 return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) ||
0415 (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
0416 is_convertible<_UpPtr, _TpPtr>::value);
0417 }
0418
0419 _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {}
0420
0421 template <class _UArg>
0422 _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
0423 : __value_(std::addressof(__uarg)) {
0424 static_assert(__can_bind_reference<_UArg>(),
0425 "Attempted to construct a reference element in tuple from a "
0426 "possible temporary");
0427 }
0428
0429 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }
0430
0431 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __value_ != nullptr; }
0432
0433 _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() const& noexcept { return *__value_; }
0434
0435 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() const&& noexcept { return std::forward<value_type>(*__value_); }
0436
0437 template <class _UArg>
0438 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) {
0439 _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage");
0440 static_assert(__can_bind_reference<_UArg>(),
0441 "Attempted to construct a reference element in tuple from a "
0442 "possible temporary");
0443 __value_ = std::addressof(__val);
0444 }
0445
0446 template <class _That>
0447 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) {
0448 if (__opt.has_value())
0449 __construct(std::forward<_That>(__opt).__get());
0450 }
0451
0452 template <class _That>
0453 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) {
0454 if (has_value() == __opt.has_value()) {
0455 if (has_value())
0456 *__value_ = std::forward<_That>(__opt).__get();
0457 } else {
0458 if (has_value())
0459 reset();
0460 else
0461 __construct(std::forward<_That>(__opt).__get());
0462 }
0463 }
0464 };
0465
0466 template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
0467 struct __optional_copy_base : __optional_storage_base<_Tp> {
0468 using __optional_storage_base<_Tp>::__optional_storage_base;
0469 };
0470
0471 template <class _Tp>
0472 struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> {
0473 using __optional_storage_base<_Tp>::__optional_storage_base;
0474
0475 _LIBCPP_HIDE_FROM_ABI __optional_copy_base() = default;
0476
0477 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt) {
0478 this->__construct_from(__opt);
0479 }
0480
0481 _LIBCPP_HIDE_FROM_ABI __optional_copy_base(__optional_copy_base&&) = default;
0482 _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(const __optional_copy_base&) = default;
0483 _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&) = default;
0484 };
0485
0486 template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
0487 struct __optional_move_base : __optional_copy_base<_Tp> {
0488 using __optional_copy_base<_Tp>::__optional_copy_base;
0489 };
0490
0491 template <class _Tp>
0492 struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> {
0493 using value_type = _Tp;
0494 using __optional_copy_base<_Tp>::__optional_copy_base;
0495
0496 _LIBCPP_HIDE_FROM_ABI __optional_move_base() = default;
0497 _LIBCPP_HIDE_FROM_ABI __optional_move_base(const __optional_move_base&) = default;
0498
0499 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
0500 __optional_move_base(__optional_move_base&& __opt) noexcept(is_nothrow_move_constructible_v<value_type>) {
0501 this->__construct_from(std::move(__opt));
0502 }
0503
0504 _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(const __optional_move_base&) = default;
0505 _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(__optional_move_base&&) = default;
0506 };
0507
0508 template <class _Tp,
0509 bool = is_trivially_destructible<_Tp>::value && is_trivially_copy_constructible<_Tp>::value &&
0510 is_trivially_copy_assignable<_Tp>::value>
0511 struct __optional_copy_assign_base : __optional_move_base<_Tp> {
0512 using __optional_move_base<_Tp>::__optional_move_base;
0513 };
0514
0515 template <class _Tp>
0516 struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> {
0517 using __optional_move_base<_Tp>::__optional_move_base;
0518
0519 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base() = default;
0520 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
0521 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
0522
0523 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base&
0524 operator=(const __optional_copy_assign_base& __opt) {
0525 this->__assign_from(__opt);
0526 return *this;
0527 }
0528
0529 _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
0530 };
0531
0532 template <class _Tp,
0533 bool = is_trivially_destructible<_Tp>::value && is_trivially_move_constructible<_Tp>::value &&
0534 is_trivially_move_assignable<_Tp>::value>
0535 struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> {
0536 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
0537 };
0538
0539 template <class _Tp>
0540 struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> {
0541 using value_type = _Tp;
0542 using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
0543
0544 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base() = default;
0545 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
0546 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(__optional_move_assign_base&&) = default;
0547 _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
0548
0549 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base&
0550 operator=(__optional_move_assign_base&& __opt) noexcept(
0551 is_nothrow_move_assignable_v<value_type> && is_nothrow_move_constructible_v<value_type>) {
0552 this->__assign_from(std::move(__opt));
0553 return *this;
0554 }
0555 };
0556
0557 template <class _Tp>
0558 using __optional_sfinae_ctor_base_t _LIBCPP_NODEBUG =
0559 __sfinae_ctor_base< is_copy_constructible<_Tp>::value, is_move_constructible<_Tp>::value >;
0560
0561 template <class _Tp>
0562 using __optional_sfinae_assign_base_t _LIBCPP_NODEBUG =
0563 __sfinae_assign_base< (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
0564 (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) >;
0565
0566 template <class _Tp>
0567 class optional;
0568
0569 # if _LIBCPP_STD_VER >= 20
0570
0571 template <class _Tp>
0572 concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); };
0573
0574 # endif // _LIBCPP_STD_VER >= 20
0575
0576 template <class _Tp>
0577 struct __is_std_optional : false_type {};
0578 template <class _Tp>
0579 struct __is_std_optional<optional<_Tp>> : true_type {};
0580
0581 template <class _Tp>
0582 class _LIBCPP_DECLSPEC_EMPTY_BASES optional
0583 : private __optional_move_assign_base<_Tp>,
0584 private __optional_sfinae_ctor_base_t<_Tp>,
0585 private __optional_sfinae_assign_base_t<_Tp> {
0586 using __base _LIBCPP_NODEBUG = __optional_move_assign_base<_Tp>;
0587
0588 public:
0589 using value_type = _Tp;
0590
0591 using __trivially_relocatable _LIBCPP_NODEBUG =
0592 conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
0593
0594 private:
0595 // Disable the reference extension using this static assert.
0596 static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,
0597 "instantiation of optional with in_place_t is ill-formed");
0598 static_assert(!is_same_v<__remove_cvref_t<value_type>, nullopt_t>,
0599 "instantiation of optional with nullopt_t is ill-formed");
0600 static_assert(!is_reference_v<value_type>, "instantiation of optional with a reference type is ill-formed");
0601 static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed");
0602 static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed");
0603
0604 // LWG2756: conditionally explicit conversion from _Up
0605 struct _CheckOptionalArgsConstructor {
0606 template <class _Up>
0607 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
0608 return is_constructible_v<_Tp, _Up&&> && is_convertible_v<_Up&&, _Tp>;
0609 }
0610
0611 template <class _Up>
0612 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
0613 return is_constructible_v<_Tp, _Up&&> && !is_convertible_v<_Up&&, _Tp>;
0614 }
0615 };
0616 template <class _Up>
0617 using _CheckOptionalArgsCtor _LIBCPP_NODEBUG =
0618 _If< _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && _IsNotSame<__remove_cvref_t<_Up>, optional>::value &&
0619 (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value),
0620 _CheckOptionalArgsConstructor,
0621 __check_tuple_constructor_fail >;
0622 template <class _QualUp>
0623 struct _CheckOptionalLikeConstructor {
0624 template <class _Up, class _Opt = optional<_Up>>
0625 using __check_constructible_from_opt _LIBCPP_NODEBUG =
0626 _Or< is_constructible<_Tp, _Opt&>,
0627 is_constructible<_Tp, _Opt const&>,
0628 is_constructible<_Tp, _Opt&&>,
0629 is_constructible<_Tp, _Opt const&&>,
0630 is_convertible<_Opt&, _Tp>,
0631 is_convertible<_Opt const&, _Tp>,
0632 is_convertible<_Opt&&, _Tp>,
0633 is_convertible<_Opt const&&, _Tp> >;
0634 template <class _Up, class _Opt = optional<_Up>>
0635 using __check_assignable_from_opt _LIBCPP_NODEBUG =
0636 _Or< is_assignable<_Tp&, _Opt&>,
0637 is_assignable<_Tp&, _Opt const&>,
0638 is_assignable<_Tp&, _Opt&&>,
0639 is_assignable<_Tp&, _Opt const&&> >;
0640 template <class _Up, class _QUp = _QualUp>
0641 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() {
0642 return is_convertible<_QUp, _Tp>::value &&
0643 (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
0644 }
0645 template <class _Up, class _QUp = _QualUp>
0646 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() {
0647 return !is_convertible<_QUp, _Tp>::value &&
0648 (is_same_v<remove_cv_t<_Tp>, bool> || !__check_constructible_from_opt<_Up>::value);
0649 }
0650 template <class _Up, class _QUp = _QualUp>
0651 _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() {
0652 // Construction and assignability of _QUp to _Tp has already been
0653 // checked.
0654 return !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value;
0655 }
0656 };
0657
0658 template <class _Up, class _QualUp>
0659 using _CheckOptionalLikeCtor _LIBCPP_NODEBUG =
0660 _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp> >::value,
0661 _CheckOptionalLikeConstructor<_QualUp>,
0662 __check_tuple_constructor_fail >;
0663 template <class _Up, class _QualUp>
0664 using _CheckOptionalLikeAssign _LIBCPP_NODEBUG =
0665 _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp>, is_assignable<_Tp&, _QualUp> >::value,
0666 _CheckOptionalLikeConstructor<_QualUp>,
0667 __check_tuple_constructor_fail >;
0668
0669 public:
0670 _LIBCPP_HIDE_FROM_ABI constexpr optional() noexcept {}
0671 _LIBCPP_HIDE_FROM_ABI constexpr optional(const optional&) = default;
0672 _LIBCPP_HIDE_FROM_ABI constexpr optional(optional&&) = default;
0673 _LIBCPP_HIDE_FROM_ABI constexpr optional(nullopt_t) noexcept {}
0674
0675 template <
0676 class _InPlaceT,
0677 class... _Args,
0678 class = enable_if_t< _And< _IsSame<_InPlaceT, in_place_t>, is_constructible<value_type, _Args...> >::value > >
0679 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args)
0680 : __base(in_place, std::forward<_Args>(__args)...) {}
0681
0682 template <class _Up,
0683 class... _Args,
0684 class = enable_if_t< is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> >
0685 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
0686 : __base(in_place, __il, std::forward<_Args>(__args)...) {}
0687
0688 template <class _Up = value_type,
0689 enable_if_t< _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
0690 _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
0691
0692 template <class _Up, enable_if_t< _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
0693 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
0694
0695 // LWG2756: conditionally explicit conversion from const optional<_Up>&
0696 template <class _Up,
0697 enable_if_t< _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
0698 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) {
0699 this->__construct_from(__v);
0700 }
0701 template <class _Up,
0702 enable_if_t< _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
0703 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) {
0704 this->__construct_from(__v);
0705 }
0706
0707 // LWG2756: conditionally explicit conversion from optional<_Up>&&
0708 template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0>
0709 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) {
0710 this->__construct_from(std::move(__v));
0711 }
0712 template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0>
0713 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) {
0714 this->__construct_from(std::move(__v));
0715 }
0716
0717 # if _LIBCPP_STD_VER >= 23
0718 template <class _Tag,
0719 class _Fp,
0720 class... _Args,
0721 __enable_if_t<_IsSame<_Tag, __optional_construct_from_invoke_tag>::value, int> = 0>
0722 _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Tag, _Fp&& __f, _Args&&... __args)
0723 : __base(__optional_construct_from_invoke_tag{}, std::forward<_Fp>(__f), std::forward<_Args>(__args)...) {}
0724 # endif
0725
0726 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept {
0727 reset();
0728 return *this;
0729 }
0730
0731 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default;
0732 _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default;
0733
0734 // LWG2756
0735 template <
0736 class _Up = value_type,
0737 class = enable_if_t< _And< _IsNotSame<__remove_cvref_t<_Up>, optional>,
0738 _Or< _IsNotSame<__remove_cvref_t<_Up>, value_type>, _Not<is_scalar<value_type>> >,
0739 is_constructible<value_type, _Up>,
0740 is_assignable<value_type&, _Up> >::value> >
0741 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) {
0742 if (this->has_value())
0743 this->__get() = std::forward<_Up>(__v);
0744 else
0745 this->__construct(std::forward<_Up>(__v));
0746 return *this;
0747 }
0748
0749 // LWG2756
0750 template <class _Up,
0751 enable_if_t< _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>(), int> = 0>
0752 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(const optional<_Up>& __v) {
0753 this->__assign_from(__v);
0754 return *this;
0755 }
0756
0757 // LWG2756
0758 template <class _Up, enable_if_t< _CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_assign<_Up>(), int> = 0>
0759 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(optional<_Up>&& __v) {
0760 this->__assign_from(std::move(__v));
0761 return *this;
0762 }
0763
0764 template <class... _Args, class = enable_if_t< is_constructible_v<value_type, _Args...> > >
0765 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
0766 reset();
0767 this->__construct(std::forward<_Args>(__args)...);
0768 return this->__get();
0769 }
0770
0771 template <class _Up,
0772 class... _Args,
0773 class = enable_if_t< is_constructible_v<value_type, initializer_list<_Up>&, _Args...> > >
0774 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) {
0775 reset();
0776 this->__construct(__il, std::forward<_Args>(__args)...);
0777 return this->__get();
0778 }
0779
0780 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
0781 swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>) {
0782 if (this->has_value() == __opt.has_value()) {
0783 using std::swap;
0784 if (this->has_value())
0785 swap(this->__get(), __opt.__get());
0786 } else {
0787 if (this->has_value()) {
0788 __opt.__construct(std::move(this->__get()));
0789 reset();
0790 } else {
0791 this->__construct(std::move(__opt.__get()));
0792 __opt.reset();
0793 }
0794 }
0795 }
0796
0797 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type const> operator->() const noexcept {
0798 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
0799 return std::addressof(this->__get());
0800 }
0801
0802 _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<value_type> operator->() noexcept {
0803 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value");
0804 return std::addressof(this->__get());
0805 }
0806
0807 _LIBCPP_HIDE_FROM_ABI constexpr const value_type& operator*() const& noexcept {
0808 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
0809 return this->__get();
0810 }
0811
0812 _LIBCPP_HIDE_FROM_ABI constexpr value_type& operator*() & noexcept {
0813 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
0814 return this->__get();
0815 }
0816
0817 _LIBCPP_HIDE_FROM_ABI constexpr value_type&& operator*() && noexcept {
0818 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
0819 return std::move(this->__get());
0820 }
0821
0822 _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& operator*() const&& noexcept {
0823 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value");
0824 return std::move(this->__get());
0825 }
0826
0827 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return has_value(); }
0828
0829 using __base::__get;
0830 using __base::has_value;
0831
0832 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const& value() const& {
0833 if (!this->has_value())
0834 __throw_bad_optional_access();
0835 return this->__get();
0836 }
0837
0838 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type& value() & {
0839 if (!this->has_value())
0840 __throw_bad_optional_access();
0841 return this->__get();
0842 }
0843
0844 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type&& value() && {
0845 if (!this->has_value())
0846 __throw_bad_optional_access();
0847 return std::move(this->__get());
0848 }
0849
0850 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const&& value() const&& {
0851 if (!this->has_value())
0852 __throw_bad_optional_access();
0853 return std::move(this->__get());
0854 }
0855
0856 template <class _Up>
0857 _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) const& {
0858 static_assert(is_copy_constructible_v<value_type>, "optional<T>::value_or: T must be copy constructible");
0859 static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
0860 return this->has_value() ? this->__get() : static_cast<value_type>(std::forward<_Up>(__v));
0861 }
0862
0863 template <class _Up>
0864 _LIBCPP_HIDE_FROM_ABI constexpr value_type value_or(_Up&& __v) && {
0865 static_assert(is_move_constructible_v<value_type>, "optional<T>::value_or: T must be move constructible");
0866 static_assert(is_convertible_v<_Up, value_type>, "optional<T>::value_or: U must be convertible to T");
0867 return this->has_value() ? std::move(this->__get()) : static_cast<value_type>(std::forward<_Up>(__v));
0868 }
0869
0870 # if _LIBCPP_STD_VER >= 23
0871 template <class _Func>
0872 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) & {
0873 using _Up = invoke_result_t<_Func, value_type&>;
0874 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
0875 "Result of f(value()) must be a specialization of std::optional");
0876 if (*this)
0877 return std::invoke(std::forward<_Func>(__f), value());
0878 return remove_cvref_t<_Up>();
0879 }
0880
0881 template <class _Func>
0882 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) const& {
0883 using _Up = invoke_result_t<_Func, const value_type&>;
0884 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
0885 "Result of f(value()) must be a specialization of std::optional");
0886 if (*this)
0887 return std::invoke(std::forward<_Func>(__f), value());
0888 return remove_cvref_t<_Up>();
0889 }
0890
0891 template <class _Func>
0892 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto and_then(_Func&& __f) && {
0893 using _Up = invoke_result_t<_Func, value_type&&>;
0894 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
0895 "Result of f(std::move(value())) must be a specialization of std::optional");
0896 if (*this)
0897 return std::invoke(std::forward<_Func>(__f), std::move(value()));
0898 return remove_cvref_t<_Up>();
0899 }
0900
0901 template <class _Func>
0902 _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
0903 using _Up = invoke_result_t<_Func, const value_type&&>;
0904 static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
0905 "Result of f(std::move(value())) must be a specialization of std::optional");
0906 if (*this)
0907 return std::invoke(std::forward<_Func>(__f), std::move(value()));
0908 return remove_cvref_t<_Up>();
0909 }
0910
0911 template <class _Func>
0912 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) & {
0913 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
0914 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
0915 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
0916 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
0917 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
0918 if (*this)
0919 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
0920 return optional<_Up>();
0921 }
0922
0923 template <class _Func>
0924 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) const& {
0925 using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
0926 static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
0927 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t");
0928 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t");
0929 static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
0930 if (*this)
0931 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
0932 return optional<_Up>();
0933 }
0934
0935 template <class _Func>
0936 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) && {
0937 using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
0938 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
0939 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
0940 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
0941 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
0942 if (*this)
0943 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
0944 return optional<_Up>();
0945 }
0946
0947 template <class _Func>
0948 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr auto transform(_Func&& __f) const&& {
0949 using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
0950 static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
0951 static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t");
0952 static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t");
0953 static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
0954 if (*this)
0955 return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
0956 return optional<_Up>();
0957 }
0958
0959 template <invocable _Func>
0960 _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
0961 requires is_copy_constructible_v<value_type>
0962 {
0963 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
0964 "Result of f() should be the same type as this optional");
0965 if (*this)
0966 return *this;
0967 return std::forward<_Func>(__f)();
0968 }
0969
0970 template <invocable _Func>
0971 _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
0972 requires is_move_constructible_v<value_type>
0973 {
0974 static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
0975 "Result of f() should be the same type as this optional");
0976 if (*this)
0977 return std::move(*this);
0978 return std::forward<_Func>(__f)();
0979 }
0980 # endif // _LIBCPP_STD_VER >= 23
0981
0982 using __base::reset;
0983 };
0984
0985 # if _LIBCPP_STD_VER >= 17
0986 template <class _Tp>
0987 optional(_Tp) -> optional<_Tp>;
0988 # endif
0989
0990 // Comparisons between optionals
0991 template <class _Tp, class _Up>
0992 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
0993 is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>,
0994 bool >
0995 operator==(const optional<_Tp>& __x, const optional<_Up>& __y) {
0996 if (static_cast<bool>(__x) != static_cast<bool>(__y))
0997 return false;
0998 if (!static_cast<bool>(__x))
0999 return true;
1000 return *__x == *__y;
1001 }
1002
1003 template <class _Tp, class _Up>
1004 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1005 is_convertible_v<decltype(std::declval<const _Tp&>() != std::declval<const _Up&>()), bool>,
1006 bool >
1007 operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1008 if (static_cast<bool>(__x) != static_cast<bool>(__y))
1009 return true;
1010 if (!static_cast<bool>(__x))
1011 return false;
1012 return *__x != *__y;
1013 }
1014
1015 template <class _Tp, class _Up>
1016 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1017 is_convertible_v<decltype(std::declval<const _Tp&>() < std::declval<const _Up&>()), bool>,
1018 bool >
1019 operator<(const optional<_Tp>& __x, const optional<_Up>& __y) {
1020 if (!static_cast<bool>(__y))
1021 return false;
1022 if (!static_cast<bool>(__x))
1023 return true;
1024 return *__x < *__y;
1025 }
1026
1027 template <class _Tp, class _Up>
1028 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1029 is_convertible_v<decltype(std::declval<const _Tp&>() > std::declval<const _Up&>()), bool>,
1030 bool >
1031 operator>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1032 if (!static_cast<bool>(__x))
1033 return false;
1034 if (!static_cast<bool>(__y))
1035 return true;
1036 return *__x > *__y;
1037 }
1038
1039 template <class _Tp, class _Up>
1040 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1041 is_convertible_v<decltype(std::declval<const _Tp&>() <= std::declval<const _Up&>()), bool>,
1042 bool >
1043 operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1044 if (!static_cast<bool>(__x))
1045 return true;
1046 if (!static_cast<bool>(__y))
1047 return false;
1048 return *__x <= *__y;
1049 }
1050
1051 template <class _Tp, class _Up>
1052 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1053 is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
1054 bool >
1055 operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) {
1056 if (!static_cast<bool>(__y))
1057 return true;
1058 if (!static_cast<bool>(__x))
1059 return false;
1060 return *__x >= *__y;
1061 }
1062
1063 # if _LIBCPP_STD_VER >= 20
1064
1065 template <class _Tp, three_way_comparable_with<_Tp> _Up>
1066 _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1067 operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) {
1068 if (__x && __y)
1069 return *__x <=> *__y;
1070 return __x.has_value() <=> __y.has_value();
1071 }
1072
1073 # endif // _LIBCPP_STD_VER >= 20
1074
1075 // Comparisons with nullopt
1076 template <class _Tp>
1077 _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept {
1078 return !static_cast<bool>(__x);
1079 }
1080
1081 # if _LIBCPP_STD_VER <= 17
1082
1083 template <class _Tp>
1084 _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(nullopt_t, const optional<_Tp>& __x) noexcept {
1085 return !static_cast<bool>(__x);
1086 }
1087
1088 template <class _Tp>
1089 _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, nullopt_t) noexcept {
1090 return static_cast<bool>(__x);
1091 }
1092
1093 template <class _Tp>
1094 _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(nullopt_t, const optional<_Tp>& __x) noexcept {
1095 return static_cast<bool>(__x);
1096 }
1097
1098 template <class _Tp>
1099 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>&, nullopt_t) noexcept {
1100 return false;
1101 }
1102
1103 template <class _Tp>
1104 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<(nullopt_t, const optional<_Tp>& __x) noexcept {
1105 return static_cast<bool>(__x);
1106 }
1107
1108 template <class _Tp>
1109 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, nullopt_t) noexcept {
1110 return !static_cast<bool>(__x);
1111 }
1112
1113 template <class _Tp>
1114 _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(nullopt_t, const optional<_Tp>&) noexcept {
1115 return true;
1116 }
1117
1118 template <class _Tp>
1119 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, nullopt_t) noexcept {
1120 return static_cast<bool>(__x);
1121 }
1122
1123 template <class _Tp>
1124 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>(nullopt_t, const optional<_Tp>&) noexcept {
1125 return false;
1126 }
1127
1128 template <class _Tp>
1129 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>&, nullopt_t) noexcept {
1130 return true;
1131 }
1132
1133 template <class _Tp>
1134 _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(nullopt_t, const optional<_Tp>& __x) noexcept {
1135 return !static_cast<bool>(__x);
1136 }
1137
1138 # else // _LIBCPP_STD_VER <= 17
1139
1140 template <class _Tp>
1141 _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept {
1142 return __x.has_value() <=> false;
1143 }
1144
1145 # endif // _LIBCPP_STD_VER <= 17
1146
1147 // Comparisons with T
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 optional<_Tp>& __x, const _Up& __v) {
1153 return static_cast<bool>(__x) ? *__x == __v : 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 _Tp& __v, const optional<_Up>& __x) {
1161 return static_cast<bool>(__x) ? __v == *__x : false;
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 optional<_Tp>& __x, const _Up& __v) {
1169 return static_cast<bool>(__x) ? *__x != __v : 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 _Tp& __v, const optional<_Up>& __x) {
1177 return static_cast<bool>(__x) ? __v != *__x : 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 optional<_Tp>& __x, const _Up& __v) {
1185 return static_cast<bool>(__x) ? *__x < __v : true;
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 _Tp& __v, const optional<_Up>& __x) {
1193 return static_cast<bool>(__x) ? __v < *__x : false;
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 optional<_Tp>& __x, const _Up& __v) {
1201 return static_cast<bool>(__x) ? *__x <= __v : true;
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 _Tp& __v, const optional<_Up>& __x) {
1209 return static_cast<bool>(__x) ? __v <= *__x : 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 optional<_Tp>& __x, const _Up& __v) {
1217 return static_cast<bool>(__x) ? *__x > __v : false;
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 _Tp& __v, const optional<_Up>& __x) {
1225 return static_cast<bool>(__x) ? __v > *__x : true;
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 optional<_Tp>& __x, const _Up& __v) {
1233 return static_cast<bool>(__x) ? *__x >= __v : false;
1234 }
1235
1236 template <class _Tp, class _Up>
1237 _LIBCPP_HIDE_FROM_ABI constexpr enable_if_t<
1238 is_convertible_v<decltype(std::declval<const _Tp&>() >= std::declval<const _Up&>()), bool>,
1239 bool >
1240 operator>=(const _Tp& __v, const optional<_Up>& __x) {
1241 return static_cast<bool>(__x) ? __v >= *__x : true;
1242 }
1243
1244 # if _LIBCPP_STD_VER >= 20
1245
1246 template <class _Tp, class _Up>
1247 requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up>
1248 _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up>
1249 operator<=>(const optional<_Tp>& __x, const _Up& __v) {
1250 return __x.has_value() ? *__x <=> __v : strong_ordering::less;
1251 }
1252
1253 # endif // _LIBCPP_STD_VER >= 20
1254
1255 template <class _Tp>
1256 inline _LIBCPP_HIDE_FROM_ABI
1257 _LIBCPP_CONSTEXPR_SINCE_CXX20 enable_if_t< is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, void >
1258 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) {
1259 __x.swap(__y);
1260 }
1261
1262 template <class _Tp>
1263 _LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) {
1264 return optional<decay_t<_Tp>>(std::forward<_Tp>(__v));
1265 }
1266
1267 template <class _Tp, class... _Args>
1268 _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) {
1269 return optional<_Tp>(in_place, std::forward<_Args>(__args)...);
1270 }
1271
1272 template <class _Tp, class _Up, class... _Args>
1273 _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) {
1274 return optional<_Tp>(in_place, __il, std::forward<_Args>(__args)...);
1275 }
1276
1277 template <class _Tp>
1278 struct _LIBCPP_TEMPLATE_VIS hash< __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> > {
1279 # if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1280 _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
1281 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1282 # endif
1283
1284 _LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const {
1285 return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
1286 }
1287 };
1288
1289 _LIBCPP_END_NAMESPACE_STD
1290
1291 # endif // _LIBCPP_STD_VER >= 17
1292
1293 _LIBCPP_POP_MACROS
1294
1295 # if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1296 # include <atomic>
1297 # include <climits>
1298 # include <concepts>
1299 # include <ctime>
1300 # include <iterator>
1301 # include <limits>
1302 # include <memory>
1303 # include <ratio>
1304 # include <stdexcept>
1305 # include <tuple>
1306 # include <type_traits>
1307 # include <typeinfo>
1308 # include <utility>
1309 # include <variant>
1310 # endif
1311 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
1312
1313 #endif // _LIBCPP_OPTIONAL