From 63c919598090177f236d9ccccc97daba45f37960 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Thu, 23 Feb 2023 20:26:25 +0700 Subject: [PATCH 1/4] Implement LWG-3655: The `INVOKE` operation and `union` types --- stl/inc/type_traits | 6 ++++-- tests/std/tests/P2136R3_invoke_r/test.cpp | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 103cb1fa5c9..c71b677dd8b 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1554,7 +1554,8 @@ struct _Invoker1; template struct _Invoker1<_Callable, _Ty1, _Removed_cvref, true, false> - : conditional_t::_Class_type, remove_reference_t<_Ty1>>, + : conditional_t::_Class_type, remove_cvref_t<_Ty1>> + || is_base_of_v::_Class_type, remove_cvref_t<_Ty1>>, _Invoker_pmf_object, conditional_t<_Is_specialization_v<_Remove_cvref_t<_Ty1>, reference_wrapper>, _Invoker_pmf_refwrap, _Invoker_pmf_pointer>> {}; // pointer to member function @@ -1562,7 +1563,8 @@ struct _Invoker1<_Callable, _Ty1, _Removed_cvref, true, false> template struct _Invoker1<_Callable, _Ty1, _Removed_cvref, false, true> : conditional_t< - is_base_of_v::_Class_type, remove_reference_t<_Ty1>>, + is_same_v::_Class_type, remove_cvref_t<_Ty1>> + || is_base_of_v::_Class_type, remove_cvref_t<_Ty1>>, _Invoker_pmd_object, conditional_t<_Is_specialization_v<_Remove_cvref_t<_Ty1>, reference_wrapper>, _Invoker_pmd_refwrap, _Invoker_pmd_pointer>> {}; // pointer to member data diff --git a/tests/std/tests/P2136R3_invoke_r/test.cpp b/tests/std/tests/P2136R3_invoke_r/test.cpp index f8d7bac3192..991d979df1a 100644 --- a/tests/std/tests/P2136R3_invoke_r/test.cpp +++ b/tests/std/tests/P2136R3_invoke_r/test.cpp @@ -109,6 +109,13 @@ constexpr bool test_invoke_r() { return true; } +// LWG-3655: The INVOKE operation and union types +union Foo { + int x; +}; +static_assert(is_invocable_v); +static_assert(is_invocable_v); + int main() { test_invoke_r(); STATIC_ASSERT(test_invoke_r()); From 2b2dfc0fd6ec8ab0c5f0368b14f66260a52c5b3a Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Thu, 23 Feb 2023 20:59:47 +0700 Subject: [PATCH 2/4] _Remove_cvref_t --- stl/inc/type_traits | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index c71b677dd8b..463db6fd760 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1554,8 +1554,8 @@ struct _Invoker1; template struct _Invoker1<_Callable, _Ty1, _Removed_cvref, true, false> - : conditional_t::_Class_type, remove_cvref_t<_Ty1>> - || is_base_of_v::_Class_type, remove_cvref_t<_Ty1>>, + : conditional_t::_Class_type, _Remove_cvref_t<_Ty1>> + || is_base_of_v::_Class_type, _Remove_cvref_t<_Ty1>>, _Invoker_pmf_object, conditional_t<_Is_specialization_v<_Remove_cvref_t<_Ty1>, reference_wrapper>, _Invoker_pmf_refwrap, _Invoker_pmf_pointer>> {}; // pointer to member function @@ -1563,8 +1563,8 @@ struct _Invoker1<_Callable, _Ty1, _Removed_cvref, true, false> template struct _Invoker1<_Callable, _Ty1, _Removed_cvref, false, true> : conditional_t< - is_same_v::_Class_type, remove_cvref_t<_Ty1>> - || is_base_of_v::_Class_type, remove_cvref_t<_Ty1>>, + is_same_v::_Class_type, _Remove_cvref_t<_Ty1>> + || is_base_of_v::_Class_type, _Remove_cvref_t<_Ty1>>, _Invoker_pmd_object, conditional_t<_Is_specialization_v<_Remove_cvref_t<_Ty1>, reference_wrapper>, _Invoker_pmd_refwrap, _Invoker_pmd_pointer>> {}; // pointer to member data From 3250c68ff279826861bca99e2070a3ba8e861bed Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 23 Feb 2023 07:59:51 -0800 Subject: [PATCH 3/4] Rename to Union. --- tests/std/tests/P2136R3_invoke_r/test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/P2136R3_invoke_r/test.cpp b/tests/std/tests/P2136R3_invoke_r/test.cpp index 991d979df1a..a6c3f680256 100644 --- a/tests/std/tests/P2136R3_invoke_r/test.cpp +++ b/tests/std/tests/P2136R3_invoke_r/test.cpp @@ -110,11 +110,11 @@ constexpr bool test_invoke_r() { } // LWG-3655: The INVOKE operation and union types -union Foo { +union Union { int x; }; -static_assert(is_invocable_v); -static_assert(is_invocable_v); +static_assert(is_invocable_v); +static_assert(is_invocable_v); int main() { test_invoke_r(); From 2eb2136c33703891773b5263ba7091ee2f4aa524 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 23 Feb 2023 08:01:44 -0800 Subject: [PATCH 4/4] Verify that remove_cvref_t is used. --- tests/std/tests/P2136R3_invoke_r/test.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/std/tests/P2136R3_invoke_r/test.cpp b/tests/std/tests/P2136R3_invoke_r/test.cpp index a6c3f680256..e8beb0e9965 100644 --- a/tests/std/tests/P2136R3_invoke_r/test.cpp +++ b/tests/std/tests/P2136R3_invoke_r/test.cpp @@ -113,8 +113,20 @@ constexpr bool test_invoke_r() { union Union { int x; }; +static_assert(is_invocable_v); static_assert(is_invocable_v); +static_assert(is_invocable_v); +static_assert(is_invocable_v); + +static_assert(is_invocable_v); static_assert(is_invocable_v); +static_assert(!is_invocable_v); +static_assert(!is_invocable_v); + +static_assert(is_invocable_v); +static_assert(is_invocable_v); +static_assert(is_invocable_v); +static_assert(is_invocable_v); int main() { test_invoke_r();