mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Add moveable parameter support to delegate (#356)
* Add moveable parameter support * Change std::forward to etl::forward
This commit is contained in:
parent
c75e7afe68
commit
c9b170a05a
@ -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)...);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user