From eff6500aca1dbc54584a4bfe4ac64b997484ea60 Mon Sep 17 00:00:00 2001 From: Esteve Fernandez Date: Thu, 19 Nov 2015 17:17:01 -0800 Subject: [PATCH] Added support for deducing the return type of a functor --- rclcpp/include/rclcpp/function_traits.hpp | 4 ++ rclcpp/test/test_function_traits.cpp | 85 ++++++++++++++++++++++- 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/rclcpp/include/rclcpp/function_traits.hpp b/rclcpp/include/rclcpp/function_traits.hpp index 0f8ef75..5e3b498 100644 --- a/rclcpp/include/rclcpp/function_traits.hpp +++ b/rclcpp/include/rclcpp/function_traits.hpp @@ -54,6 +54,8 @@ struct function_traits template using argument_type = typename std::tuple_element::type; + + using return_type = typename function_traits::return_type; }; // Free functions @@ -66,6 +68,8 @@ struct function_traits template using argument_type = typename std::tuple_element::type; + + using return_type = ReturnTypeT; }; // Function pointers diff --git a/rclcpp/test/test_function_traits.cpp b/rclcpp/test/test_function_traits.cpp index 5475060..363e9d1 100644 --- a/rclcpp/test/test_function_traits.cpp +++ b/rclcpp/test/test_function_traits.cpp @@ -14,7 +14,9 @@ #include -#include +#include + +#include "rclcpp/function_traits.hpp" int func_no_args() { @@ -118,6 +120,42 @@ int func_accept_callback(FunctorT callback) return callback(a, b); } +template< + typename FunctorT, + std::size_t Arity = 0, + typename std::enable_if< + rclcpp::function_traits::arity_comparator::value + >::type * = nullptr, + typename std::enable_if< + std::is_same< + typename rclcpp::function_traits::function_traits::return_type, + double + >::value + >::type * = nullptr +> +double func_accept_callback_return_type(FunctorT callback) +{ + return callback(); +} + +template< + typename FunctorT, + std::size_t Arity = 0, + typename std::enable_if< + rclcpp::function_traits::arity_comparator::value + >::type * = nullptr, + typename std::enable_if< + std::is_same< + typename rclcpp::function_traits::function_traits::return_type, + std::string + >::value + >::type * = nullptr +> +std::string func_accept_callback_return_type(FunctorT callback) +{ + return callback(); +} + /* Tests that funcion_traits calculates arity of several functors. */ @@ -452,6 +490,39 @@ TEST(TestFunctionTraits, same_arguments) { "Functor and lambda have the same arguments"); } +TEST(TestFunctionTraits, return_type) { + // Test regular function + static_assert( + std::is_same< + rclcpp::function_traits::function_traits::return_type, + int + >::value, + "Functor return ints"); + + // Test lambda + auto lambda_one_int_return_double = [](int one) -> double { + (void)one; + return 1.0; + }; + + static_assert( + std::is_same< + rclcpp::function_traits::function_traits< + decltype(lambda_one_int_return_double) + >::return_type, + double + >::value, + "Lambda returns a double"); + + // Test objects that have a call operator + static_assert( + std::is_same< + rclcpp::function_traits::function_traits::return_type, + int + >::value, + "Functor return ints"); +} + /* Tests that functions are matched via SFINAE. */ @@ -500,4 +571,16 @@ TEST(TestFunctionTraits, sfinae_match) { EXPECT_EQ(2, func_accept_callback(FunctionObjectTwoInts())); EXPECT_EQ(3, func_accept_callback(FunctionObjectOneIntOneChar())); + + auto lambda_no_args_double = []() -> double { + return 123.45; + }; + + auto lambda_no_args_string = []() -> std::string { + return std::string("foo"); + }; + + EXPECT_EQ(123.45, func_accept_callback_return_type(lambda_no_args_double)); + + EXPECT_EQ("foo", func_accept_callback_return_type(lambda_no_args_string)); }