Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add check_argument_types #130

Merged
merged 1 commit into from
Oct 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 22 additions & 44 deletions rclcpp/include/rclcpp/any_subscription_callback.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,80 +59,58 @@ struct AnySubscriptionCallback

template<
typename CallbackT,
std::size_t Arity = 1
>
typename std::enable_if<rclcpp::arity_comparator<Arity, CallbackT>::value, void>::type
set(
CallbackT callback,
typename std::enable_if<
std::is_same<
typename function_traits<CallbackT>::template argument_type<0>,
rclcpp::check_argument_types<
CallbackT,
typename std::shared_ptr<MessageT>
>::value
>::type * = nullptr)
>::type * = nullptr
>
void set(CallbackT callback)
{
shared_ptr_callback = callback;
}

template<
typename CallbackT,
std::size_t Arity = 2
>
typename std::enable_if<rclcpp::arity_comparator<Arity, CallbackT>::value, void>::type
set(
CallbackT callback,
typename std::enable_if<
std::is_same<
typename function_traits<CallbackT>::template argument_type<0>,
typename std::shared_ptr<MessageT>
>::value
>::type * = nullptr,
typename std::enable_if<
std::is_same<
typename function_traits<CallbackT>::template argument_type<1>,
rclcpp::check_argument_types<
CallbackT,
typename std::shared_ptr<MessageT>,
const rmw_message_info_t &
>::value
>::type * = nullptr)
>::type * = nullptr
>
void set(CallbackT callback)
{
shared_ptr_with_info_callback = callback;
}

template<
typename CallbackT,
std::size_t Arity = 1
>
typename std::enable_if<rclcpp::arity_comparator<Arity, CallbackT>::value, void>::type
set(
CallbackT callback,
typename std::enable_if<
std::is_same<
typename function_traits<CallbackT>::template argument_type<0>,
rclcpp::check_argument_types<
CallbackT,
typename std::shared_ptr<const MessageT>
>::value
>::type * = nullptr)
>::type * = nullptr
>
void set(CallbackT callback)
{
const_shared_ptr_callback = callback;
}

template<
typename CallbackT,
std::size_t Arity = 2
>
typename std::enable_if<rclcpp::arity_comparator<Arity, CallbackT>::value, void>::type
set(
CallbackT callback,
typename std::enable_if<
std::is_same<
typename function_traits<CallbackT>::template argument_type<0>,
typename std::shared_ptr<const MessageT>
>::value
>::type * = nullptr,
typename std::enable_if<
std::is_same<
typename function_traits<CallbackT>::template argument_type<1>,
rclcpp::check_argument_types<
CallbackT,
typename std::shared_ptr<const MessageT>,
const rmw_message_info_t &
>::value
>::type * = nullptr)
>::type * = nullptr
>
void set(CallbackT callback)
{
const_shared_ptr_with_info_callback = callback;
}
Expand Down
34 changes: 30 additions & 4 deletions rclcpp/include/rclcpp/function_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,36 @@ struct function_traits<ReturnTypeT (ClassT::*)(Args ...) const>
* the arity of a function.
*/
template<std::size_t Arity, typename FunctorT>
struct arity_comparator
{
static constexpr bool value = (Arity == function_traits<FunctorT>::arity);
};
struct arity_comparator : std::integral_constant<
bool, (Arity == function_traits<FunctorT>::arity)>{};

template<typename FunctorT, typename First, typename ... Last>
struct check_argument_types_recursive : std::conditional<
std::is_same<
typename function_traits<FunctorT>::template argument_type<
function_traits<FunctorT>::arity - sizeof ... (Last) -1
>,
First
>::value,
check_argument_types_recursive<FunctorT, Last ...>,
std::false_type>::type
{};

template<typename FunctorT, typename Arg>
struct check_argument_types_recursive<FunctorT, Arg>: std::is_same<
typename function_traits<FunctorT>::template argument_type<
function_traits<FunctorT>::arity - 1
>,
Arg
>
{};

template<typename FunctorT, typename ... Args>
struct check_argument_types : std::conditional<
arity_comparator<sizeof ... (Args), FunctorT>::value,
check_argument_types_recursive<FunctorT, Args ...>,
std::false_type>::type
{};

} /* namespace rclcpp */

Expand Down
71 changes: 19 additions & 52 deletions rclcpp/include/rclcpp/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,42 +283,23 @@ class Node
bool ignore_local_publications,
typename message_memory_strategy::MessageMemoryStrategy<MessageT>::SharedPtr msg_mem_strat);

/* NOTE(esteve):
* The following template machinery works around VS2015's lack of support for expression SFINAE:
* - We first declare the arity we want to match, i.e. 2 or 3.
* - Then we use the arity_comparator template to SFINAE on the arity of the passed functor.
* - Lastly, we SFINAE on the types of the arguments of the functor.
* These steps happen in different parts of the function signature because we want to stagger
* instantation of the templates because VS2015 can't conditionally enable templates that depend
* on another template.
* See test_function_traits.cpp for streamlined examples of how to use this pattern.
*/
template<
typename ServiceT,
typename FunctorT,
std::size_t Arity = 2
typename std::enable_if<
rclcpp::check_argument_types<
FunctorT,
typename std::shared_ptr<typename ServiceT::Request>,
typename std::shared_ptr<typename ServiceT::Response>
>::value
>::type * = nullptr
>
typename std::enable_if<
rclcpp::arity_comparator<Arity, FunctorT>::value,
typename rclcpp::service::Service<ServiceT>::SharedPtr
>::type
typename rclcpp::service::Service<ServiceT>::SharedPtr
create_service_internal(
std::shared_ptr<rmw_node_t> node_handle,
rmw_service_t * service_handle,
const std::string & service_name,
FunctorT callback,
typename std::enable_if<
std::is_same<
typename function_traits<FunctorT>::template argument_type<0>,
typename std::shared_ptr<typename ServiceT::Request>
>::value
>::type * = nullptr,
typename std::enable_if<
std::is_same<
typename function_traits<FunctorT>::template argument_type<1>,
typename std::shared_ptr<typename ServiceT::Response>
>::value
>::type * = nullptr)
FunctorT callback)
{
typename rclcpp::service::Service<ServiceT>::CallbackType callback_without_header =
callback;
Expand All @@ -329,35 +310,21 @@ class Node
template<
typename ServiceT,
typename FunctorT,
std::size_t Arity = 3
typename std::enable_if<
rclcpp::check_argument_types<
FunctorT,
std::shared_ptr<rmw_request_id_t>,
typename std::shared_ptr<typename ServiceT::Request>,
typename std::shared_ptr<typename ServiceT::Response>
>::value
>::type * = nullptr
>
typename std::enable_if<
arity_comparator<Arity, FunctorT>::value,
typename rclcpp::service::Service<ServiceT>::SharedPtr
>::type
typename rclcpp::service::Service<ServiceT>::SharedPtr
create_service_internal(
std::shared_ptr<rmw_node_t> node_handle,
rmw_service_t * service_handle,
const std::string & service_name,
FunctorT callback,
typename std::enable_if<
std::is_same<
typename function_traits<FunctorT>::template argument_type<0>,
std::shared_ptr<rmw_request_id_t>
>::value
>::type * = nullptr,
typename std::enable_if<
std::is_same<
typename function_traits<FunctorT>::template argument_type<1>,
typename std::shared_ptr<typename ServiceT::Request>
>::value
>::type * = nullptr,
typename std::enable_if<
std::is_same<
typename function_traits<FunctorT>::template argument_type<2>,
typename std::shared_ptr<typename ServiceT::Response>
>::value
>::type * = nullptr)
FunctorT callback)
{
typename rclcpp::service::Service<ServiceT>::CallbackWithHeaderType callback_with_header =
callback;
Expand Down
Loading