[libcxx-commits] [libcxx] [libc++] Reimplement optional<T&> as a partial specialization (PR #201983)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jun 5 18:57:52 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: William Tran-Viet (smallp-o-p)
<details>
<summary>Changes</summary>
- Break out the optional<T&> implementation that was interwoven with the regular interface
- This should the implementation
- Also fixes a bug where returning an optional<T&> for the monadic functions was broken
---
Patch is 35.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/201983.diff
6 Files Affected:
- (modified) libcxx/include/optional (+175-180)
- (modified) libcxx/test/std/utilities/optional/optional.monadic/and_then.pass.cpp (+35-2)
- (modified) libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp (+8)
- (modified) libcxx/test/std/utilities/optional/optional.monadic/transform.pass.cpp (+17-4)
- (modified) libcxx/test/std/utilities/optional/optional.syn/optional_in_place_t.verify.cpp (+7-1)
- (modified) libcxx/test/std/utilities/optional/optional.syn/optional_nullopt_t.verify.cpp (+8-3)
``````````diff
diff --git a/libcxx/include/optional b/libcxx/include/optional
index d0ddd2c0b8ea2..a5a98425c88ae 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -558,7 +558,7 @@ struct __optional_storage_base<_Tp, true> {
_LIBCPP_HIDE_FROM_ABI constexpr __optional_storage_base() noexcept : __value_(nullptr) {}
template <class _Up>
- _LIBCPP_HIDE_FROM_ABI constexpr void __convert_init_ref_val(_Up&& __val) noexcept {
+ _LIBCPP_HIDE_FROM_ABI constexpr void __convert_init_ref_val(_Up&& __val) {
_Tp& __r(std::forward<_Up>(__val));
__value_ = std::addressof(__r);
}
@@ -571,6 +571,14 @@ struct __optional_storage_base<_Tp, true> {
__convert_init_ref_val(std::forward<_UArg>(__uarg));
}
+# if _LIBCPP_STD_VER >= 23
+ template <class _Fp, class... _Args>
+ constexpr __optional_storage_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) {
+ _Tp& __r = std::invoke(std::forward<_Fp>(__f), std::forward<_Args>(__args)...);
+ __value_ = std::addressof(__r);
+ }
+# endif
+
_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; }
@@ -579,7 +587,6 @@ struct __optional_storage_base<_Tp, true> {
template <class _UArg>
_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");
@@ -726,8 +733,8 @@ using __optional_sfinae_ctor_base_t _LIBCPP_NODEBUG =
template <class _Tp>
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>>;
+ __sfinae_assign_base< (is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Tp>),
+ (is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp>)>;
template <class _Tp>
class optional;
@@ -769,6 +776,7 @@ inline constexpr bool __is_constructible_for_optional_initializer_list_v =
# if _LIBCPP_STD_VER >= 26
template <class _Tp, class... _Args>
inline constexpr bool __is_constructible_for_optional_v<_Tp&, _Args...> = false;
+
template <class _Tp, class _Arg>
inline constexpr bool __is_constructible_for_optional_v<_Tp&, _Arg> =
is_constructible_v<_Tp&, _Arg> && !reference_constructs_from_temporary_v<_Tp&, _Arg>;
@@ -777,6 +785,14 @@ template <class _Tp, class _Up, class... _Args>
inline constexpr bool __is_constructible_for_optional_initializer_list_v<_Tp&, _Up, _Args...> = false;
# endif
+# if _LIBCPP_STD_VER >= 26
+template <class _Tp>
+inline constexpr bool __is_valid_optional_type = std::is_object_v<_Tp> || std::is_lvalue_reference_v<_Tp>;
+# else
+template <class _Tp>
+inline constexpr bool __is_valid_optional_type = std::is_object_v<_Tp>;
+# endif
+
template <class _Tp, class = void>
struct __optional_iterator_base : __optional_move_assign_base<_Tp> {
using __optional_move_assign_base<_Tp>::__optional_move_assign_base;
@@ -878,9 +894,8 @@ public:
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");
+ static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>, "instantiation of optional with in_place_t is ill-formed");
+ static_assert(!is_same_v<remove_cv_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
@@ -889,16 +904,6 @@ private:
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 <class _Up>
- constexpr static bool __libcpp_opt_ref_ctor_deleted =
- is_lvalue_reference_v<_Tp> && reference_constructs_from_temporary_v<_Tp, _Up>;
-
- template <class _Up>
- constexpr static bool __ref_ctor_enabled =
- is_lvalue_reference_v<_Tp> && !reference_constructs_from_temporary_v<_Tp, _Up>;
-# endif
-
// LWG2756: conditionally explicit conversion from _Up
struct _CheckOptionalArgsConstructor {
template <class _Up>
@@ -984,117 +989,34 @@ public:
: __base(in_place, __il, std::forward<_Args>(__args)...) {}
template <class _Up = _Tp, enable_if_t<_CheckOptionalArgsCtor<_Up>::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)) {
- }
+ _LIBCPP_HIDE_FROM_ABI constexpr optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
template <class _Up = remove_cv_t<_Tp>,
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)) {
- }
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit optional(_Up&& __v) : __base(in_place, std::forward<_Up>(__v)) {}
// LWG2756: conditionally explicit conversion from const optional<_Up>&
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::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&, const _Up&>)
-# endif
- {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>& __v) {
this->__construct_from(__v);
}
+
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::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&, const _Up&>)
-# endif
- {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(const optional<_Up>& __v) {
this->__construct_from(__v);
}
// LWG2756: conditionally explicit conversion from optional<_Up>&&
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::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 <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::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
- {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(optional<_Up>&& __v) {
this->__construct_from(std::move(__v));
}
- // deleted optional<T&> constructors and additional optional<T&> constructors
-# if _LIBCPP_STD_VER >= 26
- // optional(U&&)
- template <class _Up = _Tp, enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>(), int> = 0>
- requires __libcpp_opt_ref_ctor_deleted<_Up>
- optional(_Up&&) = delete;
-
- template <class _Up = remove_cv_t<_Tp>,
- enable_if_t<_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>(), int> = 0>
- requires __libcpp_opt_ref_ctor_deleted<_Up>
- explicit optional(_Up&&) = delete;
-
- // optional(optional<U>& rhs)
- template <class _Up>
- requires __ref_ctor_enabled<_Up&> && (!is_same_v<remove_cvref_t<_Tp>, 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 <class _Up>
- requires __libcpp_opt_ref_ctor_deleted<_Up&> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
- (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, _Up&>
- constexpr explicit optional(optional<_Up>& __rhs) noexcept = delete;
-
- // optional(const optional<U>&)
- template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>(), int> = 0>
- requires __libcpp_opt_ref_ctor_deleted<const _Up&>
- optional(const optional<_Up>&) = delete;
-
- template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>(), int> = 0>
- requires __libcpp_opt_ref_ctor_deleted<const _Up&>
- explicit optional(const optional<_Up>&) = delete;
-
- // optional(optional<U>&&)
- template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_implicit<_Up>(), int> = 0>
- requires __libcpp_opt_ref_ctor_deleted<_Up>
- optional(optional<_Up>&&) = delete;
-
template <class _Up, enable_if_t<_CheckOptionalLikeCtor<_Up, _Up&&>::template __enable_explicit<_Up>(), int> = 0>
- requires __libcpp_opt_ref_ctor_deleted<_Up>
- explicit optional(optional<_Up>&&) = delete;
-
- // optional(const optional<U>&&)
- template <class _Up>
- requires __ref_ctor_enabled<const _Up> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
- (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, const _Up>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit(!is_convertible_v<const _Up, _Tp&>)
- optional(const optional<_Up>&& __v) noexcept(is_nothrow_constructible_v<_Tp&, const _Up>) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit optional(optional<_Up>&& __v) {
this->__construct_from(std::move(__v));
}
- template <class _Up>
- requires __libcpp_opt_ref_ctor_deleted<const _Up> && (!is_same_v<remove_cvref_t<_Tp>, optional<_Up>>) &&
- (!is_same_v<_Tp&, _Up>) && is_constructible_v<_Tp&, const _Up>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional(const optional<_Up>&& __v) noexcept = delete;
-# endif
-
# if _LIBCPP_STD_VER >= 23
template <class _Tag,
class _Fp,
@@ -1117,8 +1039,7 @@ public:
enable_if_t<_And<_IsNotSame<__remove_cvref_t<_Up>, optional>,
_Or<_IsNotSame<__remove_cvref_t<_Up>, _Tp>, _Not<is_scalar<_Tp>>>,
is_constructible<_Tp, _Up>,
- is_assignable<_Tp&, _Up>,
- is_object<_Tp>>::value,
+ is_assignable<_Tp&, _Up>>::value,
int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 optional& operator=(_Up&& __v) {
if (this->has_value())
@@ -1143,11 +1064,7 @@ public:
}
template <class... _Args, enable_if_t<__is_constructible_for_optional_v<_Tp, _Args...>, 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
- {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& emplace(_Args&&... __args) {
reset();
this->__construct(std::forward<_Args>(__args)...);
return this->__get();
@@ -1162,12 +1079,8 @@ public:
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
- ) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
+ swap(optional& __opt) noexcept((is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp>)) {
this->__swap(__opt);
}
@@ -1181,9 +1094,6 @@ public:
using __base::value;
template <class _Up = remove_cv_t<_Tp>>
-# 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<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");
@@ -1191,9 +1101,6 @@ public:
}
template <class _Up = remove_cv_t<_Tp>>
-# 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<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");
@@ -1202,9 +1109,6 @@ public:
# if _LIBCPP_STD_VER >= 23
template <class _Func>
-# 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<remove_cvref_t<_Up>>::value,
@@ -1215,9 +1119,6 @@ public:
}
template <class _Func>
-# 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<remove_cvref_t<_Up>>::value,
@@ -1228,9 +1129,6 @@ public:
}
template <class _Func>
-# 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<remove_cvref_t<_Up>>::value,
@@ -1241,9 +1139,6 @@ public:
}
template <class _Func>
-# 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<remove_cvref_t<_Up>>::value,
@@ -1254,60 +1149,48 @@ public:
}
template <class _Func>
-# 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<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");
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");
+ static_assert(__is_valid_optional_type<_Up>, "Result of f(value()) should be a valid contained type for optional");
if (*this)
return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
return optional<_Up>();
}
template <class _Func>
-# 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<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");
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");
+ static_assert(__is_valid_optional_type<_Up>, "Result of f(value()) should be a valid contained type for optional");
if (*this)
return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), value());
return optional<_Up>();
}
template <class _Func>
-# 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<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");
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");
+ static_assert(__is_valid_optional_type<_Up>, "Result of f(value()) should be a valid contained type for optional");
if (*this)
return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
return optional<_Up>();
}
template <class _Func>
-# 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<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");
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");
+ static_assert(__is_valid_optional_type<_Up>, "Result of f(value()) should be a valid contained type for optional");
if (*this)
return optional<_Up>(__optional_construct_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value()));
return optional<_Up>();
@@ -1316,9 +1199,6 @@ public:
template <invocable _Func>
[[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<remove_cvref_t<invoke_result_t<_Func>>, optional>,
"Result of f() should be the same type as this optional");
@@ -1330,9 +1210,6 @@ public:
template <invocable _Func>
[[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<remove_cvref_t<invoke_result_t<_Func>>, optional>,
"Result of f() should be the same type as this optional");
@@ -1343,24 +1220,136 @@ public:
# endif // _LIBCPP_STD_VER >= 23
using __base::reset;
+};
-// optional<T&> overloads
# if _LIBCPP_STD_VER >= 26
+template <class _Tp>
+class optional<_Tp&> : public __optional_iterator_base<_Tp&> {
+ using __base _LIBCPP_NODEBUG = __optional_iterator_base<_Tp&>;
+
+ template <class _Up, class _QualUp>
+ static constexpr bool __check_optionalU_ctor =
+ !std::is_same_v<std::remove_cv_t<_Tp>, optional<_Up>> && !std::is_same_v<_Tp&, _Up> &&
+ std::is_construc...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/201983
More information about the libcxx-commits
mailing list