Added support for free functions and std::bind

This commit is contained in:
Esteve Fernandez 2015-12-16 09:29:16 -08:00
parent 534ae69ed5
commit 1577ab2992
2 changed files with 113 additions and 4 deletions

View file

@ -78,7 +78,7 @@ template<typename ReturnTypeT, typename ... 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>
#if defined _LIBCPP_VERSION // libc++ (Clang)
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<
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
: function_traits<ReturnTypeT(Args ...)>
{};

View file

@ -74,11 +74,25 @@ struct FunctionObjectOneIntOneChar
struct ObjectMember
{
int callback(bool a)
int callback_one_bool(bool a)
{
(void)a;
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<
@ -371,13 +385,91 @@ TEST(TestFunctionTraits, argument_types) {
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(
std::is_same<
bool,
rclcpp::function_traits::function_traits<decltype(bind_one_bool)>::template argument_type<0>
>::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;
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
static_assert(