rclcpp  master
C++ ROS Client Library API
function_traits.hpp
Go to the documentation of this file.
1 // Copyright 2014 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RCLCPP__FUNCTION_TRAITS_HPP_
16 #define RCLCPP__FUNCTION_TRAITS_HPP_
17 
18 #include <functional>
19 #include <memory>
20 #include <tuple>
21 
22 namespace rclcpp
23 {
24 
25 namespace function_traits
26 {
27 
28 /* NOTE(esteve):
29  * We support service callbacks that can optionally take the request id,
30  * which should be possible with two overloaded create_service methods,
31  * but unfortunately std::function's constructor on VS2015 is too greedy,
32  * so we need a mechanism for checking the arity and the type of each argument
33  * in a callback function.
34  * See http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx
35  */
36 
37 // Remove the first item in a tuple
38 template<typename T>
39 struct tuple_tail;
40 
41 template<typename Head, typename ... Tail>
42 struct tuple_tail<std::tuple<Head, Tail ...>>
43 {
44  using type = std::tuple<Tail ...>;
45 };
46 
47 // std::function
48 template<typename FunctionT>
50 {
51  using arguments = typename tuple_tail<
52  typename function_traits<decltype( &FunctionT::operator())>::arguments>::type;
53 
54  static constexpr std::size_t arity = std::tuple_size<arguments>::value;
55 
56  template<std::size_t N>
57  using argument_type = typename std::tuple_element<N, arguments>::type;
58 
59  using return_type = typename function_traits<decltype( &FunctionT::operator())>::return_type;
60 };
61 
62 // Free functions
63 template<typename ReturnTypeT, typename ... Args>
64 struct function_traits<ReturnTypeT(Args ...)>
65 {
66  using arguments = std::tuple<Args ...>;
67 
68  static constexpr std::size_t arity = std::tuple_size<arguments>::value;
69 
70  template<std::size_t N>
71  using argument_type = typename std::tuple_element<N, arguments>::type;
72 
73  using return_type = ReturnTypeT;
74 };
75 
76 // Function pointers
77 template<typename ReturnTypeT, typename ... Args>
78 struct function_traits<ReturnTypeT (*)(Args ...)>: function_traits<ReturnTypeT(Args ...)>
79 {};
80 
81 // std::bind for object methods
82 template<typename ClassT, typename ReturnTypeT, typename ... Args, typename ... FArgs>
83 #if defined _LIBCPP_VERSION // libc++ (Clang)
84 struct function_traits<std::__bind<ReturnTypeT (ClassT::*)(Args ...), FArgs ...>>
85 #elif defined _GLIBCXX_RELEASE // glibc++ (GNU C++ >= 7.1)
86 struct function_traits<std::_Bind<ReturnTypeT(ClassT::*(FArgs ...))(Args ...)>>
87 #elif defined __GLIBCXX__ // glibc++ (GNU C++)
88 struct function_traits<std::_Bind<std::_Mem_fn<ReturnTypeT (ClassT::*)(Args ...)>(FArgs ...)>>
89 #elif defined _MSC_VER // MS Visual Studio
90 struct function_traits<
91  std::_Binder<std::_Unforced, ReturnTypeT (ClassT::*)(Args ...), FArgs ...>>
92 #else
93 #error "Unsupported C++ compiler / standard library"
94 #endif
95  : function_traits<ReturnTypeT(Args ...)>
96 {};
97 
98 // std::bind for object const methods
99 template<typename ClassT, typename ReturnTypeT, typename ... Args, typename ... FArgs>
100 #if defined _LIBCPP_VERSION // libc++ (Clang)
101 struct function_traits<std::__bind<ReturnTypeT (ClassT::*)(Args ...) const, FArgs ...>>
102 #elif defined _GLIBCXX_RELEASE // glibc++ (GNU C++ >= 7.1)
103 struct function_traits<std::_Bind<ReturnTypeT(ClassT::*(FArgs ...))(Args ...) const>>
104 #elif defined __GLIBCXX__ // glibc++ (GNU C++)
105 struct function_traits<std::_Bind<std::_Mem_fn<ReturnTypeT (ClassT::*)(Args ...) const>(FArgs ...)>>
106 #elif defined _MSC_VER // MS Visual Studio
107 struct function_traits<
108  std::_Binder<std::_Unforced, ReturnTypeT (ClassT::*)(Args ...) const, FArgs ...>>
109 #else
110 #error "Unsupported C++ compiler / standard library"
111 #endif
112  : function_traits<ReturnTypeT(Args ...)>
113 {};
114 
115 // std::bind for free functions
116 template<typename ReturnTypeT, typename ... Args, typename ... FArgs>
117 #if defined _LIBCPP_VERSION // libc++ (Clang)
118 struct function_traits<std::__bind<ReturnTypeT( &)(Args ...), FArgs ...>>
119 #elif defined __GLIBCXX__ // glibc++ (GNU C++)
120 struct function_traits<std::_Bind<ReturnTypeT(*(FArgs ...))(Args ...)>>
121 #elif defined _MSC_VER // MS Visual Studio
122 struct function_traits<std::_Binder<std::_Unforced, ReturnTypeT( &)(Args ...), FArgs ...>>
123 #else
124 #error "Unsupported C++ compiler / standard library"
125 #endif
126  : function_traits<ReturnTypeT(Args ...)>
127 {};
128 
129 // Lambdas
130 template<typename ClassT, typename ReturnTypeT, typename ... Args>
131 struct function_traits<ReturnTypeT (ClassT::*)(Args ...) const>
132  : function_traits<ReturnTypeT(ClassT &, Args ...)>
133 {};
134 
135 template<typename FunctionT>
137 {};
138 
139 template<typename FunctionT>
141 {};
142 
143 /* NOTE(esteve):
144  * VS2015 does not support expression SFINAE, so we're using this template to evaluate
145  * the arity of a function.
146  */
147 template<std::size_t Arity, typename FunctorT>
149  bool, (Arity == function_traits<FunctorT>::arity)> {};
150 
151 template<typename FunctorT, typename ... Args>
153  typename function_traits<FunctorT>::arguments,
154  std::tuple<Args ...>
155 >
156 {};
157 
158 template<typename FunctorAT, typename FunctorBT>
160  typename function_traits<FunctorAT>::arguments,
161  typename function_traits<FunctorBT>::arguments
162 >
163 {};
164 
165 } // namespace function_traits
166 
167 } // namespace rclcpp
168 
169 #endif // RCLCPP__FUNCTION_TRAITS_HPP_
rclcpp::function_traits::function_traits::arguments
typename tuple_tail< typename function_traits< decltype(&FunctionT::operator())>::arguments >::type arguments
Definition: function_traits.hpp:52
std::is_same
std::integral_constant
rclcpp::function_traits::function_traits< ReturnTypeT(ClassT &, Args ...)>::return_type
typename function_traits< decltype(&ReturnTypeT(ClassT &, Args ...) ::operator())>::return_type return_type
Definition: function_traits.hpp:59
rclcpp::function_traits::function_traits
Definition: function_traits.hpp:49
std::tuple
rclcpp
This header provides the get_node_base_interface() template function.
Definition: allocator_common.hpp:24
rclcpp::function_traits::tuple_tail
Definition: function_traits.hpp:39
rclcpp::function_traits::check_arguments
Definition: function_traits.hpp:152
rclcpp::function_traits::function_traits::arity
static constexpr std::size_t arity
Definition: function_traits.hpp:54
rclcpp::function_traits::same_arguments
Definition: function_traits.hpp:159
rclcpp::function_traits::function_traits< ReturnTypeT(Args ...)>::return_type
ReturnTypeT return_type
Definition: function_traits.hpp:73
std
rclcpp::function_traits::function_traits< ReturnTypeT(ClassT &, Args ...)>::argument_type
typename std::tuple_element< N, arguments >::type argument_type
Definition: function_traits.hpp:57
rclcpp::function_traits::arity_comparator
Definition: function_traits.hpp:148
std::size_t
rclcpp::function_traits::function_traits< ReturnTypeT(Args ...)>::argument_type
typename std::tuple_element< N, arguments >::type argument_type
Definition: function_traits.hpp:71