mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Added etl::mem_fn
This commit is contained in:
parent
e64b489d5e
commit
1474d4add8
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user