From 51d823becf6d89d1a70b471d31628df21ecdb859 Mon Sep 17 00:00:00 2001 From: Slava Andrejev Date: Sun, 19 Dec 2021 22:25:46 -0800 Subject: [PATCH 1/2] Add missing perfect forwarding in bound_mem_functor::operator() This is a missed addition to the commit that allowed rvalue references in slot parameters. --- sigc++/functors/mem_fun.h | 4 +++- tests/test_rvalue_ref.cc | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/sigc++/functors/mem_fun.h b/sigc++/functors/mem_fun.h index 65563a30..e3327fb2 100644 --- a/sigc++/functors/mem_fun.h +++ b/sigc++/functors/mem_fun.h @@ -149,7 +149,9 @@ class bound_mem_functor : mem_functor */ decltype(auto) operator()(type_trait_take_t... a) const { - return std::invoke(this->func_ptr_, obj_.invoke(), a...); + return std::invoke( + this->func_ptr_, obj_.invoke(), + std::forward>(a)...); } // protected: diff --git a/tests/test_rvalue_ref.cc b/tests/test_rvalue_ref.cc index 54b04f34..ec81d39e 100644 --- a/tests/test_rvalue_ref.cc +++ b/tests/test_rvalue_ref.cc @@ -16,6 +16,12 @@ struct foo void operator()(MoveableStruct&& /* x */) { result_stream << "foo(MoveableStruct&&)"; } }; +struct A +{ + void foo(MoveableStruct &&) { result_stream << "A::foo(MoveableStruct&&)"; } +}; + + } // end anonymous namespace void @@ -40,6 +46,17 @@ test_slot() util->check_result(result_stream, "foo(MoveableStruct&&)"); } +void +test_mem_fun() +{ + sigc::slot slot; + A a; + slot = sigc::mem_fun(a, &A::foo); + MoveableStruct x; + slot(std::move(x)); + util->check_result(result_stream, "A::foo(MoveableStruct&&)"); +} + int main(int argc, char* argv[]) { @@ -49,6 +66,7 @@ main(int argc, char* argv[]) test_signal(); test_slot(); + test_mem_fun(); return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE; } // end main() From 928d29e759f851d3aa12d25471ce98ea6aa7fb2d Mon Sep 17 00:00:00 2001 From: Slava Andrejev Date: Wed, 22 Dec 2021 21:19:45 -0800 Subject: [PATCH 2/2] Add missing perfect forwarding in mem_functor and pointer_functor This is a missed addition to the commit that allowed rvalue references in slot parameters. --- sigc++/functors/mem_fun.h | 2 +- sigc++/functors/ptr_fun.h | 4 +++- tests/test_rvalue_ref.cc | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/sigc++/functors/mem_fun.h b/sigc++/functors/mem_fun.h index e3327fb2..1b74c3d4 100644 --- a/sigc++/functors/mem_fun.h +++ b/sigc++/functors/mem_fun.h @@ -113,7 +113,7 @@ class mem_functor */ decltype(auto) operator()(obj_type_with_modifier& obj, type_trait_take_t... a) const { - return std::invoke(func_ptr_, obj, a...); + return std::invoke(func_ptr_, obj, std::forward>(a)...); } protected: diff --git a/sigc++/functors/ptr_fun.h b/sigc++/functors/ptr_fun.h index 288ac871..c1dc8b75 100644 --- a/sigc++/functors/ptr_fun.h +++ b/sigc++/functors/ptr_fun.h @@ -92,7 +92,9 @@ class pointer_functor * @param a Arguments to be passed on to the function. * @return The return value of the function invocation. */ - T_return operator()(type_trait_take_t... a) const { return std::invoke(func_ptr_, a...); } + T_return operator()(type_trait_take_t... a) const { + return std::invoke(func_ptr_, std::forward>(a)...); + } }; /** Creates a functor of type sigc::pointer_functor which wraps an existing non-member function. diff --git a/tests/test_rvalue_ref.cc b/tests/test_rvalue_ref.cc index ec81d39e..4e1666b4 100644 --- a/tests/test_rvalue_ref.cc +++ b/tests/test_rvalue_ref.cc @@ -21,6 +21,9 @@ struct A void foo(MoveableStruct &&) { result_stream << "A::foo(MoveableStruct&&)"; } }; +void boo(MoveableStruct &&) { + result_stream << "boo(MoveableStruct&&)"; +} } // end anonymous namespace @@ -48,6 +51,17 @@ test_slot() void test_mem_fun() +{ + sigc::slot slot; + A a; + slot = sigc::mem_fun(&A::foo); + MoveableStruct x; + slot(a, std::move(x)); + util->check_result(result_stream, "A::foo(MoveableStruct&&)"); +} + +void +test_bound_mem_fun() { sigc::slot slot; A a; @@ -57,6 +71,16 @@ test_mem_fun() util->check_result(result_stream, "A::foo(MoveableStruct&&)"); } +void +test_ptr_fun() +{ + sigc::slot slot; + slot = sigc::ptr_fun(&boo); + MoveableStruct x; + slot(std::move(x)); + util->check_result(result_stream, "boo(MoveableStruct&&)"); +} + int main(int argc, char* argv[]) { @@ -66,7 +90,9 @@ main(int argc, char* argv[]) test_signal(); test_slot(); + test_bound_mem_fun(); test_mem_fun(); + test_ptr_fun(); return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE; } // end main()