Merge pull request 'feature/bugfix-argbyref' (#3) from feature/bugfix-argbyref into master

Reviewed-on: https://git.4beumer.nl/bart/network-experiment/pulls/3
This commit is contained in:
Bart Beumer 2023-10-03 18:55:08 +00:00
commit 14dec24c54
6 changed files with 64 additions and 13 deletions

View File

@ -28,6 +28,7 @@ class flexible_value final
std::vector<int64_t>, std::vector<int64_t>,
std::vector<uint64_t>, std::vector<uint64_t>,
std::vector<std::string>, std::vector<std::string>,
std::vector<flexible_value>,
keyvalue_type>; keyvalue_type>;
flexible_value(); flexible_value();

View File

@ -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...)>;

View File

@ -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...);
} }

View File

@ -6,6 +6,7 @@
// the Free Software Foundation. // the Free Software Foundation.
// //
#include "bmrshared/to_tuple.hpp" #include "bmrshared/to_tuple.hpp"
#include <algorithm>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@ -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);
}

View File

@ -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);
}