diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 103cb1fa5c9..463db6fd760 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..e8beb0e9965 100644 --- a/tests/std/tests/P2136R3_invoke_r/test.cpp +++ b/tests/std/tests/P2136R3_invoke_r/test.cpp @@ -109,6 +109,25 @@ constexpr bool test_invoke_r() { return true; } +// LWG-3655: The INVOKE operation and union types +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(); STATIC_ASSERT(test_invoke_r());