From c9b170a05ac050cee140df67340ea158b9723d78 Mon Sep 17 00:00:00 2001 From: Chiraffollo Date: Wed, 24 Mar 2021 09:57:28 +0100 Subject: [PATCH] Add moveable parameter support to delegate (#356) * Add moveable parameter support * Change std::forward to etl::forward --- include/etl/delegate.h | 17 ++++---- test/test_delegate.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 8 deletions(-) diff --git a/include/etl/delegate.h b/include/etl/delegate.h index f9ee7714..7fa1eaf7 100644 --- a/include/etl/delegate.h +++ b/include/etl/delegate.h @@ -52,6 +52,7 @@ Original publication: https://www.codeproject.com/Articles/1170503/The-Impossibl #include "error_handler.h" #include "exception.h" #include "type_traits.h" +#include "utility.h" #if ETL_CPP11_NOT_SUPPORTED #if !defined(ETL_IN_UNIT_TEST) @@ -198,7 +199,7 @@ namespace etl { ETL_ASSERT(is_valid(), ETL_ERROR(delegate_uninitialised)); - return (*invocation.stub)(invocation.object, args...); + return (*invocation.stub)(invocation.object, etl::forward(args)...); } //************************************************************************* @@ -315,7 +316,7 @@ namespace etl static TReturn method_stub(void* object, TParams... params) { T* p = static_cast(object); - return (p->*Method)(params...); + return (p->*Method)(etl::forward(params)...); } //************************************************************************* @@ -325,7 +326,7 @@ namespace etl static TReturn const_method_stub(void* object, TParams... params) { T* const p = static_cast(object); - return (p->*Method)(params...); + return (p->*Method)(etl::forward(params)...); } //************************************************************************* @@ -334,7 +335,7 @@ namespace etl template static TReturn method_instance_stub(void*, TParams... params) { - return (Instance.*Method)(params...); + return (Instance.*Method)(etl::forward(params)...); } //************************************************************************* @@ -343,7 +344,7 @@ namespace etl template static TReturn const_method_instance_stub(void*, TParams... params) { - return (Instance.*Method)(params...); + return (Instance.*Method)(etl::forward(params)...); } #if !defined(ETL_COMPILER_GCC) @@ -353,7 +354,7 @@ namespace etl template static TReturn operator_instance_stub(void*, TParams... params) { - return Instance.operator()(params...); + return Instance.operator()(etl::forward(params)...); } #endif @@ -363,7 +364,7 @@ namespace etl template static TReturn function_stub(void*, TParams... params) { - return (Method)(params...); + return (Method)(etl::forward(params)...); } //************************************************************************* @@ -373,7 +374,7 @@ namespace etl static TReturn lambda_stub(void* object, TParams... arg) { TLambda* p = static_cast(object); - return (p->operator())(arg...); + return (p->operator())(etl::forward(arg)...); } //************************************************************************* diff --git a/test/test_delegate.cpp b/test/test_delegate.cpp index 917da8d0..cd8f4cd9 100644 --- a/test/test_delegate.cpp +++ b/test/test_delegate.cpp @@ -46,6 +46,20 @@ namespace int d; }; + //***************************************************************************** + // Test moveable only data structure. + //***************************************************************************** + struct MoveableOnlyData + { + MoveableOnlyData() = default; + ~MoveableOnlyData() = default; + MoveableOnlyData(const MoveableOnlyData&) = delete; + MoveableOnlyData& operator=(const MoveableOnlyData&) = delete; + MoveableOnlyData(MoveableOnlyData&&) = default; + MoveableOnlyData& operator=(MoveableOnlyData&&) = default; + int d; + }; + //***************************************************************************** // The free function taking no parameters. //***************************************************************************** @@ -72,6 +86,15 @@ namespace parameter_correct = (data.d == VALUE1) && (j == VALUE2); } + //***************************************************************************** + // The free function taking a moveable only parameter. + //***************************************************************************** + void free_moveableonly(MoveableOnlyData&& data) + { + function_called = true; + parameter_correct = (data.d == VALUE1); + } + //***************************************************************************** // The test class with member functions. //***************************************************************************** @@ -119,6 +142,14 @@ namespace parameter_correct = (data.d == VALUE1) && (j = VALUE2); } + //******************************************* + // moveable only data + void member_moveableonly(MoveableOnlyData&& data) + { + function_called = true; + parameter_correct = (data.d == VALUE1); + } + //******************************************* // static static void member_static(const Data& data, int j) @@ -265,6 +296,34 @@ namespace CHECK(parameter_correct); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_free_moveableonly) + { + auto d = etl::delegate::create(); + + MoveableOnlyData data; + data.d = VALUE1; + + d(std::move(data)); + + CHECK(function_called); + CHECK(parameter_correct); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_free_moveableonly_constexpr) + { + constexpr auto d = etl::delegate::create(); + + MoveableOnlyData data; + data.d = VALUE1; + + d(std::move(data)); + + CHECK(function_called); + CHECK(parameter_correct); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_lambda_int) { @@ -553,6 +612,36 @@ namespace CHECK(parameter_correct); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_member_moveableonly) + { + Test test; + auto d = etl::delegate::create(test); + + MoveableOnlyData data; + data.d = VALUE1; + + d(std::move(data)); + + CHECK(function_called); + CHECK(parameter_correct); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_member_moveableonly_constexpr) + { + static Test test; + constexpr auto d = etl::delegate::create(test); + + MoveableOnlyData data; + data.d = VALUE1; + + d(std::move(data)); + + CHECK(function_called); + CHECK(parameter_correct); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_member_static) {