From 882d92ec47580a4ee88543f567b50e9382934059 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 4 Mar 2023 07:20:14 +0800 Subject: [PATCH] Implement LWG-3877 Incorrect constraints on `const`-qualified monadic overloads for `std::expected` (#3504) Co-authored-by: Stephan T. Lavavej --- stl/inc/expected | 24 +-- .../test.cpp | 146 ++++++++++++++++++ 2 files changed, 158 insertions(+), 12 deletions(-) diff --git a/stl/inc/expected b/stl/inc/expected index 9d4a583cf..573d1e7d6 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -732,7 +732,7 @@ public: // [expected.object.monadic] template - requires is_copy_constructible_v<_Err> + requires is_constructible_v<_Err, _Err&> constexpr auto and_then(_Fn&& _Func) & { using _Uty = remove_cvref_t>; @@ -789,7 +789,7 @@ public: } template - requires is_move_constructible_v<_Err> + requires is_constructible_v<_Err, const _Err> constexpr auto and_then(_Fn&& _Func) const&& { using _Uty = remove_cvref_t>; @@ -808,7 +808,7 @@ public: } template - requires is_copy_constructible_v<_Ty> + requires is_constructible_v<_Ty, _Ty&> constexpr auto or_else(_Fn&& _Func) & { using _Uty = remove_cvref_t>; @@ -865,7 +865,7 @@ public: } template - requires is_move_constructible_v<_Ty> + requires is_constructible_v<_Ty, const _Ty> constexpr auto or_else(_Fn&& _Func) const&& { using _Uty = remove_cvref_t>; @@ -884,7 +884,7 @@ public: } template - requires is_copy_constructible_v<_Err> + requires is_constructible_v<_Err, _Err&> constexpr auto transform(_Fn&& _Func) & { static_assert(invocable<_Fn, _Ty&>, "expected::transform(F) requires that F is invocable with T. " "(N4928 [expected.object.monadic]/19)"); @@ -965,7 +965,7 @@ public: } template - requires is_move_constructible_v<_Err> + requires is_constructible_v<_Err, const _Err> constexpr auto transform(_Fn&& _Func) const&& { static_assert(invocable<_Fn, const _Ty>, "expected::transform(F) requires that F is invocable with T. " "(N4928 [expected.object.monadic]/23)"); @@ -992,7 +992,7 @@ public: } template - requires is_copy_constructible_v<_Ty> + requires is_constructible_v<_Ty, _Ty&> constexpr auto transform_error(_Fn&& _Func) & { static_assert(invocable<_Fn, _Err&>, "expected::transform_error(F) requires that F is invocable with E. " "(N4928 [expected.object.monadic]/27)"); @@ -1053,7 +1053,7 @@ public: } template - requires is_move_constructible_v<_Ty> + requires is_constructible_v<_Ty, const _Ty> constexpr auto transform_error(_Fn&& _Func) const&& { static_assert(invocable<_Fn, const _Err>, "expected::transform_error(F) requires that F is invocable with E. " @@ -1470,7 +1470,7 @@ public: // [expected.void.monadic] template - requires is_copy_constructible_v<_Err> + requires is_constructible_v<_Err, _Err&> constexpr auto and_then(_Fn&& _Func) & { using _Uty = remove_cvref_t>; @@ -1527,7 +1527,7 @@ public: } template - requires is_move_constructible_v<_Err> + requires is_constructible_v<_Err, const _Err> constexpr auto and_then(_Fn&& _Func) const&& { using _Uty = remove_cvref_t>; @@ -1618,7 +1618,7 @@ public: } template - requires is_copy_constructible_v<_Err> + requires is_constructible_v<_Err, _Err&> constexpr auto transform(_Fn&& _Func) & { static_assert(invocable<_Fn>, "expected::transform(F) requires that F is invocable with no arguments. " "(N4928 [expected.void.monadic]/17)"); @@ -1696,7 +1696,7 @@ public: } template - requires is_move_constructible_v<_Err> + requires is_constructible_v<_Err, const _Err> constexpr auto transform(_Fn&& _Func) const&& { static_assert(invocable<_Fn>, "expected::transform(F) requires that F is invocable with no arguments. " "(N4928 [expected.void.monadic]/21)"); diff --git a/tests/std/tests/P2505R5_monadic_functions_for_std_expected/test.cpp b/tests/std/tests/P2505R5_monadic_functions_for_std_expected/test.cpp index 9ce4e74d8..39b6ffcc4 100644 --- a/tests/std/tests/P2505R5_monadic_functions_for_std_expected/test.cpp +++ b/tests/std/tests/P2505R5_monadic_functions_for_std_expected/test.cpp @@ -375,7 +375,153 @@ constexpr bool test() { return true; } +template class Tmpl> +constexpr bool is_specialization_of = false; + +template