From 3ad39e9878310e5317ee73c9b353c1e2c1c5c4ee Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Sat, 11 Jul 2026 22:48:30 +0800 Subject: lib: establish Zircon libc++ and KTL foundation --- third_party/libcxx/include/c++/v1/optional | 1771 ++++++++++++++++++++++++++++ 1 file changed, 1771 insertions(+) create mode 100644 third_party/libcxx/include/c++/v1/optional (limited to 'third_party/libcxx/include/c++/v1/optional') diff --git a/third_party/libcxx/include/c++/v1/optional b/third_party/libcxx/include/c++/v1/optional new file mode 100644 index 0000000..9eed886 --- /dev/null +++ b/third_party/libcxx/include/c++/v1/optional @@ -0,0 +1,1771 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_OPTIONAL +#define _LIBCPP_OPTIONAL + +/* + optional synopsis + +// C++1z + +namespace std { + // [optional.optional], class template optional + template + class optional; + + template + constexpr bool ranges::enable_view> = true; + template + constexpr auto format_kind> = range_format::disabled; + + template + concept is-derived-from-optional = requires(const T& t) { // exposition only + [](const optional&){ }(t); + }; + + // [optional.nullopt], no-value state indicator + struct nullopt_t{see below }; + inline constexpr nullopt_t nullopt(unspecified ); + + // [optional.bad.access], class bad_optional_access + class bad_optional_access; + + // [optional.relops], relational operators + template + constexpr bool operator==(const optional&, const optional&); + template + constexpr bool operator!=(const optional&, const optional&); + template + constexpr bool operator<(const optional&, const optional&); + template + constexpr bool operator>(const optional&, const optional&); + template + constexpr bool operator<=(const optional&, const optional&); + template + constexpr bool operator>=(const optional&, const optional&); + template U> + constexpr compare_three_way_result_t + operator<=>(const optional&, const optional&); // since C++20 + + // [optional.nullops], comparison with nullopt + template constexpr bool operator==(const optional&, nullopt_t) noexcept; + template constexpr bool operator==(nullopt_t, const optional&) noexcept; // until C++17 + template constexpr bool operator!=(const optional&, nullopt_t) noexcept; // until C++17 + template constexpr bool operator!=(nullopt_t, const optional&) noexcept; // until C++17 + template constexpr bool operator<(const optional&, nullopt_t) noexcept; // until C++17 + template constexpr bool operator<(nullopt_t, const optional&) noexcept; // until C++17 + template constexpr bool operator<=(const optional&, nullopt_t) noexcept; // until C++17 + template constexpr bool operator<=(nullopt_t, const optional&) noexcept; // until C++17 + template constexpr bool operator>(const optional&, nullopt_t) noexcept; // until C++17 + template constexpr bool operator>(nullopt_t, const optional&) noexcept; // until C++17 + template constexpr bool operator>=(const optional&, nullopt_t) noexcept; // until C++17 + template constexpr bool operator>=(nullopt_t, const optional&) noexcept; // until C++17 + template + constexpr strong_ordering operator<=>(const optional&, nullopt_t) noexcept; // since C++20 + + // [optional.comp.with.t], comparison with T + template constexpr bool operator==(const optional&, const U&); + template constexpr bool operator==(const T&, const optional&); + template constexpr bool operator!=(const optional&, const U&); + template constexpr bool operator!=(const T&, const optional&); + template constexpr bool operator<(const optional&, const U&); + template constexpr bool operator<(const T&, const optional&); + template constexpr bool operator<=(const optional&, const U&); + template constexpr bool operator<=(const T&, const optional&); + template constexpr bool operator>(const optional&, const U&); + template constexpr bool operator>(const T&, const optional&); + template constexpr bool operator>=(const optional&, const U&); + template constexpr bool operator>=(const T&, const optional&); + template + requires (!is-derived-from-optional) && three_way_comparable_with + constexpr compare_three_way_result_t + operator<=>(const optional&, const U&); // since C++20 + + // [optional.specalg], specialized algorithms + template + void swap(optional&, optional&) noexcept(see below ); // constexpr in C++20 + + template + constexpr optional make_optional(T&&); + template + constexpr optional make_optional(Args&&... args); + template + constexpr optional make_optional(initializer_list il, Args&&... args); + + // [optional.hash], hash support + template struct hash; + template struct hash>; + + template + class optional { + public: + using value_type = T; + using iterator = implementation-defined; // see [optional.iterators] + using const_iterator = implementation-defined; // see [optional.iterators] + + // [optional.ctor], constructors + constexpr optional() noexcept; + constexpr optional(nullopt_t) noexcept; + constexpr optional(const optional &); + constexpr optional(optional &&) noexcept(see below); + template + constexpr explicit optional(in_place_t, Args &&...); + template + constexpr explicit optional(in_place_t, initializer_list, Args &&...); + template> + constexpr explicit(see-below) optional(U &&); + template + explicit(see-below) optional(const optional &); // constexpr in C++20 + template + explicit(see-below) optional(optional &&); // constexpr in C++20 + + // [optional.dtor], destructor + ~optional(); // constexpr in C++20 + + // [optional.assign], assignment + optional &operator=(nullopt_t) noexcept; // constexpr in C++20 + constexpr optional &operator=(const optional &); + constexpr optional &operator=(optional &&) noexcept(see below); + template> optional &operator=(U &&); // constexpr in C++20 + template optional &operator=(const optional &); // constexpr in C++20 + template optional &operator=(optional &&); // constexpr in C++20 + template T& emplace(Args &&...); // constexpr in C++20 + template T& emplace(initializer_list, Args &&...); // constexpr in C++20 + + // [optional.swap], swap + void swap(optional &) noexcept(see below ); // constexpr in C++20 + + // [optional.iterators], iterator support + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + + // [optional.observe], observers + constexpr T const *operator->() const noexcept; + constexpr T *operator->() noexcept; + constexpr T const &operator*() const & noexcept; + constexpr T &operator*() & noexcept; + constexpr T &&operator*() && noexcept; + constexpr const T &&operator*() const && noexcept; + constexpr explicit operator bool() const noexcept; + constexpr bool has_value() const noexcept; + constexpr T const &value() const &; + constexpr T &value() &; + constexpr T &&value() &&; + constexpr const T &&value() const &&; + template> constexpr T value_or(U &&) const &; + template> constexpr T value_or(U &&) &&; + + // [optional.monadic], monadic operations + template constexpr auto and_then(F&& f) &; // since C++23 + template constexpr auto and_then(F&& f) &&; // since C++23 + template constexpr auto and_then(F&& f) const&; // since C++23 + template constexpr auto and_then(F&& f) const&&; // since C++23 + template constexpr auto transform(F&& f) &; // since C++23 + template constexpr auto transform(F&& f) &&; // since C++23 + template constexpr auto transform(F&& f) const&; // since C++23 + template constexpr auto transform(F&& f) const&&; // since C++23 + template constexpr optional or_else(F&& f) &&; // since C++23 + template constexpr optional or_else(F&& f) const&; // since C++23 + + // [optional.mod], modifiers + void reset() noexcept; // constexpr in C++20 + + private: + T *val; // exposition only + }; + + template + optional(T) -> optional; + + template + class optional { // since C++26 + public: + using value_type = T; + using iterator = implementation-defined; // see [optional.ref.iterators] + + public: + // [optional.ref.ctor], constructors + constexpr optional() noexcept = default; + constexpr optional(nullopt_t) noexcept : optional() {} + constexpr optional(const optional& rhs) noexcept = default; + + template + constexpr explicit optional(in_place_t, Arg&& arg); + template + constexpr explicit(see below) optional(U&& u) noexcept(see below); + template + constexpr explicit(see below) optional(optional& rhs) noexcept(see below); + template + constexpr explicit(see below) optional(const optional& rhs) noexcept(see below); + template + constexpr explicit(see below) optional(optional&& rhs) noexcept(see below); + template + constexpr explicit(see below) optional(const optional&& rhs) noexcept(see below); + + constexpr ~optional() = default; + + // [optional.ref.assign], assignment + constexpr optional& operator=(nullopt_t) noexcept; + constexpr optional& operator=(const optional& rhs) noexcept = default; + + template constexpr T& emplace(U&& u) noexcept(see below); + + // [optional.ref.swap], swap + constexpr void swap(optional& rhs) noexcept; + + // [optional.ref.iterators], iterator support + constexpr iterator begin() const noexcept; + constexpr iterator end() const noexcept; + + // [optional.ref.observe], observers + constexpr T* operator->() const noexcept; + constexpr T& operator*() const noexcept; + constexpr explicit operator bool() const noexcept; + constexpr bool has_value() const noexcept; + constexpr T& value() const; // freestanding-deleted + template> + constexpr remove_cv_t value_or(U&& u) const; + + // [optional.ref.monadic], monadic operations + template constexpr auto and_then(F&& f) const; + template constexpr optional> transform(F&& f) const; + template constexpr optional or_else(F&& f) const; + + // [optional.ref.mod], modifiers + constexpr void reset() noexcept; + + private: + T* val = nullptr; // exposition only + + // [optional.ref.expos], exposition only helper functions + template + constexpr void convert-ref-init-val(U&& u); // exposition only + }; + +} // namespace std + +*/ + +#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) +# include <__cxx03/__config> +#else +# include <__assert> +# include <__compare/compare_three_way_result.h> +# include <__compare/ordering.h> +# include <__compare/three_way_comparable.h> +# include <__concepts/invocable.h> +# include <__config> +# include <__exception/exception.h> +# include <__functional/hash.h> +# include <__functional/invoke.h> +# include <__functional/unary_function.h> +# include <__fwd/format.h> +# include <__fwd/functional.h> +# include <__iterator/bounded_iter.h> +# include <__iterator/capacity_aware_iterator.h> +# include <__memory/addressof.h> +# include <__memory/construct_at.h> +# include <__ranges/enable_borrowed_range.h> +# include <__ranges/enable_view.h> +# include <__tuple/sfinae_helpers.h> +# include <__type_traits/add_pointer.h> +# include <__type_traits/conditional.h> +# include <__type_traits/conjunction.h> +# include <__type_traits/decay.h> +# include <__type_traits/disjunction.h> +# include <__type_traits/enable_if.h> +# include <__type_traits/integral_constant.h> +# include <__type_traits/invoke.h> +# include <__type_traits/is_array.h> +# include <__type_traits/is_assignable.h> +# include <__type_traits/is_constructible.h> +# include <__type_traits/is_convertible.h> +# include <__type_traits/is_core_convertible.h> +# include <__type_traits/is_destructible.h> +# include <__type_traits/is_function.h> +# include <__type_traits/is_nothrow_assignable.h> +# include <__type_traits/is_nothrow_constructible.h> +# include <__type_traits/is_object.h> +# include <__type_traits/is_reference.h> +# include <__type_traits/is_same.h> +# include <__type_traits/is_scalar.h> +# include <__type_traits/is_swappable.h> +# include <__type_traits/is_trivially_assignable.h> +# include <__type_traits/is_trivially_constructible.h> +# include <__type_traits/is_trivially_destructible.h> +# include <__type_traits/is_trivially_relocatable.h> +# include <__type_traits/negation.h> +# include <__type_traits/reference_constructs_from_temporary.h> +# include <__type_traits/remove_const.h> +# include <__type_traits/remove_cv.h> +# include <__type_traits/remove_cvref.h> +# include <__type_traits/remove_reference.h> +# include <__utility/declval.h> +# include <__utility/forward.h> +# include <__utility/in_place.h> +# include <__utility/move.h> +# include <__utility/swap.h> +# include <__verbose_abort> +# include +# include + +// standard-mandated includes + +// [optional.syn] +# include + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_PUSH_MACROS +# include <__undef_macros> + +namespace std // purposefully not using versioning namespace +{ + +class _LIBCPP_EXPORTED_FROM_ABI bad_optional_access : public exception { +public: + _LIBCPP_HIDE_FROM_ABI bad_optional_access() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_optional_access(const bad_optional_access&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_optional_access& operator=(const bad_optional_access&) _NOEXCEPT = default; + // Get the key function ~bad_optional_access() into the dylib + ~bad_optional_access() _NOEXCEPT override; + [[__nodiscard__]] const char* what() const _NOEXCEPT override; +}; + +} // namespace std + +# if _LIBCPP_STD_VER >= 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +[[noreturn]] inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_optional_access() { +# if _LIBCPP_HAS_EXCEPTIONS + throw bad_optional_access(); +# else + _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode"); +# endif +} + +struct nullopt_t { + struct __secret_tag { + explicit __secret_tag() = default; + }; + _LIBCPP_HIDE_FROM_ABI constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {} +}; + +inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}}; + +struct __optional_construct_from_invoke_tag {}; + +template ::value> +struct __optional_destruct_base; + +template +struct __optional_destruct_base<_Tp, false> { + typedef _Tp value_type; + static_assert(is_object_v, "instantiation of optional with a non-object type is undefined behavior"); + union { + char __null_state_; + remove_cv_t __val_; + }; + bool __engaged_; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__optional_destruct_base() { + if (__engaged_) + __val_.~value_type(); + } + + _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) + : __val_(std::forward<_Args>(__args)...), __engaged_(true) {} + +# if _LIBCPP_STD_VER >= 23 + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base( + __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) + : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {} +# endif + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { + if (__engaged_) { + __val_.~value_type(); + __engaged_ = false; + } + } +}; + +template +struct __optional_destruct_base<_Tp, true> { + typedef _Tp value_type; + static_assert(is_object_v, "instantiation of optional with a non-object type is undefined behavior"); + union { + char __null_state_; + remove_cv_t __val_; + }; + bool __engaged_; + + _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base() noexcept : __null_state_(), __engaged_(false) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) + : __val_(std::forward<_Args>(__args)...), __engaged_(true) {} + +# if _LIBCPP_STD_VER >= 23 + template + _LIBCPP_HIDE_FROM_ABI constexpr __optional_destruct_base( + __optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) + : __val_(std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...)), __engaged_(true) {} +# endif + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { + if (__engaged_) { + __engaged_ = false; + } + } +}; + +template ::value> +struct __optional_storage_base : __optional_destruct_base<_Tp> { + using __base _LIBCPP_NODEBUG = __optional_destruct_base<_Tp>; + using value_type = _Tp; + using __base::__base; + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; } + + _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() & noexcept { return this->__val_; } + _LIBCPP_HIDE_FROM_ABI constexpr const value_type& __get() const& noexcept { return this->__val_; } + _LIBCPP_HIDE_FROM_ABI constexpr value_type&& __get() && noexcept { return std::move(this->__val_); } + _LIBCPP_HIDE_FROM_ABI constexpr const value_type&& __get() const&& noexcept { return std::move(this->__val_); } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) { + _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage"); + std::__construct_at(std::addressof(this->__val_), std::forward<_Args>(__args)...); + this->__engaged_ = true; + } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) { + if (__opt.has_value()) + __construct(std::forward<_That>(__opt).__get()); + } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) { + if (this->__engaged_ == __opt.has_value()) { + if (this->__engaged_) + static_cast<_Tp&>(this->__val_) = std::forward<_That>(__opt).__get(); + } else { + if (this->__engaged_) + this->reset(); + else + __construct(std::forward<_That>(__opt).__get()); + } + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void + __swap(__optional_storage_base& __rhs) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>) { + using std::swap; + if (this->has_value() == __rhs.has_value()) { + if (this->has_value()) + swap(this->__get(), __rhs.__get()); + } else { + if (this->has_value()) { + __rhs.__construct(std::move(this->__get())); + this->reset(); + } else { + this->__construct(std::move(__rhs.__get())); + __rhs.reset(); + } + } + } + + // [optional.observe] + _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp const> operator->() const noexcept { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); + return std::addressof(this->__get()); + } + + _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> operator->() noexcept { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); + return std::addressof(this->__get()); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); + return this->__get(); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); + return this->__get(); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); + return std::move(this->__get()); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); + return std::move(this->__get()); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& value() const& { + if (!this->has_value()) + std::__throw_bad_optional_access(); + return this->__get(); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { + if (!this->has_value()) + std::__throw_bad_optional_access(); + return this->__get(); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { + if (!this->has_value()) + std::__throw_bad_optional_access(); + return std::move(this->__get()); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp const&& value() const&& { + if (!this->has_value()) + std::__throw_bad_optional_access(); + return std::move(this->__get()); + } +}; + +template +struct __optional_storage_base<_Tp, true> { + using value_type = _Tp; + using __raw_type _LIBCPP_NODEBUG = remove_reference_t<_Tp>; + __raw_type* __value_; + + _LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr void __convert_init_ref_val(_Up&& __val) noexcept { + _Tp& __r(std::forward<_Up>(__val)); + __value_ = std::addressof(__r); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) { + static_assert(!__reference_constructs_from_temporary_v<_Tp, _UArg>, + "Attempted to construct a reference element in optional from a " + "possible temporary"); + __convert_init_ref_val(std::forward<_UArg>(__uarg)); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __value_ != nullptr; } + + _LIBCPP_HIDE_FROM_ABI constexpr value_type& __get() const noexcept { return *__value_; } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) { + _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage"); + static_assert(!__reference_constructs_from_temporary_v<_Tp, _UArg>, + "Attempted to construct a reference element in tuple from a " + "possible temporary"); + __convert_init_ref_val(std::forward<_UArg>(__val)); + } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_from(_That&& __opt) { + if (__opt.has_value()) + __construct(std::forward<_That>(__opt).__get()); + } + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __assign_from(_That&& __opt) { + if (has_value() == __opt.has_value()) { + if (has_value()) + *__value_ = std::forward<_That>(__opt).__get(); + } else { + if (has_value()) + reset(); + else + __construct(std::forward<_That>(__opt).__get()); + } + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __swap(__optional_storage_base& __rhs) noexcept { + std::swap(__value_, __rhs.__value_); + } + + // [optional.ref.observe] + _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> operator->() const noexcept { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); + return std::addressof(this->__get()); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() const noexcept { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); + return this->__get(); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() const { + if (!this->has_value()) + std::__throw_bad_optional_access(); + return this->__get(); + } +}; + +template || is_lvalue_reference_v<_Tp>> +struct __optional_copy_base : __optional_storage_base<_Tp> { + using __optional_storage_base<_Tp>::__optional_storage_base; +}; + +template +struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp> { + using __optional_storage_base<_Tp>::__optional_storage_base; + + _LIBCPP_HIDE_FROM_ABI __optional_copy_base() = default; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_base(const __optional_copy_base& __opt) { + this->__construct_from(__opt); + } + + _LIBCPP_HIDE_FROM_ABI __optional_copy_base(__optional_copy_base&&) = default; + _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(const __optional_copy_base&) = default; + _LIBCPP_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&) = default; +}; + +template || is_lvalue_reference_v<_Tp>> +struct __optional_move_base : __optional_copy_base<_Tp> { + using __optional_copy_base<_Tp>::__optional_copy_base; +}; + +template +struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp> { + using value_type = _Tp; + using __optional_copy_base<_Tp>::__optional_copy_base; + + _LIBCPP_HIDE_FROM_ABI __optional_move_base() = default; + _LIBCPP_HIDE_FROM_ABI __optional_move_base(const __optional_move_base&) = default; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + __optional_move_base(__optional_move_base&& __opt) noexcept(is_nothrow_move_constructible_v) { + this->__construct_from(std::move(__opt)); + } + + _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(const __optional_move_base&) = default; + _LIBCPP_HIDE_FROM_ABI __optional_move_base& operator=(__optional_move_base&&) = default; +}; + +template && is_trivially_copy_constructible_v<_Tp> && + is_trivially_copy_assignable_v<_Tp>) || + is_lvalue_reference_v<_Tp>> +struct __optional_copy_assign_base : __optional_move_base<_Tp> { + using __optional_move_base<_Tp>::__optional_move_base; +}; + +template +struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp> { + using __optional_move_base<_Tp>::__optional_move_base; + + _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base() = default; + _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(const __optional_copy_assign_base&) = default; + _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base(__optional_copy_assign_base&&) = default; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_copy_assign_base& + operator=(const __optional_copy_assign_base& __opt) { + this->__assign_from(__opt); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default; +}; + +template && is_trivially_move_constructible_v<_Tp> && + is_trivially_move_assignable_v<_Tp>) || + is_lvalue_reference_v<_Tp>> +struct __optional_move_assign_base : __optional_copy_assign_base<_Tp> { + using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; +}; + +template +struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp> { + using value_type = _Tp; + using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base; + + _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base() = default; + _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(const __optional_move_assign_base& __opt) = default; + _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base(__optional_move_assign_base&&) = default; + _LIBCPP_HIDE_FROM_ABI __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __optional_move_assign_base& + operator=(__optional_move_assign_base&& __opt) noexcept( + is_nothrow_move_assignable_v && is_nothrow_move_constructible_v) { + this->__assign_from(std::move(__opt)); + return *this; + } +}; + +template +using __optional_sfinae_ctor_base_t _LIBCPP_NODEBUG = + __sfinae_ctor_base< is_copy_constructible<_Tp>::value, is_move_constructible<_Tp>::value >; + +template +using __optional_sfinae_assign_base_t _LIBCPP_NODEBUG = + __sfinae_assign_base< (is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Tp>) || is_lvalue_reference_v<_Tp>, + (is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp>) || is_lvalue_reference_v<_Tp>>; + +template +class optional; + +# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR +template +constexpr bool ranges::enable_view> = true; + +template +constexpr range_format format_kind> = range_format::disabled; + +template +constexpr bool ranges::enable_borrowed_range> = true; + +# endif + +# if _LIBCPP_STD_VER >= 20 + +template +concept __is_derived_from_optional = requires(const _Tp& __t) { [](const optional<_Up>&) {}(__t); }; + +# endif // _LIBCPP_STD_VER >= 20 + +template +struct __is_std_optional : false_type {}; +template +struct __is_std_optional> : true_type {}; + +template +inline constexpr bool __is_constructible_for_optional_v = is_constructible_v<_Tp, _Args...>; + +template +struct __is_constructible_for_optional : bool_constant<__is_constructible_for_optional_v<_Tp, _Args...>> {}; + +template +inline constexpr bool __is_constructible_for_optional_initializer_list_v = + is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>; + +# if _LIBCPP_STD_VER >= 26 +template +inline constexpr bool __is_constructible_for_optional_v<_Tp&, _Args...> = false; +template +inline constexpr bool __is_constructible_for_optional_v<_Tp&, _Arg> = + is_constructible_v<_Tp&, _Arg> && !reference_constructs_from_temporary_v<_Tp&, _Arg>; + +template +inline constexpr bool __is_constructible_for_optional_initializer_list_v<_Tp&, _Up, _Args...> = false; +# endif + +template +struct __optional_iterator_base : __optional_move_assign_base<_Tp> { + using __optional_move_assign_base<_Tp>::__optional_move_assign_base; +}; + +# if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR + +template +struct __optional_iterator_base<_Tp, enable_if_t>> : __optional_move_assign_base<_Tp> { +private: + using __pointer _LIBCPP_NODEBUG = add_pointer_t<_Tp>; + using __const_pointer _LIBCPP_NODEBUG = add_pointer_t; + +public: + using __optional_move_assign_base<_Tp>::__optional_move_assign_base; + +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL + using iterator = __bounded_iter<__pointer>; + using const_iterator = __bounded_iter<__const_pointer>; +# else + using iterator = __capacity_aware_iterator<__pointer, optional<_Tp>, 1>; + using const_iterator = __capacity_aware_iterator<__const_pointer, optional<_Tp>, 1>; +# endif + + // [optional.iterators], iterator support + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept { + auto* __ptr = std::addressof(this->__get()); + +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL + return std::__make_bounded_iter(__ptr, __ptr, __ptr + (this->has_value() ? 1 : 0)); +# else + return std::__make_capacity_aware_iterator<__pointer, optional<_Tp>, 1>(__ptr); +# endif + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { + auto* __ptr = std::addressof(this->__get()); + +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL + return std::__make_bounded_iter(__ptr, __ptr, __ptr + (this->has_value() ? 1 : 0)); +# else + return std::__make_capacity_aware_iterator<__const_pointer, optional<_Tp>, 1>(__ptr); +# endif + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept { + return begin() + (this->has_value() ? 1 : 0); + } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { + return begin() + (this->has_value() ? 1 : 0); + } +}; + +template +struct __optional_iterator_base<_Tp&, enable_if_t && !__is_unbounded_array_v<_Tp> >> + : __optional_move_assign_base<_Tp&> { +private: + using __pointer _LIBCPP_NODEBUG = add_pointer_t<_Tp>; + +public: + using __optional_move_assign_base<_Tp&>::__optional_move_assign_base; + +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL + using iterator = __bounded_iter<__pointer>; +# else + using iterator = __capacity_aware_iterator<__pointer, optional<_Tp&>, 1>; +# endif + + // [optional.ref.iterators], iterator support + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const noexcept { + auto* __ptr = this->has_value() ? std::addressof(this->__get()) : nullptr; + +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS_IN_OPTIONAL + return std::__make_bounded_iter(__ptr, __ptr, __ptr + (this->has_value() ? 1 : 0)); +# else + return std::__make_capacity_aware_iterator<__pointer, optional<_Tp&>, 1>(__ptr); +# endif + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const noexcept { + return begin() + (this->has_value() ? 1 : 0); + } +}; + +# endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPERIMENTAL_OPTIONAL_ITERATOR + +template +class _LIBCPP_DECLSPEC_EMPTY_BASES optional + : public __optional_iterator_base<_Tp>, + private __optional_sfinae_ctor_base_t<_Tp>, + private __optional_sfinae_assign_base_t<_Tp> { + using __base _LIBCPP_NODEBUG = __optional_iterator_base<_Tp>; + +public: + using value_type = __libcpp_remove_reference_t<_Tp>; + + using __trivially_relocatable _LIBCPP_NODEBUG = + conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>; + +private: + static_assert(!is_same_v<__remove_cvref_t<_Tp>, in_place_t>, + "instantiation of optional with in_place_t is ill-formed"); + static_assert(!is_same_v<__remove_cvref_t<_Tp>, nullopt_t>, "instantiation of optional with nullopt_t is ill-formed"); +# if _LIBCPP_STD_VER >= 26 + static_assert(!is_rvalue_reference_v<_Tp>, "instantiation of optional with an rvalue reference type is ill-formed"); +# else + static_assert(!is_reference_v<_Tp>, "instantiation of optional with a reference type is ill-formed"); +# endif + static_assert(is_destructible_v<_Tp>, "instantiation of optional with a non-destructible type is ill-formed"); + static_assert(!is_array_v<_Tp>, "instantiation of optional with an array type is ill-formed"); + +# if _LIBCPP_STD_VER >= 26 + template + constexpr static bool __libcpp_opt_ref_ctor_deleted = + is_lvalue_reference_v<_Tp> && reference_constructs_from_temporary_v<_Tp, _Up>; +# endif + + // LWG2756: conditionally explicit conversion from _Up + struct _CheckOptionalArgsConstructor { + template + _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() { + return is_constructible_v<_Tp, _Up&&> && is_convertible_v<_Up&&, _Tp>; + } + + template + _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() { + return is_constructible_v<_Tp, _Up&&> && !is_convertible_v<_Up&&, _Tp>; + } + }; + template + using _CheckOptionalArgsCtor _LIBCPP_NODEBUG = + _If< _IsNotSame<__remove_cvref_t<_Up>, in_place_t>::value && _IsNotSame<__remove_cvref_t<_Up>, optional>::value && + (!is_same_v, bool> || !__is_std_optional<__remove_cvref_t<_Up>>::value), + _CheckOptionalArgsConstructor, + __check_tuple_constructor_fail >; + template + struct _CheckOptionalLikeConstructor { + template > + using __check_constructible_from_opt _LIBCPP_NODEBUG = + _Or< is_constructible<_Tp, _Opt&>, + is_constructible<_Tp, _Opt const&>, + is_constructible<_Tp, _Opt&&>, + is_constructible<_Tp, _Opt const&&>, + is_convertible<_Opt&, _Tp>, + is_convertible<_Opt const&, _Tp>, + is_convertible<_Opt&&, _Tp>, + is_convertible<_Opt const&&, _Tp> >; + template > + using __check_assignable_from_opt _LIBCPP_NODEBUG = + _Or< is_assignable<_Tp&, _Opt&>, + is_assignable<_Tp&, _Opt const&>, + is_assignable<_Tp&, _Opt&&>, + is_assignable<_Tp&, _Opt const&&> >; + template + _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() { + return is_convertible<_QUp, _Tp>::value && + (is_same_v, bool> || !__check_constructible_from_opt<_Up>::value); + } + template + _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() { + return !is_convertible<_QUp, _Tp>::value && + (is_same_v, bool> || !__check_constructible_from_opt<_Up>::value); + } + template + _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() { + // Construction and assignability of _QUp to _Tp has already been + // checked. + return !__check_constructible_from_opt<_Up>::value && !__check_assignable_from_opt<_Up>::value; + } + }; + + template + using _CheckOptionalLikeCtor _LIBCPP_NODEBUG = + _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp> >::value, + _CheckOptionalLikeConstructor<_QualUp>, + __check_tuple_constructor_fail >; + template + using _CheckOptionalLikeAssign _LIBCPP_NODEBUG = + _If< _And< _IsNotSame<_Up, _Tp>, is_constructible<_Tp, _QualUp>, is_assignable<_Tp&, _QualUp> >::value, + _CheckOptionalLikeConstructor<_QualUp>, + __check_tuple_constructor_fail >; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr optional() noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr optional(const optional&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr optional(optional&&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr optional(nullopt_t) noexcept {} + + template < + class _InPlaceT, + class... _Args, + enable_if_t<_And<_IsSame<_InPlaceT, in_place_t>, __is_constructible_for_optional<_Tp, _Args...>>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_InPlaceT, _Args&&... __args) + : __base(in_place, std::forward<_Args>(__args)...) {} + + template , int> = 0> + _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) + : __base(in_place, __il, std::forward<_Args>(__args)...) {} + + template ::template __enable_implicit<_Up>(), int> = 0> + _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) +# if _LIBCPP_STD_VER >= 26 + noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up>) +# endif + : __base(in_place, std::forward<_Up>(__v)) { + } + + template , + enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0> + _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) +# if _LIBCPP_STD_VER >= 26 + noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up>) +# endif + : __base(in_place, std::forward<_Up>(__v)) { + } + + // LWG2756: conditionally explicit conversion from const optional<_Up>& + template ::template __enable_implicit<_Up>(), int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) +# if _LIBCPP_STD_VER >= 26 + noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up&>) +# endif + { + this->__construct_from(__v); + } + template ::template __enable_explicit<_Up>(), int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) +# if _LIBCPP_STD_VER >= 26 + noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up&>) +# endif + { + this->__construct_from(__v); + } + + // LWG2756: conditionally explicit conversion from optional<_Up>&& + template ::template __enable_implicit<_Up>(), int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) +# if _LIBCPP_STD_VER >= 26 + noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up>) +# endif + { + this->__construct_from(std::move(__v)); + } + template ::template __enable_explicit<_Up>(), int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) +# if _LIBCPP_STD_VER >= 26 + noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp&, _Up>) +# endif + { + this->__construct_from(std::move(__v)); + } + + // deleted optional constructors and additional optional constructors +# if _LIBCPP_STD_VER >= 26 + // optional(U&&) + template ::template __enable_implicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + optional(_Up&&) = delete; + + template , + enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + explicit optional(_Up&&) = delete; + + // optional(optional& rhs) + template + requires(!__libcpp_opt_ref_ctor_deleted<_Up>) && (!is_same_v, optional<_Up>>) && + (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up&> + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up&, _Tp&>) + optional(optional<_Up>& __rhs) noexcept(is_nothrow_constructible_v<_Tp&, _Up&>) { + this->__construct_from(__rhs); + } + + template + requires __libcpp_opt_ref_ctor_deleted<_Up> && (!is_same_v, optional<_Up>>) && + (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up&> + constexpr explicit optional(optional<_Up>& __rhs) noexcept = delete; + + // optional(const optional&) + template ::template __enable_implicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + optional(const optional<_Up>&) = delete; + + template ::template __enable_explicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + explicit optional(const optional<_Up>&) = delete; + + // optional(optional&&) + template ::template __enable_implicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + optional(optional<_Up>&&) = delete; + + template ::template __enable_explicit<_Up>(), int> = 0> + requires __libcpp_opt_ref_ctor_deleted<_Up> + explicit optional(optional<_Up>&&) = delete; + + // optional(const optional&&) + template + requires(!__libcpp_opt_ref_ctor_deleted<_Up>) && (!is_same_v, optional<_Up>>) && + (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!is_convertible_v) + optional(const optional<_Up>&& __v) noexcept(is_nothrow_constructible_v<_Tp&, const _Up>) { + this->__construct_from(std::move(__v)); + } + + template + requires __libcpp_opt_ref_ctor_deleted<_Up> && (!is_same_v, optional<_Up>>) && + (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>&& __v) noexcept = delete; +# endif + +# if _LIBCPP_STD_VER >= 23 + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Tag, _Fp&& __f, _Args&&... __args) + : __base(__optional_construct_from_invoke_tag{}, std::forward<_Fp>(__f), std::forward<_Args>(__args)...) {} +# endif + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(nullopt_t) noexcept { + reset(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default; + _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default; + + // LWG2756 + template , + enable_if_t<_And<_IsNotSame<__remove_cvref_t<_Up>, optional>, + _Or<_IsNotSame<__remove_cvref_t<_Up>, _Tp>, _Not>>, + is_constructible<_Tp, _Up>, + is_assignable<_Tp&, _Up>, + is_object<_Tp>>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) { + if (this->has_value()) + this->__get() = std::forward<_Up>(__v); + else + this->__construct(std::forward<_Up>(__v)); + return *this; + } + + // LWG2756 + template ::template __enable_assign<_Up>(), int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(const optional<_Up>& __v) { + this->__assign_from(__v); + return *this; + } + + // LWG2756 + template ::template __enable_assign<_Up>(), int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(optional<_Up>&& __v) { + this->__assign_from(std::move(__v)); + return *this; + } + + template , int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) +# if _LIBCPP_STD_VER >= 26 + noexcept(is_lvalue_reference_v<_Tp> && is_nothrow_constructible_v<_Tp, _Args...>) +# endif + { + reset(); + this->__construct(std::forward<_Args>(__args)...); + return this->__get(); + } + + template , int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) { + reset(); + this->__construct(__il, std::forward<_Args>(__args)...); + return this->__get(); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional& __opt) noexcept( + (is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>) +# if _LIBCPP_STD_VER >= 26 + || is_lvalue_reference_v<_Tp> +# endif + ) { + this->__swap(__opt); + } + + using __base::operator*; + using __base::operator->; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return has_value(); } + + using __base::__get; + using __base::has_value; + using __base::value; + + template > +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& { + static_assert(is_copy_constructible_v<_Tp>, "optional::value_or: T must be copy constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "optional::value_or: U must be convertible to T"); + return this->has_value() ? this->__get() : static_cast<_Tp>(std::forward<_Up>(__v)); + } + + template > +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && { + static_assert(is_move_constructible_v<_Tp>, "optional::value_or: T must be move constructible"); + static_assert(is_convertible_v<_Up, _Tp>, "optional::value_or: U must be convertible to T"); + return this->has_value() ? std::move(this->__get()) : static_cast<_Tp>(std::forward<_Up>(__v)); + } + +# if _LIBCPP_STD_VER >= 23 + template +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { + using _Up = invoke_result_t<_Func, _Tp&>; + static_assert(__is_std_optional>::value, + "Result of f(value()) must be a specialization of std::optional"); + if (*this) + return std::invoke(std::forward<_Func>(__f), value()); + return remove_cvref_t<_Up>(); + } + + template +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { + using _Up = invoke_result_t<_Func, const _Tp&>; + static_assert(__is_std_optional>::value, + "Result of f(value()) must be a specialization of std::optional"); + if (*this) + return std::invoke(std::forward<_Func>(__f), value()); + return remove_cvref_t<_Up>(); + } + + template +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { + using _Up = invoke_result_t<_Func, _Tp&&>; + static_assert(__is_std_optional>::value, + "Result of f(std::move(value())) must be a specialization of std::optional"); + if (*this) + return std::invoke(std::forward<_Func>(__f), std::move(value())); + return remove_cvref_t<_Up>(); + } + + template +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { + using _Up = invoke_result_t<_Func, const _Tp&&>; + static_assert(__is_std_optional>::value, + "Result of f(std::move(value())) must be a specialization of std::optional"); + if (*this) + return std::invoke(std::forward<_Func>(__f), std::move(value())); + return remove_cvref_t<_Up>(); + } + + template +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { + using _Up = remove_cv_t>; + static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); + static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t"); + static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t"); + static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type"); + if (*this) + return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value()); + return optional<_Up>(); + } + + template +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { + using _Up = remove_cv_t>; + static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); + static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t"); + static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t"); + static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type"); + if (*this) + return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value()); + return optional<_Up>(); + } + + template +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { + using _Up = remove_cv_t>; + static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array"); + static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t"); + static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t"); + static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type"); + if (*this) + return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); + return optional<_Up>(); + } + + template +# if _LIBCPP_STD_VER >= 26 + requires(is_object_v<_Tp>) +# endif + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { + using _Up = remove_cv_t>; + static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array"); + static_assert(!is_same_v<_Up, in_place_t>, "Result of f(std::move(value())) should not be std::in_place_t"); + static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(std::move(value())) should not be std::nullopt_t"); + static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type"); + if (*this) + return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); + return optional<_Up>(); + } + + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const& + requires is_copy_constructible_v<_Tp> +# if _LIBCPP_STD_VER >= 26 + && (is_object_v<_Tp>) +# endif + { + static_assert(is_same_v>, optional>, + "Result of f() should be the same type as this optional"); + if (*this) + return *this; + return std::forward<_Func>(__f)(); + } + + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) && + requires is_move_constructible_v<_Tp> +# if _LIBCPP_STD_VER >= 26 + && (is_object_v<_Tp>) +# endif + { + static_assert(is_same_v>, optional>, + "Result of f() should be the same type as this optional"); + if (*this) + return std::move(*this); + return std::forward<_Func>(__f)(); + } +# endif // _LIBCPP_STD_VER >= 23 + + using __base::reset; + +// optional overloads +# if _LIBCPP_STD_VER >= 26 + + template > + requires(is_lvalue_reference_v<_Tp> && is_object_v<__libcpp_remove_reference_t<_Tp>> && + !is_array_v<__libcpp_remove_reference_t<_Tp>>) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decay_t<_Tp> value_or(_Up&& __v) const { + static_assert( + is_constructible_v, _Tp&>, "optional::value_or: remove_cv_t must be constructible"); + static_assert( + is_convertible_v<_Up, remove_cvref_t<_Tp>>, "optional::value_or: U must be convertible to remove_cv_t"); + return this->has_value() ? this->__get() : static_cast>(std::forward<_Up>(__v)); + } + + template + requires(is_lvalue_reference_v<_Tp>) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const { + using _Up = invoke_result_t<_Func, _Tp&>; + static_assert(__is_std_optional>::value, + "Result of f(value()) must be a specialization of std::optional"); + if (*this) + return std::invoke(std::forward<_Func>(__f), value()); + return remove_cvref_t<_Up>(); + } + + template + requires(is_lvalue_reference_v<_Tp>) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional>> + transform(_Func&& __f) const { + using _Up = remove_cvref_t>; + static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array"); + static_assert(!is_same_v<_Up, in_place_t>, "Result of f(value()) should not be std::in_place_t"); + static_assert(!is_same_v<_Up, nullopt_t>, "Result of f(value()) should not be std::nullopt_t"); + static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type"); + if (*this) + return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value()); + return optional<_Up>(); + } + + template + requires(is_lvalue_reference_v<_Tp>) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const { + static_assert(is_same_v>, optional>, + "Result of f() should be the same type as this optional"); + if (*this) + return *this; + return std::forward<_Func>(__f)(); + } +# endif +}; + +template +optional(_Tp) -> optional<_Tp>; + +// [optional.relops] Relational operators + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() == std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (static_cast(__x) != static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return *__x == *__y; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() != std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (static_cast(__x) != static_cast(__y)) + return true; + if (!static_cast(__x)) + return false; + return *__x != *__y; +} + +template < class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() < std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (!static_cast(__y)) + return false; + if (!static_cast(__x)) + return true; + return *__x < *__y; +} + +template < class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() > std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (!static_cast(__x)) + return false; + if (!static_cast(__y)) + return true; + return *__x > *__y; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() <= std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (!static_cast(__x)) + return true; + if (!static_cast(__y)) + return false; + return *__x <= *__y; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() >= std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (!static_cast(__y)) + return true; + if (!static_cast(__x)) + return false; + return *__x >= *__y; +} + +# if _LIBCPP_STD_VER >= 20 + +template _Up> +_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up> +operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) { + if (__x && __y) + return *__x <=> *__y; + return __x.has_value() <=> __y.has_value(); +} + +# endif // _LIBCPP_STD_VER >= 20 + +// [optional.nullops] Comparison with nullopt + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept { + return !static_cast(__x); +} + +# if _LIBCPP_STD_VER <= 17 + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(nullopt_t, const optional<_Tp>& __x) noexcept { + return !static_cast(__x); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, nullopt_t) noexcept { + return static_cast(__x); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(nullopt_t, const optional<_Tp>& __x) noexcept { + return static_cast(__x); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>&, nullopt_t) noexcept { + return false; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(nullopt_t, const optional<_Tp>& __x) noexcept { + return static_cast(__x); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, nullopt_t) noexcept { + return !static_cast(__x); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(nullopt_t, const optional<_Tp>&) noexcept { + return true; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, nullopt_t) noexcept { + return static_cast(__x); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(nullopt_t, const optional<_Tp>&) noexcept { + return false; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>&, nullopt_t) noexcept { + return true; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(nullopt_t, const optional<_Tp>& __x) noexcept { + return !static_cast(__x); +} + +# else // _LIBCPP_STD_VER <= 17 + +template +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept { + return __x.has_value() <=> false; +} + +# endif // _LIBCPP_STD_VER <= 17 + +// [optional.comp.with.t] Comparison with T + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() == std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const _Up& __v) { + if (__x.has_value()) + return *__x == __v; + return false; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() == std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __v, const optional<_Up>& __x) { + if (__x.has_value()) + return __v == *__x; + return false; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() != std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const optional<_Tp>& __x, const _Up& __v) { + if (__x.has_value()) + return *__x != __v; + return true; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() != std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __v, const optional<_Up>& __x) { + if (__x.has_value()) + return __v != *__x; + return true; +} + +template < class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() < std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const optional<_Tp>& __x, const _Up& __v) { + if (__x.has_value()) + return *__x < __v; + return true; +} + +template < class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() < std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __v, const optional<_Up>& __x) { + if (__x.has_value()) + return __v < *__x; + return false; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() <= std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const optional<_Tp>& __x, const _Up& __v) { + if (__x.has_value()) + return *__x <= __v; + return true; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() <= std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __v, const optional<_Up>& __x) { + if (__x.has_value()) + return __v <= *__x; + return false; +} + +template < class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() > std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const optional<_Tp>& __x, const _Up& __v) { + if (__x.has_value()) + return *__x > __v; + return false; +} + +template < class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() > std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __v, const optional<_Up>& __x) { + if (__x.has_value()) + return __v > *__x; + return true; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() >= std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const optional<_Tp>& __x, const _Up& __v) { + if (__x.has_value()) + return *__x >= __v; + return false; +} + +template < + class _Tp, + class _Up, + enable_if_t<__is_core_convertible_v() >= std::declval()), bool>, + int> = 0> +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __v, const optional<_Up>& __x) { + if (__x.has_value()) + return __v >= *__x; + return true; +} + +# if _LIBCPP_STD_VER >= 20 + +template + requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up> +_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up> +operator<=>(const optional<_Tp>& __x, const _Up& __v) { + return __x.has_value() ? *__x <=> __v : strong_ordering::less; +} + +# endif // _LIBCPP_STD_VER >= 20 + +template && is_swappable_v<_Tp>, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) { + __x.swap(__y); +} + +struct __make_optional_barrier_tag { + explicit __make_optional_barrier_tag() = default; +}; + +template < +# if _LIBCPP_STD_VER >= 26 + __make_optional_barrier_tag = __make_optional_barrier_tag{}, +# endif + class _Tp, + enable_if_t, _Tp>, int> = 0> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional> make_optional(_Tp&& __v) { + return optional>(std::forward<_Tp>(__v)); +} + +template , int> = 0> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) { + return optional<_Tp>(in_place, std::forward<_Args>(__args)...); +} + +template , int> = 0> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> +make_optional(initializer_list<_Up> __il, _Args&&... __args) { + return optional<_Tp>(in_place, __il, std::forward<_Args>(__args)...); +} + +template +struct hash< __enable_hash_helper, remove_const_t<_Tp>> > { +# if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) + _LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type; + _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type; +# endif + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const { + return static_cast(__opt) ? hash>()(*__opt) : 0; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +# endif // _LIBCPP_STD_VER >= 17 + +_LIBCPP_POP_MACROS + +# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# endif +#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) + +#endif // _LIBCPP_OPTIONAL -- cgit v1.2.3