ROS 2 rclcpp + rcl - humble  humble
ROS 2 C++ Client Library with ROS Client Library
node_interfaces_helpers.hpp
1 // Copyright 2022 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__NODE_INTERFACES__DETAIL__NODE_INTERFACES_HELPERS_HPP_
16 #define RCLCPP__NODE_INTERFACES__DETAIL__NODE_INTERFACES_HELPERS_HPP_
17 
18 #include <memory>
19 #include <tuple>
20 #include <type_traits>
21 #include <utility>
22 
23 #include "rclcpp/visibility_control.hpp"
24 
25 namespace rclcpp
26 {
27 namespace node_interfaces
28 {
29 namespace detail
30 {
31 
32 // Support and Helper template classes for the NodeInterfaces class.
33 
34 template<typename NodeT, typename ... Ts>
35 std::tuple<std::shared_ptr<Ts>...>
36 init_tuple(NodeT & n);
37 
39 template<typename ... InterfaceTs>
41 {
42  template<typename NodeT>
43  NodeInterfacesStorage(NodeT & node) // NOLINT(runtime/explicit)
44  : interfaces_(init_tuple<decltype(node), InterfaceTs ...>(node))
45  {}
46 
47  explicit NodeInterfacesStorage(std::shared_ptr<InterfaceTs>... args)
48  : interfaces_(args ...)
49  {}
50 
52  template<typename NodeInterfaceT>
53  std::shared_ptr<NodeInterfaceT>
54  get()
55  {
56  static_assert(
57  (std::is_same_v<NodeInterfaceT, InterfaceTs>|| ...),
58  "NodeInterfaces class does not contain given NodeInterfaceT");
59  return std::get<std::shared_ptr<NodeInterfaceT>>(interfaces_);
60  }
61 
63  template<typename NodeInterfaceT>
64  std::shared_ptr<const NodeInterfaceT>
65  get() const
66  {
67  static_assert(
68  (std::is_same_v<NodeInterfaceT, InterfaceTs>|| ...),
69  "NodeInterfaces class does not contain given NodeInterfaceT");
70  return std::get<std::shared_ptr<NodeInterfaceT>>(interfaces_);
71  }
72 
73 protected:
74  std::tuple<std::shared_ptr<InterfaceTs>...> interfaces_;
75 };
76 
78 
84 template<typename StorageClassT, typename ... Ts>
85 struct NodeInterfacesSupports;
86 
88 
92 template<typename StorageClassT, typename ... InterfaceTs>
94 
96 template<typename StorageClassT, typename NextInterfaceT, typename ... RemainingInterfaceTs>
97 struct NodeInterfacesSupportCheck<StorageClassT, NextInterfaceT, RemainingInterfaceTs ...>
98  : public NodeInterfacesSupportCheck<StorageClassT, RemainingInterfaceTs ...>
99 {
100  static_assert(
102  "given NodeInterfaceT is not supported by rclcpp::node_interfaces::NodeInterfaces");
103 };
104 
106 template<typename StorageClassT>
107 struct NodeInterfacesSupportCheck<StorageClassT>
108 {};
109 
111 template<typename StorageClassT, typename ... RemainingInterfaceTs>
113 {
114  // Specializations need to set this to std::true_type in addition to other interfaces.
115  using is_supported = std::false_type;
116 };
117 
119 template<typename StorageClassT>
120 struct NodeInterfacesSupports<StorageClassT>
121  : public StorageClassT
122 {
124  template<typename ... ArgsT>
125  explicit NodeInterfacesSupports(ArgsT && ... args)
126  : StorageClassT(std::forward<ArgsT>(args) ...)
127  {}
128 };
129 
130 // Helper functions to initialize the tuple in NodeInterfaces.
131 
132 template<typename StorageClassT, typename ElementT, typename TupleT, typename NodeT>
133 void
134 init_element(TupleT & t, NodeT & n)
135 {
136  std::get<std::shared_ptr<ElementT>>(t) =
137  NodeInterfacesSupports<StorageClassT, ElementT>::get_from_node_like(n);
138 }
139 
140 template<typename NodeT, typename ... Ts>
141 std::tuple<std::shared_ptr<Ts>...>
142 init_tuple(NodeT & n)
143 {
144  using StorageClassT = NodeInterfacesStorage<Ts ...>;
145  std::tuple<std::shared_ptr<Ts>...> t;
146  (init_element<StorageClassT, Ts>(t, n), ...);
147  return t;
148 }
149 
151 
166 #define RCLCPP_NODE_INTERFACE_HELPERS_SUPPORT(NodeInterfaceType, NodeInterfaceName) \
167  namespace rclcpp::node_interfaces::detail { \
168  template<typename StorageClassT, typename ... RemainingInterfaceTs> \
169  struct NodeInterfacesSupports< \
170  StorageClassT, \
171  NodeInterfaceType, \
172  RemainingInterfaceTs ...> \
173  : public NodeInterfacesSupports<StorageClassT, RemainingInterfaceTs ...> \
174  { \
175  using is_supported = std::true_type; \
176  \
177  template<typename NodeT> \
178  static \
179  std::shared_ptr<NodeInterfaceType> \
180  get_from_node_like(NodeT & node_like) \
181  { \
182  return node_like.get_node_ ## NodeInterfaceName ## _interface(); \
183  } \
184  \
185  /* Perfect forwarding constructor to get arguments down to StorageClassT (eventually). */ \
186  template<typename ... ArgsT> \
187  explicit NodeInterfacesSupports(ArgsT && ... args) \
188  : NodeInterfacesSupports<StorageClassT, RemainingInterfaceTs ...>( \
189  std::forward<ArgsT>(args) ...) \
190  {} \
191  \
192  std::shared_ptr<NodeInterfaceType> \
193  get_node_ ## NodeInterfaceName ## _interface() \
194  { \
195  return StorageClassT::template get<NodeInterfaceType>(); \
196  } \
197  \
198  std::shared_ptr<const NodeInterfaceType> \
199  get_node_ ## NodeInterfaceName ## _interface() const \
200  { \
201  return StorageClassT::template get<NodeInterfaceType>(); \
202  } \
203  }; \
204  } // namespace rclcpp::node_interfaces::detail
205 
206 } // namespace detail
207 } // namespace node_interfaces
208 } // namespace rclcpp
209 
210 #endif // RCLCPP__NODE_INTERFACES__DETAIL__NODE_INTERFACES_HELPERS_HPP_
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
Stores the interfaces in a tuple, provides constructors, and getters.
std::shared_ptr< const NodeInterfaceT > get() const
Individual Node Interface const getter.
std::shared_ptr< NodeInterfaceT > get()
Individual Node Interface non-const getter.
Prototype of NodeInterfacesSupportCheck template meta-function.
NodeInterfacesSupports(ArgsT &&... args)
Perfect forwarding constructor to get arguments down to StorageClassT.