Add moveable parameter support to delegate (#356)

* Add moveable parameter support

* Change std::forward to etl::forward
This commit is contained in:
Chiraffollo 2021-03-24 09:57:28 +01:00 committed by GitHub
parent c75e7afe68
commit c9b170a05a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 98 additions and 8 deletions

View File

@ -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<TParams>(args)...);
}
//*************************************************************************
@ -315,7 +316,7 @@ namespace etl
static TReturn method_stub(void* object, TParams... params)
{
T* p = static_cast<T*>(object);
return (p->*Method)(params...);
return (p->*Method)(etl::forward<TParams>(params)...);
}
//*************************************************************************
@ -325,7 +326,7 @@ namespace etl
static TReturn const_method_stub(void* object, TParams... params)
{
T* const p = static_cast<T*>(object);
return (p->*Method)(params...);
return (p->*Method)(etl::forward<TParams>(params)...);
}
//*************************************************************************
@ -334,7 +335,7 @@ namespace etl
template <typename T, T& Instance, TReturn(T::*Method)(TParams...)>
static TReturn method_instance_stub(void*, TParams... params)
{
return (Instance.*Method)(params...);
return (Instance.*Method)(etl::forward<TParams>(params)...);
}
//*************************************************************************
@ -343,7 +344,7 @@ namespace etl
template <typename T, const T& Instance, TReturn(T::*Method)(TParams...) const>
static TReturn const_method_instance_stub(void*, TParams... params)
{
return (Instance.*Method)(params...);
return (Instance.*Method)(etl::forward<TParams>(params)...);
}
#if !defined(ETL_COMPILER_GCC)
@ -353,7 +354,7 @@ namespace etl
template <typename T, T& Instance>
static TReturn operator_instance_stub(void*, TParams... params)
{
return Instance.operator()(params...);
return Instance.operator()(etl::forward<TParams>(params)...);
}
#endif
@ -363,7 +364,7 @@ namespace etl
template <TReturn(*Method)(TParams...)>
static TReturn function_stub(void*, TParams... params)
{
return (Method)(params...);
return (Method)(etl::forward<TParams>(params)...);
}
//*************************************************************************
@ -373,7 +374,7 @@ namespace etl
static TReturn lambda_stub(void* object, TParams... arg)
{
TLambda* p = static_cast<TLambda*>(object);
return (p->operator())(arg...);
return (p->operator())(etl::forward<TParams>(arg)...);
}
//*************************************************************************

View File

@ -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<void(MoveableOnlyData&&)>::create<free_moveableonly>();
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<void(MoveableOnlyData&&)>::create<free_moveableonly>();
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<void(MoveableOnlyData&&)>::create<Test, &Test::member_moveableonly>(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<void(MoveableOnlyData&&)>::create<Test, &Test::member_moveableonly>(test);
MoveableOnlyData data;
data.d = VALUE1;
d(std::move(data));
CHECK(function_called);
CHECK(parameter_correct);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_static)
{