Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions stl/inc/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -1554,15 +1554,17 @@ struct _Invoker1;

template <class _Callable, class _Ty1, class _Removed_cvref>
struct _Invoker1<_Callable, _Ty1, _Removed_cvref, true, false>
: conditional_t<is_base_of_v<typename _Is_memfunptr<_Removed_cvref>::_Class_type, remove_reference_t<_Ty1>>,
: conditional_t<is_same_v<typename _Is_memfunptr<_Removed_cvref>::_Class_type, _Remove_cvref_t<_Ty1>>
|| is_base_of_v<typename _Is_memfunptr<_Removed_cvref>::_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

template <class _Callable, class _Ty1, class _Removed_cvref>
struct _Invoker1<_Callable, _Ty1, _Removed_cvref, false, true>
: conditional_t<
is_base_of_v<typename _Is_member_object_pointer<_Removed_cvref>::_Class_type, remove_reference_t<_Ty1>>,
is_same_v<typename _Is_member_object_pointer<_Removed_cvref>::_Class_type, _Remove_cvref_t<_Ty1>>
|| is_base_of_v<typename _Is_member_object_pointer<_Removed_cvref>::_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
Expand Down
19 changes: 19 additions & 0 deletions tests/std/tests/P2136R3_invoke_r/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,25 @@ constexpr bool test_invoke_r() {
return true;
}

// LWG-3655: The INVOKE operation and union types

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change requested: this LWG issue resolution is being implemented unconditionally (as usual), but the test being extended here is C++23:

RUNALL_INCLUDE ..\usual_latest_matrix.lst

This means that the product code is active for C++14/17/20, but is not being tested in those modes. We have tests that are built down to C++14 mode (e.g. Dev11_0535636_functional_overhaul is where INVOKE is mostly tested).

However, I don't think this coverage needs to be moved - even with my paranoia about compiler bugs, I find it hard to imagine a compiler bug that would affect this code that would appear only in C++14/17/20 mode. Also, it's slightly annoying to test anything here in C++14 mode as all that's available there is the older/deprecated result_of. So I'm simply noting this for future consideration.

union Union {
int x;
};
static_assert(is_invocable_v<int Union::*, Union>);
static_assert(is_invocable_v<int Union::*, Union&>);
static_assert(is_invocable_v<int Union::*, const Union>);
static_assert(is_invocable_v<int Union::*, const Union&>);

static_assert(is_invocable_v<void (Union::*)(), Union>);
static_assert(is_invocable_v<void (Union::*)(), Union&>);
static_assert(!is_invocable_v<void (Union::*)(), const Union>);
static_assert(!is_invocable_v<void (Union::*)(), const Union&>);

static_assert(is_invocable_v<void (Union::*)() const, Union>);
static_assert(is_invocable_v<void (Union::*)() const, Union&>);
static_assert(is_invocable_v<void (Union::*)() const, const Union>);
static_assert(is_invocable_v<void (Union::*)() const, const Union&>);

int main() {
test_invoke_r();
STATIC_ASSERT(test_invoke_r());
Expand Down