[libcxx-commits] [libcxx] [libc++] Correct `optional<T&>` implementation (PR #174537)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 6 01:29:56 PST 2026
================
@@ -1254,6 +1366,77 @@ public:
# endif // _LIBCPP_STD_VER >= 23
using __base::reset;
+
+// optional<T&> overloads
+# if _LIBCPP_STD_VER >= 26
+
+ _LIBCPP_HIDE_FROM_ABI constexpr add_pointer_t<_Tp> operator->() const noexcept
+ requires(is_lvalue_reference_v<_Tp>)
+ {
+ _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
+ requires(is_lvalue_reference_v<_Tp>)
+ {
+ _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
+ requires(is_lvalue_reference_v<_Tp>)
+ {
+ if (!this->has_value())
+ std::__throw_bad_optional_access();
+ return this->__get();
+ }
+
+ template <class _Up = remove_cvref_t<_Tp>>
+ 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 {
+ using _X = remove_cvref_t<_Tp>;
+ static_assert(is_constructible_v<_X, _Tp&>, "optional<T&>::value_or: remove_cv_t<T> must be constructible");
+ static_assert(is_convertible_v<_Up, _X>, "optional<T&>::value_or: U must be convertible to remove_cv_t<T>");
+ return this->has_value() ? this->__get() : static_cast<_X>(std::forward<_Up>(__v));
----------------
H-G-Hristov wrote:
`using _X = remove_cvref_t<_Tp>;` Why even alias this. I think the code base uses `remove_cvref_t<_Tp>` inplace.
https://github.com/llvm/llvm-project/pull/174537
More information about the libcxx-commits
mailing list