ROS 2 rclcpp + rcl - rolling  rolling-5dd47aaf
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 
24 namespace rclcpp
25 {
26 namespace node_interfaces
27 {
28 namespace detail
29 {
30 
31 // Support and Helper template classes for the NodeInterfaces class.
32 
33 template<typename NodeT, typename ... Ts>
34 std::tuple<std::shared_ptr<Ts>...>
35 init_tuple(NodeT & n);
36 
38 template<typename ... InterfaceTs>
40 {
41  template<typename NodeT>
42  NodeInterfacesStorage(NodeT & node) // NOLINT(runtime/explicit)
43  : interfaces_(init_tuple<decltype(node), InterfaceTs ...>(node))
44  {}
45 
47  : interfaces_()
48  {}
49 
50  explicit NodeInterfacesStorage(std::shared_ptr<InterfaceTs>... args)
51  : interfaces_(args ...)
52  {}
53 
55  template<typename NodeInterfaceT>
56  std::shared_ptr<NodeInterfaceT>
57  get()
58  {
59  static_assert(
60  (std::is_same_v<NodeInterfaceT, InterfaceTs>|| ...),
61  "NodeInterfaces class does not contain given NodeInterfaceT");
62  return std::get<std::shared_ptr<NodeInterfaceT>>(interfaces_);
63  }
64 
66  template<typename NodeInterfaceT>
67  std::shared_ptr<const NodeInterfaceT>
68  get() const
69  {
70  static_assert(
71  (std::is_same_v<NodeInterfaceT, InterfaceTs>|| ...),
72  "NodeInterfaces class does not contain given NodeInterfaceT");
73  return std::get<std::shared_ptr<NodeInterfaceT>>(interfaces_);
74  }
75 
76 protected:
77  std::tuple<std::shared_ptr<InterfaceTs>...> interfaces_;
78 };
79 
81 
87 template<typename StorageClassT, typename ... Ts>
88 struct NodeInterfacesSupports;
89 
91 
95 template<typename StorageClassT, typename ... InterfaceTs>
97 
99 template<typename StorageClassT, typename NextInterfaceT, typename ... RemainingInterfaceTs>
100 struct NodeInterfacesSupportCheck<StorageClassT, NextInterfaceT, RemainingInterfaceTs ...>
101  : public NodeInterfacesSupportCheck<StorageClassT, RemainingInterfaceTs ...>
102 {
103  static_assert(
105  "given NodeInterfaceT is not supported by rclcpp::node_interfaces::NodeInterfaces");
106 };
107 
109 template<typename StorageClassT>
110 struct NodeInterfacesSupportCheck<StorageClassT>
111 {};
112 
114 template<typename StorageClassT, typename ... RemainingInterfaceTs>
116 {
117  // Specializations need to set this to std::true_type in addition to other interfaces.
118  using is_supported = std::false_type;
119 };
120 
122 template<typename StorageClassT>
123 struct NodeInterfacesSupports<StorageClassT>
124  : public StorageClassT
125 {
127  template<typename ... ArgsT>
128  explicit NodeInterfacesSupports(ArgsT && ... args)
129  : StorageClassT(std::forward<ArgsT>(args) ...)
130  {}
131 };
132 
133 // Helper functions to initialize the tuple in NodeInterfaces.
134 
135 template<typename StorageClassT, typename ElementT, typename TupleT, typename NodeT>
136 void
137 init_element(TupleT & t, NodeT & n)
138 {
139  std::get<std::shared_ptr<ElementT>>(t) =
140  NodeInterfacesSupports<StorageClassT, ElementT>::get_from_node_like(n);
141 }
142 
143 template<typename NodeT, typename ... Ts>
144 std::tuple<std::shared_ptr<Ts>...>
145 init_tuple(NodeT & n)
146 {
147  using StorageClassT = NodeInterfacesStorage<Ts ...>;
148  std::tuple<std::shared_ptr<Ts>...> t;
149  (init_element<StorageClassT, Ts>(t, n), ...);
150  return t;
151 }
152 
154 
169 // *INDENT-OFF*
170 #define RCLCPP_NODE_INTERFACE_HELPERS_SUPPORT(NodeInterfaceType, NodeInterfaceName) \
171  namespace rclcpp::node_interfaces::detail { \
172  template<typename StorageClassT, typename ... RemainingInterfaceTs> \
173  struct NodeInterfacesSupports< \
174  StorageClassT, \
175  NodeInterfaceType, \
176  RemainingInterfaceTs ...> \
177  : public NodeInterfacesSupports<StorageClassT, RemainingInterfaceTs ...> \
178  { \
179  using is_supported = std::true_type; \
180  \
181  template<typename NodeT> \
182  static \
183  std::shared_ptr<NodeInterfaceType> \
184  get_from_node_like(NodeT & node_like) \
185  { \
186  return node_like.get_node_ ## NodeInterfaceName ## _interface(); \
187  } \
188  \
189  /* Perfect forwarding constructor to get arguments down to StorageClassT (eventually). */ \
190  template<typename ... ArgsT> \
191  explicit NodeInterfacesSupports(ArgsT && ... args) \
192  : NodeInterfacesSupports<StorageClassT, RemainingInterfaceTs ...>( \
193  std::forward<ArgsT>(args) ...) \
194  {} \
195  \
196  std::shared_ptr<NodeInterfaceType> \
197  get_node_ ## NodeInterfaceName ## _interface() \
198  { \
199  return StorageClassT::template get<NodeInterfaceType>(); \
200  } \
201  \
202  std::shared_ptr<const NodeInterfaceType> \
203  get_node_ ## NodeInterfaceName ## _interface() const \
204  { \
205  return StorageClassT::template get<NodeInterfaceType>(); \
206  } \
207  }; \
208  } // namespace rclcpp::node_interfaces::detail
209 // *INDENT-ON*
210 
211 } // namespace detail
212 } // namespace node_interfaces
213 } // namespace rclcpp
214 
215 #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.