Fix function_wrapper extra parameter can be by reference.
This commit is contained in:
parent
c5be670806
commit
beced114ae
|
|
@ -23,7 +23,8 @@ struct function_wrapper;
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename... TExtraArguments>
|
template<typename T, typename... TExtraArguments>
|
||||||
requires(std::is_const<T>::value == true) struct function_wrapper<T, TExtraArguments...>
|
requires(std::is_const<T>::value == true)
|
||||||
|
struct function_wrapper<T, TExtraArguments...>
|
||||||
{
|
{
|
||||||
using wrapper_type = std::function<flexible_value(const T&, const IDataSource&, TExtraArguments...)>;
|
using wrapper_type = std::function<flexible_value(const T&, const IDataSource&, TExtraArguments...)>;
|
||||||
|
|
||||||
|
|
@ -40,7 +41,8 @@ requires(std::is_const<T>::value == true) struct function_wrapper<T, TExtraArgum
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename... TExtraArguments>
|
template<typename T, typename... TExtraArguments>
|
||||||
requires(std::is_const<T>::value == false) struct function_wrapper<T, TExtraArguments...>
|
requires(std::is_const<T>::value == false)
|
||||||
|
struct function_wrapper<T, TExtraArguments...>
|
||||||
{
|
{
|
||||||
using wrapper_type = std::function<flexible_value(T&, const IDataSource&, TExtraArguments...)>;
|
using wrapper_type = std::function<flexible_value(T&, const IDataSource&, TExtraArguments...)>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,11 @@ namespace detail
|
||||||
template<typename M, typename T, std::size_t TParameterCount, typename... TExtraArguments>
|
template<typename M, typename T, std::size_t TParameterCount, typename... TExtraArguments>
|
||||||
requires(function_info<M T::*>::is_const_member == false)
|
requires(function_info<M T::*>::is_const_member == false)
|
||||||
|
|
||||||
flexible_value invoke(T& callableObj,
|
flexible_value invoke(T& callableObj,
|
||||||
M T::*callableFn,
|
M T::*callableFn,
|
||||||
std::array<std::string, TParameterCount> names,
|
std::array<std::string, TParameterCount> names,
|
||||||
const IDataSource& source,
|
const IDataSource& source,
|
||||||
TExtraArguments... arguments)
|
TExtraArguments&&... arguments)
|
||||||
{
|
{
|
||||||
using CallableInfo = function_info<decltype(callableFn)>;
|
using CallableInfo = function_info<decltype(callableFn)>;
|
||||||
using SourceArgumentsTuple =
|
using SourceArgumentsTuple =
|
||||||
|
|
@ -74,11 +74,11 @@ requires(function_info<M T::*>::is_const_member == false)
|
||||||
template<typename M, typename T, std::size_t TParameterCount, typename... TExtraArguments>
|
template<typename M, typename T, std::size_t TParameterCount, typename... TExtraArguments>
|
||||||
requires(function_info<M T::*>::is_const_member == true)
|
requires(function_info<M T::*>::is_const_member == true)
|
||||||
|
|
||||||
flexible_value invoke(const T& callableObj,
|
flexible_value invoke(const T& callableObj,
|
||||||
M T::*callableFn,
|
M T::*callableFn,
|
||||||
std::array<std::string, TParameterCount> names,
|
std::array<std::string, TParameterCount> names,
|
||||||
const IDataSource& source,
|
const IDataSource& source,
|
||||||
TExtraArguments... arguments)
|
TExtraArguments&&... arguments)
|
||||||
{
|
{
|
||||||
using CallableInfo = function_info<decltype(callableFn)>;
|
using CallableInfo = function_info<decltype(callableFn)>;
|
||||||
using SourceArgumentsTuple =
|
using SourceArgumentsTuple =
|
||||||
|
|
@ -95,7 +95,7 @@ template<typename TCallable, std::size_t TParameterCount, typename... TExtraArgu
|
||||||
flexible_value invoke(TCallable& fn,
|
flexible_value invoke(TCallable& fn,
|
||||||
std::array<std::string, TParameterCount> names,
|
std::array<std::string, TParameterCount> names,
|
||||||
const IDataSource& source,
|
const IDataSource& source,
|
||||||
TExtraArguments... arguments)
|
TExtraArguments&&... arguments)
|
||||||
{
|
{
|
||||||
return invoke(fn, &TCallable::operator(), names, source, arguments...);
|
return invoke(fn, &TCallable::operator(), names, source, arguments...);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,3 +123,22 @@ TEST(InvokeTest, Ok_Ptr_Member_Const)
|
||||||
flexible_value returnValue = bmrshared::invoke(functor, &TestAddition::AddNumbersConst, names, mockSrc);
|
flexible_value returnValue = bmrshared::invoke(functor, &TestAddition::AddNumbersConst, names, mockSrc);
|
||||||
EXPECT_EQ(returnValue.as<uint64_t>(), 140);
|
EXPECT_EQ(returnValue.as<uint64_t>(), 140);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(InvokeTest, Ok_ExtraArgumentByRefChanged)
|
||||||
|
{
|
||||||
|
auto fn = [](int64_t a, int64_t& lastArg)
|
||||||
|
{
|
||||||
|
lastArg = a;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
std::array<std::string, 1> names = {"a"};
|
||||||
|
|
||||||
|
MockDataSource mockSrc;
|
||||||
|
EXPECT_CALL(mockSrc, GetKeys()).WillRepeatedly(Return(std::vector<std::string>{"a"}));
|
||||||
|
EXPECT_CALL(mockSrc, Get("a", An<int64_t&>())).WillRepeatedly(SetArgReferee<1>(42));
|
||||||
|
|
||||||
|
int64_t lastArg = 0;
|
||||||
|
flexible_value returnValue = bmrshared::invoke(fn, names, mockSrc, lastArg);
|
||||||
|
EXPECT_EQ(returnValue.as<bool>(), true);
|
||||||
|
EXPECT_EQ(lastArg, 42);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,17 @@ class TestAddition
|
||||||
int64_t AddNumbersConst(int64_t left, int64_t right) const { return left + (right * 2); }
|
int64_t AddNumbersConst(int64_t left, int64_t right) const { return left + (right * 2); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TestWriteOutputArgument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool WriteOutArg(int64_t a, int64_t& extraOutArg) const
|
||||||
|
{
|
||||||
|
return extraOutArg = a;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
using TestWrapperType = function_wrapper<TestAddition>;
|
using TestWrapperType = function_wrapper<TestAddition>;
|
||||||
using TestConstWrapperType = function_wrapper<const TestAddition>;
|
using TestConstWrapperType = function_wrapper<const TestAddition>;
|
||||||
|
|
||||||
|
|
@ -77,3 +88,20 @@ TEST(WrapTest, Const_Ptr_to_member_as_non_const)
|
||||||
flexible_value returnValue = wrapped(obj, mockSrc);
|
flexible_value returnValue = wrapped(obj, mockSrc);
|
||||||
EXPECT_EQ(returnValue.as<int64_t>(), 84);
|
EXPECT_EQ(returnValue.as<int64_t>(), 84);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(WrapTest, WriteExtraOutArg)
|
||||||
|
{
|
||||||
|
const TestWriteOutputArgument obj;
|
||||||
|
using TestWrapperOutArgType = function_wrapper<const TestWriteOutputArgument, int64_t&>;
|
||||||
|
TestWrapperOutArgType::wrapper_type wrapped =
|
||||||
|
TestWrapperOutArgType::Wrap(&TestWriteOutputArgument::WriteOutArg, "a");
|
||||||
|
|
||||||
|
MockDataSource mockSrc;
|
||||||
|
EXPECT_CALL(mockSrc, GetKeys()).WillRepeatedly(Return(std::vector<std::string>{"a"}));
|
||||||
|
EXPECT_CALL(mockSrc, Get("a", An<int64_t&>())).WillRepeatedly(SetArgReferee<1>(42));
|
||||||
|
|
||||||
|
int64_t lastArg = 0;
|
||||||
|
flexible_value returnValue = wrapped(obj, mockSrc, lastArg);
|
||||||
|
EXPECT_EQ(returnValue.as<bool>(), true);
|
||||||
|
EXPECT_EQ(lastArg, 42);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue