Added support for free functions and std::bind
This commit is contained in:
parent
534ae69ed5
commit
1577ab2992
2 changed files with 113 additions and 4 deletions
|
@ -78,7 +78,7 @@ template<typename ReturnTypeT, typename ... Args>
|
||||||
struct function_traits<ReturnTypeT (*)(Args ...)>: function_traits<ReturnTypeT(Args ...)>
|
struct function_traits<ReturnTypeT (*)(Args ...)>: function_traits<ReturnTypeT(Args ...)>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
// std::bind
|
// std::bind for object methods
|
||||||
template<typename ClassT, typename ReturnTypeT, typename ... Args, typename ... FArgs>
|
template<typename ClassT, typename ReturnTypeT, typename ... Args, typename ... FArgs>
|
||||||
#if defined _LIBCPP_VERSION // libc++ (Clang)
|
#if defined _LIBCPP_VERSION // libc++ (Clang)
|
||||||
struct function_traits<std::__1::__bind<ReturnTypeT (ClassT::*)(Args ...), FArgs ...>>
|
struct function_traits<std::__1::__bind<ReturnTypeT (ClassT::*)(Args ...), FArgs ...>>
|
||||||
|
@ -88,6 +88,22 @@ struct function_traits<std::_Bind<std::_Mem_fn<ReturnTypeT (ClassT::*)(Args ...)
|
||||||
struct function_traits<
|
struct function_traits<
|
||||||
std::_Binder<std::_Unforced, ReturnTypeT(__cdecl ClassT::*)(Args ...), FArgs ...>
|
std::_Binder<std::_Unforced, ReturnTypeT(__cdecl ClassT::*)(Args ...), FArgs ...>
|
||||||
>
|
>
|
||||||
|
#else
|
||||||
|
#error "Unsupported C++ compiler / standard library"
|
||||||
|
#endif
|
||||||
|
: function_traits<ReturnTypeT(Args ...)>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// std::bind for free functions
|
||||||
|
template<typename ReturnTypeT, typename ... Args, typename ... FArgs>
|
||||||
|
#if defined _LIBCPP_VERSION // libc++ (Clang)
|
||||||
|
struct function_traits<std::__1::__bind<ReturnTypeT( &)(Args ...), FArgs ...>>
|
||||||
|
#elif defined __GLIBCXX__ // glibc++ (GNU C++)
|
||||||
|
struct function_traits<std::_Bind<ReturnTypeT(*(FArgs ...))(Args ...)>>
|
||||||
|
#elif defined _MSC_VER // MS Visual Studio
|
||||||
|
struct function_traits<std::_Binder<std::_Unforced, ReturnTypeT(__cdecl &)(Args ...), FArgs ...>>
|
||||||
|
#else
|
||||||
|
#error "Unsupported C++ compiler / standard library"
|
||||||
#endif
|
#endif
|
||||||
: function_traits<ReturnTypeT(Args ...)>
|
: function_traits<ReturnTypeT(Args ...)>
|
||||||
{};
|
{};
|
||||||
|
|
|
@ -74,11 +74,25 @@ struct FunctionObjectOneIntOneChar
|
||||||
|
|
||||||
struct ObjectMember
|
struct ObjectMember
|
||||||
{
|
{
|
||||||
int callback(bool a)
|
int callback_one_bool(bool a)
|
||||||
{
|
{
|
||||||
(void)a;
|
(void)a;
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int callback_two_bools(bool a, bool b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
int callback_one_bool_one_float(bool a, float b)
|
||||||
|
{
|
||||||
|
(void)a;
|
||||||
|
(void)b;
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<
|
template<
|
||||||
|
@ -371,13 +385,91 @@ TEST(TestFunctionTraits, argument_types) {
|
||||||
|
|
||||||
ObjectMember object_member;
|
ObjectMember object_member;
|
||||||
|
|
||||||
auto bind_one_bool = std::bind(&ObjectMember::callback, &object_member, std::placeholders::_1);
|
auto bind_one_bool = std::bind(
|
||||||
|
&ObjectMember::callback_one_bool, &object_member, std::placeholders::_1);
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same<
|
std::is_same<
|
||||||
bool,
|
bool,
|
||||||
rclcpp::function_traits::function_traits<decltype(bind_one_bool)>::template argument_type<0>
|
rclcpp::function_traits::function_traits<decltype(bind_one_bool)>::template argument_type<0>
|
||||||
>::value, "Functor accepts a bool as first argument");
|
>::value, "Functor accepts a bool as first argument");
|
||||||
|
|
||||||
|
auto bind_two_bools = std::bind(
|
||||||
|
&ObjectMember::callback_two_bools, &object_member, std::placeholders::_1,
|
||||||
|
std::placeholders::_2);
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
bool,
|
||||||
|
rclcpp::function_traits::function_traits<decltype(bind_two_bools)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts a bool as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
bool,
|
||||||
|
rclcpp::function_traits::function_traits<decltype(bind_two_bools)>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts a bool as second argument");
|
||||||
|
|
||||||
|
auto bind_one_bool_one_float = std::bind(
|
||||||
|
&ObjectMember::callback_one_bool_one_float, &object_member, std::placeholders::_1,
|
||||||
|
std::placeholders::_2);
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
bool,
|
||||||
|
rclcpp::function_traits::function_traits<
|
||||||
|
decltype(bind_one_bool_one_float)
|
||||||
|
>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts a bool as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
float,
|
||||||
|
rclcpp::function_traits::function_traits<
|
||||||
|
decltype(bind_one_bool_one_float)
|
||||||
|
>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts a float as second argument");
|
||||||
|
|
||||||
|
auto bind_one_int = std::bind(func_one_int, std::placeholders::_1);
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits::function_traits<decltype(bind_one_int)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
auto bind_two_ints = std::bind(func_two_ints, std::placeholders::_1, std::placeholders::_2);
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits::function_traits<decltype(bind_two_ints)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits::function_traits<decltype(bind_two_ints)>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts an int as second argument");
|
||||||
|
|
||||||
|
auto bind_one_int_one_char = std::bind(
|
||||||
|
func_one_int_one_char, std::placeholders::_1, std::placeholders::_2);
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits::function_traits<
|
||||||
|
decltype(bind_one_int_one_char)
|
||||||
|
>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
char,
|
||||||
|
rclcpp::function_traits::function_traits<
|
||||||
|
decltype(bind_one_int_one_char)
|
||||||
|
>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts a char as second argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -462,7 +554,8 @@ TEST(TestFunctionTraits, check_arguments) {
|
||||||
|
|
||||||
ObjectMember object_member;
|
ObjectMember object_member;
|
||||||
|
|
||||||
auto bind_one_bool = std::bind(&ObjectMember::callback, &object_member, std::placeholders::_1);
|
auto bind_one_bool = std::bind(
|
||||||
|
&ObjectMember::callback_one_bool, &object_member, std::placeholders::_1);
|
||||||
|
|
||||||
// Test std::bind functions
|
// Test std::bind functions
|
||||||
static_assert(
|
static_assert(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue