Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 35 additions & 34 deletions libcxx/include/optional
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public:
_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;
const char* what() const _NOEXCEPT override;
[[__nodiscard__]] const char* what() const _NOEXCEPT override;
Copy link
Contributor

@frederick-vs-ja frederick-vs-ja Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change requested. I very wonder why we decided to expose bad_optional_access to old modes. @EricWF

};

} // namespace std
Expand Down Expand Up @@ -378,7 +378,7 @@ struct __optional_storage_base : __optional_destruct_base<_Tp> {
using value_type = _Tp;
using __base::__base;

_LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__engaged_; }
[[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_; }
Expand Down Expand Up @@ -440,7 +440,7 @@ struct __optional_storage_base<_Tp, true> {

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void reset() noexcept { __value_ = nullptr; }

_LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __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_; }

Expand Down Expand Up @@ -634,7 +634,7 @@ public:
# endif

// [optional.iterators], iterator support
_LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() noexcept {
auto& __derived_self = static_cast<optional<_Tp>&>(*this);
auto __ptr = [&__derived_self]() {
if constexpr (is_lvalue_reference_v<_Tp>) {
Expand All @@ -653,7 +653,7 @@ public:
# endif
}

_LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept {
auto& __derived_self = static_cast<const optional<_Tp>&>(*this);
auto* __ptr = [&__derived_self]() {
if constexpr (is_lvalue_reference_v<_Tp>) {
Expand All @@ -672,10 +672,10 @@ public:
# endif
}

_LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() noexcept {
return begin() + (static_cast<optional<_Tp>&>(*this).has_value() ? 1 : 0);
}
_LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept {
return begin() + (static_cast<const optional<_Tp>&>(*this).has_value() ? 1 : 0);
}
# endif
Expand Down Expand Up @@ -946,22 +946,22 @@ public:
return std::addressof(this->__get());
}

_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept {
[[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();
}

_LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept {
[[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();
}

_LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept {
[[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());
}

_LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept {
[[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());
}
Expand All @@ -971,25 +971,25 @@ public:
using __base::__get;
using __base::has_value;

_LIBCPP_HIDE_FROM_ABI constexpr _Tp const& value() const& {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& value() const& {
if (!this->has_value())
std::__throw_bad_optional_access();
return this->__get();
}

_LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & {
if (!this->has_value())
std::__throw_bad_optional_access();
return this->__get();
}

_LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && {
if (!this->has_value())
std::__throw_bad_optional_access();
return std::move(this->__get());
}

_LIBCPP_HIDE_FROM_ABI constexpr _Tp const&& value() const&& {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp const&& value() const&& {
if (!this->has_value())
std::__throw_bad_optional_access();
return std::move(this->__get());
Expand All @@ -1000,7 +1000,7 @@ public:
requires(!(is_lvalue_reference_v<_Tp> && is_function_v<__libcpp_remove_reference_t<_Tp>>) &&
!(is_lvalue_reference_v<_Tp> && is_array_v<__libcpp_remove_reference_t<_Tp>>))
# endif
_LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& {
static_assert(is_copy_constructible_v<_Tp>, "optional<T>::value_or: T must be copy constructible");
static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T");
return this->has_value() ? this->__get() : static_cast<_Tp>(std::forward<_Up>(__v));
Expand All @@ -1010,7 +1010,7 @@ public:
# if _LIBCPP_STD_VER >= 26
requires(!is_lvalue_reference_v<_Tp>)
# endif
_LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
static_assert(is_move_constructible_v<_Tp>, "optional<T>::value_or: T must be move constructible");
static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T");
return this->has_value() ? std::move(this->__get()) : static_cast<_Tp>(std::forward<_Up>(__v));
Expand All @@ -1020,7 +1020,7 @@ public:
template <class _Up = remove_cv_t<_Tp>>
requires(is_lvalue_reference_v<_Tp> &&
!(is_function_v<__libcpp_remove_reference_t<_Tp>> || is_array_v<__libcpp_remove_reference_t<_Tp>>))
_LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && {
static_assert(is_move_constructible_v<_Tp>, "optional<T>::value_or: T must be move constructible");
static_assert(is_convertible_v<_Up, _Tp>, "optional<T>::value_or: U must be convertible to T");
return this->has_value() ? this->__get() : static_cast<_Tp>(std::forward<_Up>(__v));
Expand All @@ -1029,7 +1029,7 @@ public:

# if _LIBCPP_STD_VER >= 23
template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
using _Up = invoke_result_t<_Func, _Tp&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
"Result of f(value()) must be a specialization of std::optional");
Expand All @@ -1039,7 +1039,7 @@ public:
}

template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
[[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<remove_cvref_t<_Up>>::value,
"Result of f(value()) must be a specialization of std::optional");
Expand All @@ -1049,7 +1049,7 @@ public:
}

template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
using _Up = invoke_result_t<_Func, _Tp&&>;
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
"Result of f(std::move(value())) must be a specialization of std::optional");
Expand All @@ -1059,7 +1059,7 @@ public:
}

template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
[[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<remove_cvref_t<_Up>>::value,
"Result of f(std::move(value())) must be a specialization of std::optional");
Expand All @@ -1069,7 +1069,7 @@ public:
}

template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & {
using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>;
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");
Expand All @@ -1081,7 +1081,7 @@ public:
}

template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& {
using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>;
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");
Expand All @@ -1093,7 +1093,7 @@ public:
}

template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && {
using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>;
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");
Expand All @@ -1105,7 +1105,7 @@ public:
}

template <class _Func>
_LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& {
using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
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");
Expand All @@ -1117,7 +1117,7 @@ public:
}

template <invocable _Func>
_LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) const&
requires is_copy_constructible_v<_Tp>
{
static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
Expand All @@ -1128,7 +1128,7 @@ public:
}

template <invocable _Func>
_LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional or_else(_Func&& __f) &&
requires is_move_constructible_v<_Tp>
{
static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
Expand Down Expand Up @@ -1426,8 +1426,8 @@ operator<=>(const optional<_Tp>& __x, const _Up& __v) {
# endif // _LIBCPP_STD_VER >= 20

template <class _Tp, enable_if_t< is_move_constructible_v<_Tp> && 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))) {
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);
}

Expand All @@ -1440,17 +1440,18 @@ template <
__make_optional_barrier_tag = __make_optional_barrier_tag{},
# endif
class _Tp>
_LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional<decay_t<_Tp>> make_optional(_Tp&& __v) {
return optional<decay_t<_Tp>>(std::forward<_Tp>(__v));
}

template <class _Tp, class... _Args>
_LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(_Args&&... __args) {
return optional<_Tp>(in_place, std::forward<_Args>(__args)...);
}

template <class _Tp, class _Up, class... _Args>
_LIBCPP_HIDE_FROM_ABI constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) {
[[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)...);
}

Expand All @@ -1461,7 +1462,7 @@ struct hash< __enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>> > {
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
# endif

_LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t operator()(const optional<_Tp>& __opt) const {
return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
}
};
Expand Down
Loading
Loading