diff --git a/rclcpp/include/rclcpp/function_traits.hpp b/rclcpp/include/rclcpp/function_traits.hpp index 910c353..25a8ed7 100644 --- a/rclcpp/include/rclcpp/function_traits.hpp +++ b/rclcpp/include/rclcpp/function_traits.hpp @@ -78,7 +78,7 @@ template struct function_traits: function_traits {}; -// std::bind +// std::bind for object methods template #if defined _LIBCPP_VERSION // libc++ (Clang) struct function_traits> @@ -88,6 +88,22 @@ struct function_traits > +#else +#error "Unsupported C++ compiler / standard library" +#endif + : function_traits +{}; + +// std::bind for free functions +template +#if defined _LIBCPP_VERSION // libc++ (Clang) +struct function_traits> +#elif defined __GLIBCXX__ // glibc++ (GNU C++) +struct function_traits> +#elif defined _MSC_VER // MS Visual Studio +struct function_traits> +#else +#error "Unsupported C++ compiler / standard library" #endif : function_traits {}; diff --git a/rclcpp/test/test_function_traits.cpp b/rclcpp/test/test_function_traits.cpp index aaaf53f..3121bda 100644 --- a/rclcpp/test/test_function_traits.cpp +++ b/rclcpp/test/test_function_traits.cpp @@ -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::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::template argument_type<0> + >::value, "Functor accepts a bool as first argument"); + + static_assert( + std::is_same< + bool, + rclcpp::function_traits::function_traits::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::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::template argument_type<0> + >::value, "Functor accepts an int as first argument"); + + static_assert( + std::is_same< + int, + rclcpp::function_traits::function_traits::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(