ROS 2 rclcpp + rcl - jazzy  jazzy
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 
48  : interfaces_()
49  {}
50 
51  explicit NodeInterfacesStorage(std::shared_ptr<InterfaceTs>... args)
52  : interfaces_(args ...)
53  {}
54 
56  template<typename NodeInterfaceT>
57  std::shared_ptr<NodeInterfaceT>
58  get()
59  {
60  static_assert(
61  (std::is_same_v<NodeInterfaceT, InterfaceTs>|| ...),
62  "NodeInterfaces class does not contain given NodeInterfaceT");
63  return std::get<std::shared_ptr<NodeInterfaceT>>(interfaces_);
64  }
65 
67  template<typename NodeInterfaceT>
68  std::shared_ptr<const NodeInterfaceT>
69  get() const
70  {
71  static_assert(
72  (std::is_same_v<NodeInterfaceT, InterfaceTs>|| ...),
73  "NodeInterfaces class does not contain given NodeInterfaceT");
74  return std::get<std::shared_ptr<NodeInterfaceT>>(interfaces_);
75  }
76 
77 protected:
78  std::tuple<std::shared_ptr<InterfaceTs>...> interfaces_;
79 };
80 
82 
88 template<typename StorageClassT, typename ... Ts>
89 struct NodeInterfacesSupports;
90 
92 
96 template<typename StorageClassT, typename ... InterfaceTs>
98 
100 template<typename StorageClassT, typename NextInterfaceT, typename ... RemainingInterfaceTs>
101 struct NodeInterfacesSupportCheck<StorageClassT, NextInterfaceT, RemainingInterfaceTs ...>
102  : public NodeInterfacesSupportCheck<StorageClassT, RemainingInterfaceTs ...>
103 {
104  static_assert(
106  "given NodeInterfaceT is not supported by rclcpp::node_interfaces::NodeInterfaces");
107 };
108 
110 template<typename StorageClassT>
111 struct NodeInterfacesSupportCheck<StorageClassT>
112 {};
113 
115 template<typename StorageClassT, typename ... RemainingInterfaceTs>
117 {
118  // Specializations need to set this to std::true_type in addition to other interfaces.
119  using is_supported = std::false_type;
120 };
121 
123 template<typename StorageClassT>
124 struct NodeInterfacesSupports<StorageClassT>
125  : public StorageClassT
126 {
128  template<typename ... ArgsT>
129  explicit NodeInterfacesSupports(ArgsT && ... args)
130  : StorageClassT(std::forward<ArgsT>(args) ...)
131  {}
132 };
133 
134 // Helper functions to initialize the tuple in NodeInterfaces.
135 
136 template<typename StorageClassT, typename ElementT, typename TupleT, typename NodeT>
137 void
138 init_element(TupleT & t, NodeT & n)
139 {
140  std::get<std::shared_ptr<ElementT>>(t) =
141  NodeInterfacesSupports<StorageClassT, ElementT>::get_from_node_like(n);
142 }
143 
144 template<typename NodeT, typename ... Ts>
145 std::tuple<std::shared_ptr<Ts>...>
146 init_tuple(NodeT & n)
147 {
148  using StorageClassT = NodeInterfacesStorage<Ts ...>;
149  std::tuple<std::shared_ptr<Ts>...> t;
150  (init_element<StorageClassT, Ts>(t, n), ...);
151  return t;
152 }
153 
155 
170 // *INDENT-OFF*
171 #define RCLCPP_NODE_INTERFACE_HELPERS_SUPPORT(NodeInterfaceType, NodeInterfaceName) \
172  namespace rclcpp::node_interfaces::detail { \
173  template<typename StorageClassT, typename ... RemainingInterfaceTs> \
174  struct NodeInterfacesSupports< \
175  StorageClassT, \
176  NodeInterfaceType, \
177  RemainingInterfaceTs ...> \
178  : public NodeInterfacesSupports<StorageClassT, RemainingInterfaceTs ...> \
179  { \
180  using is_supported = std::true_type; \
181  \
182  template<typename NodeT> \
183  static \
184  std::shared_ptr<NodeInterfaceType> \
185  get_from_node_like(NodeT & node_like) \
186  { \
187  return node_like.get_node_ ## NodeInterfaceName ## _interface(); \
188  } \
189  \
190  /* Perfect forwarding constructor to get arguments down to StorageClassT (eventually). */ \
191  template<typename ... ArgsT> \
192  explicit NodeInterfacesSupports(ArgsT && ... args) \
193  : NodeInterfacesSupports<StorageClassT, RemainingInterfaceTs ...>( \
194  std::forward<ArgsT>(args) ...) \
195  {} \
196  \
197  std::shared_ptr<NodeInterfaceType> \
198  get_node_ ## NodeInterfaceName ## _interface() \
199  { \
200  return StorageClassT::template get<NodeInterfaceType>(); \
201  } \
202  }; \
203  } // namespace rclcpp::node_interfaces::detail
204 // *INDENT-ON*
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.