Added etl::mem_fn

This commit is contained in:
John Wellbelove 2024-03-21 10:07:31 +00:00
parent e64b489d5e
commit 1474d4add8
2 changed files with 168 additions and 0 deletions

View File

@ -528,6 +528,73 @@ namespace etl
return ~lhs;
}
};
#if ETL_USING_CPP11
namespace private_functional
{
//***************************************************************************
template<typename TReturnType, typename TClassType, typename... TArgs>
class mem_fn_impl
{
public:
typedef TReturnType(TClassType::* MemberFunctionType)(TArgs...);
ETL_CONSTEXPR mem_fn_impl(MemberFunctionType member_function)
: member_function(member_function)
{
}
ETL_CONSTEXPR TReturnType operator()(TClassType& instance, TArgs... args) const
{
return (instance.*member_function)(std::forward<TArgs>(args)...);
}
private:
MemberFunctionType member_function;
};
//***************************************************************************
template<typename TReturnType, typename TClassType, typename... TArgs>
class const_mem_fn_impl
{
public:
typedef TReturnType(TClassType::* MemberFunctionType)(TArgs...) const;
ETL_CONSTEXPR const_mem_fn_impl(MemberFunctionType member_function)
: member_function(member_function)
{
}
ETL_CONSTEXPR TReturnType operator()(const TClassType& instance, TArgs... args) const
{
return (instance.*member_function)(std::forward<TArgs>(args)...);
}
private:
MemberFunctionType member_function;
};
}
//***************************************************************************
template<typename TReturnType, typename TClassType, typename... TArgs>
ETL_CONSTEXPR
private_functional::mem_fn_impl<TReturnType, TClassType, TArgs...> mem_fn(TReturnType(TClassType::* member_function)(TArgs...))
{
return private_functional::mem_fn_impl<TReturnType, TClassType, TArgs...>(member_function);
}
//***************************************************************************
template<typename TReturnType, typename TClassType, typename... TArgs>
ETL_CONSTEXPR
private_functional::const_mem_fn_impl<TReturnType, TClassType, TArgs...> mem_fn(TReturnType(TClassType::* member_function)(TArgs...) const)
{
return private_functional::const_mem_fn_impl<TReturnType, TClassType, TArgs...>(member_function);
}
#endif
}
#endif

View File

@ -50,6 +50,41 @@ namespace
}
};
struct MemFnTest
{
std::string Function1()
{
return std::string("Function1");
}
std::string Function2(const std::string& arg1)
{
return std::string("Function2: ") + arg1;
}
std::string Function3(const std::string& arg1, const std::string& arg2)
{
return std::string("Function3: ") + arg1 + arg2;
}
std::string Function1_Const() const
{
return std::string("Function1_Const");
}
std::string Function2_Const(const std::string& arg1) const
{
return std::string("Function2_Const: ") + arg1;
}
std::string Function3_Const(const std::string& arg1, const std::string& arg2) const
{
return std::string("Function3_Const: ") + arg1 + arg2;
}
mutable std::string result;
};
SUITE(test_functional)
{
//*************************************************************************
@ -278,5 +313,71 @@ namespace
CHECK_EQUAL(uint8_t(~0xAAU), f(0xAAU));
CHECK_EQUAL(uint8_t(~0xFFU), f(0xFFU));
}
//*************************************************************************
TEST(test_mem_fn)
{
MemFnTest mft;
std::string result;
auto f1 = etl::mem_fn(&MemFnTest::Function1);
result.clear();
result = f1(mft);
CHECK_EQUAL("Function1", result);
auto f2 = etl::mem_fn(&MemFnTest::Function2);
result.clear();
result = f2(mft, "Arg1");
CHECK_EQUAL("Function2: Arg1", result);
auto f3 = etl::mem_fn(&MemFnTest::Function3);
result.clear();
result = f3(mft, "Arg1", " : Arg2");
CHECK_EQUAL("Function3: Arg1 : Arg2", result);
}
//*************************************************************************
TEST(test_const_mem_fn)
{
const MemFnTest mft;
std::string result;
auto f1 = etl::mem_fn(&MemFnTest::Function1_Const);
result.clear();
result = f1(mft);
CHECK_EQUAL("Function1_Const", result);
auto f2 = etl::mem_fn(&MemFnTest::Function2_Const);
result.clear();
result = f2(mft, "Arg1");
CHECK_EQUAL("Function2_Const: Arg1", result);
auto f3 = etl::mem_fn(&MemFnTest::Function3_Const);
result.clear();
result = f3(mft, "Arg1", " : Arg2");
CHECK_EQUAL("Function3_Const: Arg1 : Arg2", result);
}
//*************************************************************************
TEST(test_constexpr_mem_fn)
{
const MemFnTest mft;
std::string result;
constexpr auto f1 = etl::mem_fn(&MemFnTest::Function1_Const);
result.clear();
result = f1(mft);
CHECK_EQUAL("Function1_Const", result);
constexpr auto f2 = etl::mem_fn(&MemFnTest::Function2_Const);
result.clear();
result = f2(mft, "Arg1");
CHECK_EQUAL("Function2_Const: Arg1", result);
constexpr auto f3 = etl::mem_fn(&MemFnTest::Function3_Const);
result.clear();
result = f3(mft, "Arg1", " : Arg2");
CHECK_EQUAL("Function3_Const: Arg1 : Arg2", result);
}
};
}