ROS 2 rclcpp + rcl - lyrical  lyrical
ROS 2 C++ Client Library with ROS Client Library
any_subscription_callback.hpp
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__ANY_SUBSCRIPTION_CALLBACK_HPP_
16 #define RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
17 
18 #include <atomic>
19 #include <functional>
20 #include <memory>
21 #include <mutex>
22 #include <stdexcept>
23 #include <type_traits>
24 #include <utility>
25 #include <variant>
26 
27 #include "rosidl_runtime_cpp/traits.hpp"
28 #include "tracetools/tracetools.h"
29 #include "tracetools/utils.hpp"
30 
31 #include "rclcpp/allocator/allocator_common.hpp"
32 #include "rclcpp/detail/subscription_callback_type_helper.hpp"
33 #include "rclcpp/function_traits.hpp"
34 #include "rclcpp/message_info.hpp"
35 #include "rclcpp/serialization.hpp"
36 #include "rclcpp/serialized_message.hpp"
37 #include "rclcpp/type_adapter.hpp"
38 
39 namespace rclcpp
40 {
41 
42 namespace detail
43 {
44 
45 template<class>
46 inline constexpr bool always_false_v = false;
47 
48 template<typename MessageT, typename AllocatorT>
50 {
51  using AllocTraits = allocator::AllocRebind<MessageT, AllocatorT>;
52  using Alloc = typename AllocTraits::allocator_type;
53  using Deleter = allocator::Deleter<Alloc, MessageT>;
54 };
55 
57 template<typename MessageT, typename AllocatorT>
59 {
61  using SubscribedType = typename rclcpp::TypeAdapter<MessageT>::custom_type;
63  using ROSMessageType = typename rclcpp::TypeAdapter<MessageT>::ros_message_type;
64 
65  using SubscribedMessageDeleter =
66  typename MessageDeleterHelper<SubscribedType, AllocatorT>::Deleter;
67  using ROSMessageDeleter =
68  typename MessageDeleterHelper<ROSMessageType, AllocatorT>::Deleter;
69  using SerializedMessageDeleter =
70  typename MessageDeleterHelper<rclcpp::SerializedMessage, AllocatorT>::Deleter;
71 
72  using ConstRefCallback =
73  std::function<void (const SubscribedType &)>;
74  using ConstRefROSMessageCallback =
75  std::function<void (const ROSMessageType &)>;
76  using ConstRefWithInfoCallback =
77  std::function<void (const SubscribedType &, const rclcpp::MessageInfo &)>;
78  using ConstRefWithInfoROSMessageCallback =
79  std::function<void (const ROSMessageType &, const rclcpp::MessageInfo &)>;
80  using ConstRefSerializedMessageCallback =
81  std::function<void (const rclcpp::SerializedMessage &)>;
82  using ConstRefSerializedMessageWithInfoCallback =
83  std::function<void (const rclcpp::SerializedMessage &, const rclcpp::MessageInfo &)>;
84 
85  using UniquePtrCallback =
86  std::function<void (std::unique_ptr<SubscribedType, SubscribedMessageDeleter>)>;
87  using UniquePtrROSMessageCallback =
88  std::function<void (std::unique_ptr<ROSMessageType, ROSMessageDeleter>)>;
89  using UniquePtrWithInfoCallback =
90  std::function<void (
91  std::unique_ptr<SubscribedType, SubscribedMessageDeleter>,
92  const rclcpp::MessageInfo &)>;
93  using UniquePtrWithInfoROSMessageCallback =
94  std::function<void (
95  std::unique_ptr<ROSMessageType, ROSMessageDeleter>,
96  const rclcpp::MessageInfo &)>;
97  using UniquePtrSerializedMessageCallback =
98  std::function<void (std::unique_ptr<rclcpp::SerializedMessage, SerializedMessageDeleter>)>;
99  using UniquePtrSerializedMessageWithInfoCallback =
100  std::function<void (
101  std::unique_ptr<rclcpp::SerializedMessage, SerializedMessageDeleter>,
102  const rclcpp::MessageInfo &)>;
103 
104  using SharedConstPtrCallback =
105  std::function<void (std::shared_ptr<const SubscribedType>)>;
106  using SharedConstPtrROSMessageCallback =
107  std::function<void (std::shared_ptr<const ROSMessageType>)>;
108  using SharedConstPtrWithInfoCallback =
109  std::function<void (
110  std::shared_ptr<const SubscribedType>,
111  const rclcpp::MessageInfo &)>;
112  using SharedConstPtrWithInfoROSMessageCallback =
113  std::function<void (
114  std::shared_ptr<const ROSMessageType>,
115  const rclcpp::MessageInfo &)>;
116  using SharedConstPtrSerializedMessageCallback =
117  std::function<void (std::shared_ptr<const rclcpp::SerializedMessage>)>;
118  using SharedConstPtrSerializedMessageWithInfoCallback =
119  std::function<void (
120  std::shared_ptr<const rclcpp::SerializedMessage>,
121  const rclcpp::MessageInfo &)>;
122 
123  using ConstRefSharedConstPtrCallback =
124  std::function<void (const std::shared_ptr<const SubscribedType> &)>;
125  using ConstRefSharedConstPtrROSMessageCallback =
126  std::function<void (const std::shared_ptr<const ROSMessageType> &)>;
127  using ConstRefSharedConstPtrWithInfoCallback =
128  std::function<void (
129  const std::shared_ptr<const SubscribedType> &,
130  const rclcpp::MessageInfo &)>;
131  using ConstRefSharedConstPtrWithInfoROSMessageCallback =
132  std::function<void (
133  const std::shared_ptr<const ROSMessageType> &,
134  const rclcpp::MessageInfo &)>;
135  using ConstRefSharedConstPtrSerializedMessageCallback =
136  std::function<void (const std::shared_ptr<const rclcpp::SerializedMessage> &)>;
137  using ConstRefSharedConstPtrSerializedMessageWithInfoCallback =
138  std::function<void (
139  const std::shared_ptr<const rclcpp::SerializedMessage> &,
140  const rclcpp::MessageInfo &)>;
141 
142  // Deprecated signatures:
143  using SharedPtrCallback =
144  std::function<void (std::shared_ptr<SubscribedType>)>;
145  using SharedPtrROSMessageCallback =
146  std::function<void (std::shared_ptr<ROSMessageType>)>;
147  using SharedPtrWithInfoCallback =
148  std::function<void (std::shared_ptr<SubscribedType>, const rclcpp::MessageInfo &)>;
149  using SharedPtrWithInfoROSMessageCallback =
150  std::function<void (
151  std::shared_ptr<ROSMessageType>,
152  const rclcpp::MessageInfo &)>;
153  using SharedPtrSerializedMessageCallback =
154  std::function<void (std::shared_ptr<rclcpp::SerializedMessage>)>;
155  using SharedPtrSerializedMessageWithInfoCallback =
156  std::function<void (std::shared_ptr<rclcpp::SerializedMessage>, const rclcpp::MessageInfo &)>;
157 };
158 
160 template<
161  typename MessageT,
162  typename AllocatorT,
165 >
167 
169 template<typename MessageT, typename AllocatorT>
170 struct AnySubscriptionCallbackHelper<MessageT, AllocatorT, false, false>
171 {
173 
174  using variant_type = std::variant<
175  typename CallbackTypes::ConstRefCallback,
176  typename CallbackTypes::ConstRefWithInfoCallback,
177  typename CallbackTypes::ConstRefSerializedMessageCallback,
178  typename CallbackTypes::ConstRefSerializedMessageWithInfoCallback,
179  typename CallbackTypes::UniquePtrCallback,
180  typename CallbackTypes::UniquePtrWithInfoCallback,
181  typename CallbackTypes::UniquePtrSerializedMessageCallback,
182  typename CallbackTypes::UniquePtrSerializedMessageWithInfoCallback,
183  typename CallbackTypes::SharedConstPtrCallback,
184  typename CallbackTypes::SharedConstPtrWithInfoCallback,
185  typename CallbackTypes::SharedConstPtrSerializedMessageCallback,
186  typename CallbackTypes::SharedConstPtrSerializedMessageWithInfoCallback,
187  typename CallbackTypes::ConstRefSharedConstPtrCallback,
188  typename CallbackTypes::ConstRefSharedConstPtrWithInfoCallback,
189  typename CallbackTypes::ConstRefSharedConstPtrSerializedMessageCallback,
190  typename CallbackTypes::ConstRefSharedConstPtrSerializedMessageWithInfoCallback,
191  typename CallbackTypes::SharedPtrCallback,
192  typename CallbackTypes::SharedPtrWithInfoCallback,
193  typename CallbackTypes::SharedPtrSerializedMessageCallback,
194  typename CallbackTypes::SharedPtrSerializedMessageWithInfoCallback
195  >;
196 };
197 
199 template<typename MessageT, typename AllocatorT>
200 struct AnySubscriptionCallbackHelper<MessageT, AllocatorT, true, false>
201 {
203 
204  using variant_type = std::variant<
205  typename CallbackTypes::ConstRefCallback,
206  typename CallbackTypes::ConstRefROSMessageCallback,
207  typename CallbackTypes::ConstRefWithInfoCallback,
208  typename CallbackTypes::ConstRefWithInfoROSMessageCallback,
209  typename CallbackTypes::ConstRefSerializedMessageCallback,
210  typename CallbackTypes::ConstRefSerializedMessageWithInfoCallback,
211  typename CallbackTypes::UniquePtrCallback,
212  typename CallbackTypes::UniquePtrROSMessageCallback,
213  typename CallbackTypes::UniquePtrWithInfoCallback,
214  typename CallbackTypes::UniquePtrWithInfoROSMessageCallback,
215  typename CallbackTypes::UniquePtrSerializedMessageCallback,
216  typename CallbackTypes::UniquePtrSerializedMessageWithInfoCallback,
217  typename CallbackTypes::SharedConstPtrCallback,
218  typename CallbackTypes::SharedConstPtrROSMessageCallback,
219  typename CallbackTypes::SharedConstPtrWithInfoCallback,
220  typename CallbackTypes::SharedConstPtrWithInfoROSMessageCallback,
221  typename CallbackTypes::SharedConstPtrSerializedMessageCallback,
222  typename CallbackTypes::SharedConstPtrSerializedMessageWithInfoCallback,
223  typename CallbackTypes::ConstRefSharedConstPtrCallback,
224  typename CallbackTypes::ConstRefSharedConstPtrROSMessageCallback,
225  typename CallbackTypes::ConstRefSharedConstPtrWithInfoCallback,
226  typename CallbackTypes::ConstRefSharedConstPtrWithInfoROSMessageCallback,
227  typename CallbackTypes::ConstRefSharedConstPtrSerializedMessageCallback,
228  typename CallbackTypes::ConstRefSharedConstPtrSerializedMessageWithInfoCallback,
229  typename CallbackTypes::SharedPtrCallback,
230  typename CallbackTypes::SharedPtrROSMessageCallback,
231  typename CallbackTypes::SharedPtrWithInfoCallback,
232  typename CallbackTypes::SharedPtrWithInfoROSMessageCallback,
233  typename CallbackTypes::SharedPtrSerializedMessageCallback,
234  typename CallbackTypes::SharedPtrSerializedMessageWithInfoCallback
235  >;
236 };
237 
239 template<typename MessageT, typename AllocatorT>
240 struct AnySubscriptionCallbackHelper<MessageT, AllocatorT, false, true>
241 {
243 
244  using variant_type = std::variant<
245  typename CallbackTypes::ConstRefSerializedMessageCallback,
246  typename CallbackTypes::ConstRefSerializedMessageWithInfoCallback,
247  typename CallbackTypes::UniquePtrSerializedMessageCallback,
248  typename CallbackTypes::UniquePtrSerializedMessageWithInfoCallback,
249  typename CallbackTypes::SharedConstPtrSerializedMessageCallback,
250  typename CallbackTypes::SharedConstPtrSerializedMessageWithInfoCallback,
251  typename CallbackTypes::ConstRefSharedConstPtrSerializedMessageCallback,
252  typename CallbackTypes::ConstRefSharedConstPtrSerializedMessageWithInfoCallback,
253  typename CallbackTypes::SharedPtrSerializedMessageCallback,
254  typename CallbackTypes::SharedPtrSerializedMessageWithInfoCallback
255  >;
256 };
257 
258 } // namespace detail
259 
260 template<
261  typename MessageT,
262  typename AllocatorT = std::allocator<void>
263 >
265 {
266 private:
268  using SubscribedType = typename rclcpp::TypeAdapter<MessageT>::custom_type;
270  using ROSMessageType = typename rclcpp::TypeAdapter<MessageT>::ros_message_type;
271 
273 
276  using SubscribedTypeAllocatorTraits = typename SubscribedTypeDeleterHelper::AllocTraits;
277  using SubscribedTypeAllocator = typename SubscribedTypeDeleterHelper::Alloc;
278  using SubscribedTypeDeleter = typename SubscribedTypeDeleterHelper::Deleter;
279 
282  using ROSMessageTypeAllocatorTraits = typename ROSMessageTypeDeleterHelper::AllocTraits;
283  using ROSMessageTypeAllocator = typename ROSMessageTypeDeleterHelper::Alloc;
284  using ROSMessageTypeDeleter = typename ROSMessageTypeDeleterHelper::Deleter;
285 
288  using SerializedMessageAllocatorTraits = typename SerializedMessageDeleterHelper::AllocTraits;
289  using SerializedMessageAllocator = typename SerializedMessageDeleterHelper::Alloc;
290  using SerializedMessageDeleter = typename SerializedMessageDeleterHelper::Deleter;
291 
292  // See AnySubscriptionCallbackPossibleTypes for the types of these.
294 
295  using ConstRefCallback =
296  typename CallbackTypes::ConstRefCallback;
297  using ConstRefROSMessageCallback =
298  typename CallbackTypes::ConstRefROSMessageCallback;
299  using ConstRefWithInfoCallback =
300  typename CallbackTypes::ConstRefWithInfoCallback;
301  using ConstRefWithInfoROSMessageCallback =
302  typename CallbackTypes::ConstRefWithInfoROSMessageCallback;
303  using ConstRefSerializedMessageCallback =
304  typename CallbackTypes::ConstRefSerializedMessageCallback;
305  using ConstRefSerializedMessageWithInfoCallback =
306  typename CallbackTypes::ConstRefSerializedMessageWithInfoCallback;
307  using UniquePtrCallback =
308  typename CallbackTypes::UniquePtrCallback;
309  using UniquePtrROSMessageCallback =
310  typename CallbackTypes::UniquePtrROSMessageCallback;
311  using UniquePtrWithInfoCallback =
312  typename CallbackTypes::UniquePtrWithInfoCallback;
313  using UniquePtrWithInfoROSMessageCallback =
314  typename CallbackTypes::UniquePtrWithInfoROSMessageCallback;
315  using UniquePtrSerializedMessageCallback =
316  typename CallbackTypes::UniquePtrSerializedMessageCallback;
317  using UniquePtrSerializedMessageWithInfoCallback =
318  typename CallbackTypes::UniquePtrSerializedMessageWithInfoCallback;
319  using SharedConstPtrCallback =
320  typename CallbackTypes::SharedConstPtrCallback;
321  using SharedConstPtrROSMessageCallback =
322  typename CallbackTypes::SharedConstPtrROSMessageCallback;
323  using SharedConstPtrWithInfoCallback =
324  typename CallbackTypes::SharedConstPtrWithInfoCallback;
325  using SharedConstPtrWithInfoROSMessageCallback =
326  typename CallbackTypes::SharedConstPtrWithInfoROSMessageCallback;
327  using SharedConstPtrSerializedMessageCallback =
328  typename CallbackTypes::SharedConstPtrSerializedMessageCallback;
329  using SharedConstPtrSerializedMessageWithInfoCallback =
330  typename CallbackTypes::SharedConstPtrSerializedMessageWithInfoCallback;
331  using ConstRefSharedConstPtrCallback =
332  typename CallbackTypes::ConstRefSharedConstPtrCallback;
333  using ConstRefSharedConstPtrROSMessageCallback =
334  typename CallbackTypes::ConstRefSharedConstPtrROSMessageCallback;
335  using ConstRefSharedConstPtrWithInfoCallback =
336  typename CallbackTypes::ConstRefSharedConstPtrWithInfoCallback;
337  using ConstRefSharedConstPtrWithInfoROSMessageCallback =
338  typename CallbackTypes::ConstRefSharedConstPtrWithInfoROSMessageCallback;
339  using ConstRefSharedConstPtrSerializedMessageCallback =
340  typename CallbackTypes::ConstRefSharedConstPtrSerializedMessageCallback;
341  using ConstRefSharedConstPtrSerializedMessageWithInfoCallback =
342  typename CallbackTypes::ConstRefSharedConstPtrSerializedMessageWithInfoCallback;
343  using SharedPtrCallback =
344  typename CallbackTypes::SharedPtrCallback;
345  using SharedPtrROSMessageCallback =
346  typename CallbackTypes::SharedPtrROSMessageCallback;
347  using SharedPtrWithInfoCallback =
348  typename CallbackTypes::SharedPtrWithInfoCallback;
349  using SharedPtrWithInfoROSMessageCallback =
350  typename CallbackTypes::SharedPtrWithInfoROSMessageCallback;
351  using SharedPtrSerializedMessageCallback =
352  typename CallbackTypes::SharedPtrSerializedMessageCallback;
353  using SharedPtrSerializedMessageWithInfoCallback =
354  typename CallbackTypes::SharedPtrSerializedMessageWithInfoCallback;
355 
356  template<typename T>
357  struct NotNull
358  {
359  NotNull(const T * pointer_in, const char * msg)
360  : pointer(pointer_in)
361  {
362  if (pointer == nullptr) {
363  throw std::invalid_argument(msg);
364  }
365  }
366 
367  const T * pointer;
368  };
369 
370 public:
371  explicit
372  AnySubscriptionCallback(const AllocatorT & allocator = AllocatorT()) // NOLINT[runtime/explicit]
373  : subscribed_type_allocator_(allocator),
374  ros_message_type_allocator_(allocator)
375  {
376  allocator::set_allocator_for_deleter(&subscribed_type_deleter_, &subscribed_type_allocator_);
377  allocator::set_allocator_for_deleter(&ros_message_type_deleter_, &ros_message_type_allocator_);
378  }
379 
381  : callback_variant_(other.callback_variant_),
382  callback_disabled_(other.callback_disabled_.load()),
383  subscribed_type_allocator_(other.subscribed_type_allocator_),
384  subscribed_type_deleter_(other.subscribed_type_deleter_),
385  ros_message_type_allocator_(other.ros_message_type_allocator_),
386  ros_message_type_deleter_(other.ros_message_type_deleter_),
387  serialized_message_allocator_(other.serialized_message_allocator_),
388  serialized_message_deleter_(other.serialized_message_deleter_)
389  {
390  allocator::set_allocator_for_deleter(&subscribed_type_deleter_, &subscribed_type_allocator_);
391  allocator::set_allocator_for_deleter(&ros_message_type_deleter_, &ros_message_type_allocator_);
392  }
393 
395 
400  template<typename CallbackT>
402  set(CallbackT callback)
403  {
404  // Use the SubscriptionCallbackTypeHelper to determine the actual type of
405  // the CallbackT, in terms of std::function<...>, which does not happen
406  // automatically with lambda functions in cases where the arguments can be
407  // converted to one another, e.g. shared_ptr and unique_ptr.
409 
410  // Determine if the given CallbackT is a deprecated signature or not.
411  constexpr auto is_deprecated =
413  typename scbth::callback_type,
414  std::function<void(std::shared_ptr<SubscribedType>)>
415  >::value ||
417  typename scbth::callback_type,
418  std::function<void(std::shared_ptr<SubscribedType>, const rclcpp::MessageInfo &)>
419  >::value ||
421  typename scbth::callback_type,
422  std::function<void(std::shared_ptr<ROSMessageType>)>
423  >::value ||
425  typename scbth::callback_type,
426  std::function<void(std::shared_ptr<ROSMessageType>, const rclcpp::MessageInfo &)>
427  >::value ||
429  typename scbth::callback_type,
430  std::function<void(std::shared_ptr<rclcpp::SerializedMessage>)>
431  >::value ||
433  typename scbth::callback_type,
434  std::function<void(std::shared_ptr<rclcpp::SerializedMessage>, const rclcpp::MessageInfo &)>
435  >::value;
436 
437  // Use the discovered type to force the type of callback when assigning
438  // into the variant.
439  if constexpr (is_deprecated) {
440  // If deprecated, call sub-routine that is deprecated.
441  set_deprecated(static_cast<typename scbth::callback_type>(callback));
442  } else {
443  // Otherwise just assign it.
444  callback_variant_ = static_cast<typename scbth::callback_type>(callback);
445  }
446 
447  // Return copy of self for easier testing, normally will be compiled out.
448  return *this;
449  }
450 
452  template<typename SetT>
453  // *INDENT-OFF*
454  #if !defined(RCLCPP_AVOID_DEPRECATIONS_FOR_UNIT_TESTS)
455  // suppress deprecation warnings in `test_any_subscription_callback.cpp`
456  [[deprecated("use 'void(std::shared_ptr<const MessageT>)' instead")]]
457  #endif
458  // *INDENT-ON*
459  void
460  set_deprecated(std::function<void(std::shared_ptr<SetT>)> callback)
461  {
462  callback_variant_ = callback;
463  }
464 
466  template<typename SetT>
467  // *INDENT-OFF*
468  #if !defined(RCLCPP_AVOID_DEPRECATIONS_FOR_UNIT_TESTS)
469  // suppress deprecation warnings in `test_any_subscription_callback.cpp`
470  [[deprecated(
471  "use 'void(std::shared_ptr<const MessageT>, const rclcpp::MessageInfo &)' instead"
472  )]]
473  #endif
474  // *INDENT-ON*
475  void
476  set_deprecated(std::function<void(std::shared_ptr<SetT>, const rclcpp::MessageInfo &)> callback)
477  {
478  callback_variant_ = callback;
479  }
480 
482  void disable()
483  {
484  std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
485  callback_disabled_.store(true);
486  }
487 
489  void enable()
490  {
491  std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
492  callback_disabled_.store(false);
493  }
494 
495  std::unique_ptr<ROSMessageType, ROSMessageTypeDeleter>
496  create_ros_unique_ptr_from_ros_shared_ptr_message(
497  const std::shared_ptr<const ROSMessageType> & message)
498  {
499  auto ptr = ROSMessageTypeAllocatorTraits::allocate(ros_message_type_allocator_, 1);
500  ROSMessageTypeAllocatorTraits::construct(ros_message_type_allocator_, ptr, *message);
501  return std::unique_ptr<ROSMessageType, ROSMessageTypeDeleter>(ptr, ros_message_type_deleter_);
502  }
503 
504  std::unique_ptr<rclcpp::SerializedMessage, SerializedMessageDeleter>
505  create_serialized_message_unique_ptr_from_shared_ptr(
506  const std::shared_ptr<const rclcpp::SerializedMessage> & serialized_message)
507  {
508  auto ptr = SerializedMessageAllocatorTraits::allocate(serialized_message_allocator_, 1);
509  SerializedMessageAllocatorTraits::construct(
510  serialized_message_allocator_, ptr, *serialized_message);
511  return std::unique_ptr<
513  SerializedMessageDeleter
514  >(ptr, serialized_message_deleter_);
515  }
516 
517  std::unique_ptr<SubscribedType, SubscribedTypeDeleter>
518  create_custom_unique_ptr_from_custom_shared_ptr_message(
519  const std::shared_ptr<const SubscribedType> & message)
520  {
521  auto ptr = SubscribedTypeAllocatorTraits::allocate(subscribed_type_allocator_, 1);
522  SubscribedTypeAllocatorTraits::construct(subscribed_type_allocator_, ptr, *message);
523  return std::unique_ptr<SubscribedType, SubscribedTypeDeleter>(ptr, subscribed_type_deleter_);
524  }
525 
526  std::unique_ptr<SubscribedType, SubscribedTypeDeleter>
527  convert_ros_message_to_custom_type_unique_ptr(const ROSMessageType & msg)
528  {
530  auto ptr = SubscribedTypeAllocatorTraits::allocate(subscribed_type_allocator_, 1);
531  SubscribedTypeAllocatorTraits::construct(subscribed_type_allocator_, ptr);
533  return std::unique_ptr<SubscribedType, SubscribedTypeDeleter>(ptr, subscribed_type_deleter_);
534  } else {
535  throw std::runtime_error(
536  "convert_ros_message_to_custom_type_unique_ptr "
537  "unexpectedly called without TypeAdapter");
538  }
539  }
540 
541  std::unique_ptr<ROSMessageType, ROSMessageTypeDeleter>
542  convert_custom_type_to_ros_message_unique_ptr(const SubscribedType & msg)
543  {
545  auto ptr = ROSMessageTypeAllocatorTraits::allocate(ros_message_type_allocator_, 1);
546  ROSMessageTypeAllocatorTraits::construct(ros_message_type_allocator_, ptr);
548  return std::unique_ptr<ROSMessageType, ROSMessageTypeDeleter>(ptr, ros_message_type_deleter_);
549  } else {
550  static_assert(
551  !sizeof(MessageT *),
552  "convert_custom_type_to_ros_message_unique_ptr() "
553  "unexpectedly called without specialized TypeAdapter");
554  }
555  }
556 
557  // Dispatch when input is a ros message and the output could be anything.
558  template<typename TMsg = ROSMessageType>
559  typename std::enable_if<!serialization_traits::is_serialized_message_class<TMsg>::value,
560  void>::type
561  dispatch(
562  std::shared_ptr<ROSMessageType> message,
563  const rclcpp::MessageInfo & message_info)
564  {
565  std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
566  if (callback_disabled_.load()) {
567  return;
568  }
569  TRACETOOLS_TRACEPOINT(callback_start, static_cast<const void *>(this), false);
570  // Check if the variant is "unset", throw if it is.
571  if (callback_variant_.index() == 0) {
572  if (std::get<0>(callback_variant_) == nullptr) {
573  // This can happen if it is default initialized, or if it is assigned nullptr.
574  throw std::runtime_error("dispatch called on an unset AnySubscriptionCallback");
575  }
576  }
577  // Dispatch.
578  std::visit(
579  [&message, &message_info, this](auto && callback) {
580  using T = std::decay_t<decltype(callback)>;
581  static constexpr bool is_ta = rclcpp::TypeAdapter<MessageT>::is_specialized::value;
582 
583  // conditions for output is custom message
584  if constexpr (is_ta && std::is_same_v<T, ConstRefCallback>) {
585  // TODO(wjwwood): consider avoiding heap allocation for small messages
586  // maybe something like:
587  // if constexpr (rosidl_generator_traits::has_fixed_size<T> && sizeof(T) < N) {
588  // ... on stack
589  // }
590  auto local_message = convert_ros_message_to_custom_type_unique_ptr(*message);
591  callback(*local_message);
592  } else if constexpr (is_ta && std::is_same_v<T, ConstRefWithInfoCallback>) { // NOLINT
593  auto local_message = convert_ros_message_to_custom_type_unique_ptr(*message);
594  callback(*local_message, message_info);
595  } else if constexpr (is_ta && std::is_same_v<T, UniquePtrCallback>) {
596  callback(convert_ros_message_to_custom_type_unique_ptr(*message));
597  } else if constexpr (is_ta && std::is_same_v<T, UniquePtrWithInfoCallback>) {
598  callback(convert_ros_message_to_custom_type_unique_ptr(*message), message_info);
599  } else if constexpr ( // NOLINT[readability/braces]
600  is_ta && (
601  std::is_same_v<T, SharedConstPtrCallback>||
602  std::is_same_v<T, ConstRefSharedConstPtrCallback>||
603  std::is_same_v<T, SharedPtrCallback>
604  ))
605  {
606  callback(convert_ros_message_to_custom_type_unique_ptr(*message));
607  } else if constexpr ( // NOLINT[readability/braces]
608  is_ta && (
609  std::is_same_v<T, SharedConstPtrWithInfoCallback>||
610  std::is_same_v<T, ConstRefSharedConstPtrWithInfoCallback>||
611  std::is_same_v<T, SharedPtrWithInfoCallback>
612  ))
613  {
614  callback(convert_ros_message_to_custom_type_unique_ptr(*message), message_info);
615  }
616  // conditions for output is ros message
617  else if constexpr (std::is_same_v<T, ConstRefROSMessageCallback>) { // NOLINT
618  callback(*message);
619  } else if constexpr (std::is_same_v<T, ConstRefWithInfoROSMessageCallback>) {
620  callback(*message, message_info);
621  } else if constexpr (std::is_same_v<T, UniquePtrROSMessageCallback>) {
622  callback(create_ros_unique_ptr_from_ros_shared_ptr_message(message));
623  } else if constexpr (std::is_same_v<T, UniquePtrWithInfoROSMessageCallback>) {
624  callback(create_ros_unique_ptr_from_ros_shared_ptr_message(message), message_info);
625  } else if constexpr ( // NOLINT[readability/braces]
626  std::is_same_v<T, SharedConstPtrROSMessageCallback>||
627  std::is_same_v<T, ConstRefSharedConstPtrROSMessageCallback>||
628  std::is_same_v<T, SharedPtrROSMessageCallback>)
629  {
630  callback(message);
631  } else if constexpr ( // NOLINT[readability/braces]
632  std::is_same_v<T, SharedConstPtrWithInfoROSMessageCallback>||
633  std::is_same_v<T, ConstRefSharedConstPtrWithInfoROSMessageCallback>||
634  std::is_same_v<T, SharedPtrWithInfoROSMessageCallback>)
635  {
636  callback(message, message_info);
637  }
638  // condition to catch SerializedMessage types
639  else if constexpr ( // NOLINT[readability/braces]
640  std::is_same_v<T, ConstRefSerializedMessageCallback>||
641  std::is_same_v<T, ConstRefSerializedMessageWithInfoCallback>||
642  std::is_same_v<T, UniquePtrSerializedMessageCallback>||
643  std::is_same_v<T, UniquePtrSerializedMessageWithInfoCallback>||
644  std::is_same_v<T, SharedConstPtrSerializedMessageCallback>||
645  std::is_same_v<T, SharedConstPtrSerializedMessageWithInfoCallback>||
646  std::is_same_v<T, ConstRefSharedConstPtrSerializedMessageCallback>||
647  std::is_same_v<T, ConstRefSharedConstPtrSerializedMessageWithInfoCallback>||
648  std::is_same_v<T, SharedPtrSerializedMessageCallback>||
649  std::is_same_v<T, SharedPtrSerializedMessageWithInfoCallback>)
650  {
651  throw std::runtime_error(
652  "Cannot dispatch std::shared_ptr<ROSMessageType> message "
653  "to rclcpp::SerializedMessage");
654  }
655  // condition to catch unhandled callback types
656  else { // NOLINT[readability/braces]
657  static_assert(detail::always_false_v<T>, "unhandled callback type");
658  }
659  }, callback_variant_);
660  TRACETOOLS_TRACEPOINT(callback_end, static_cast<const void *>(this));
661  }
662 
663  // Dispatch when input is a serialized message and the output could be anything.
664  void
665  dispatch(
666  std::shared_ptr<const rclcpp::SerializedMessage> serialized_message,
667  const rclcpp::MessageInfo & message_info)
668  {
669  std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
670  if (callback_disabled_.load()) {
671  return;
672  }
673  TRACETOOLS_TRACEPOINT(callback_start, static_cast<const void *>(this), false);
674  // Check if the variant is "unset", throw if it is.
675  if (callback_variant_.index() == 0) {
676  if (std::get<0>(callback_variant_) == nullptr) {
677  // This can happen if it is default initialized, or if it is assigned nullptr.
678  throw std::runtime_error("dispatch called on an unset AnySubscriptionCallback");
679  }
680  }
681  // Dispatch.
682  std::visit(
683  [&serialized_message, &message_info, this](auto && callback) {
684  using T = std::decay_t<decltype(callback)>;
685 
686  // condition to catch SerializedMessage types
687  if constexpr (std::is_same_v<T, ConstRefSerializedMessageCallback>) {
688  callback(*serialized_message);
689  } else if constexpr (std::is_same_v<T, ConstRefSerializedMessageWithInfoCallback>) {
690  callback(*serialized_message, message_info);
691  } else if constexpr (std::is_same_v<T, UniquePtrSerializedMessageCallback>) {
692  callback(create_serialized_message_unique_ptr_from_shared_ptr(serialized_message));
693  } else if constexpr (std::is_same_v<T, UniquePtrSerializedMessageWithInfoCallback>) {
694  callback(
695  create_serialized_message_unique_ptr_from_shared_ptr(serialized_message),
696  message_info);
697  } else if constexpr ( // NOLINT[readability/braces]
698  std::is_same_v<T, SharedConstPtrSerializedMessageCallback>||
699  std::is_same_v<T, ConstRefSharedConstPtrSerializedMessageCallback>||
700  std::is_same_v<T, SharedPtrSerializedMessageCallback>)
701  {
702  callback(create_serialized_message_unique_ptr_from_shared_ptr(serialized_message));
703  } else if constexpr ( // NOLINT[readability/braces]
704  std::is_same_v<T, SharedConstPtrSerializedMessageWithInfoCallback>||
705  std::is_same_v<T, ConstRefSharedConstPtrSerializedMessageWithInfoCallback>||
706  std::is_same_v<T, SharedPtrSerializedMessageWithInfoCallback>)
707  {
708  callback(
709  create_serialized_message_unique_ptr_from_shared_ptr(serialized_message),
710  message_info);
711  }
712  // conditions for output anything else
713  else if constexpr ( // NOLINT[whitespace/newline]
714  std::is_same_v<T, ConstRefCallback>||
715  std::is_same_v<T, ConstRefROSMessageCallback>||
716  std::is_same_v<T, ConstRefWithInfoCallback>||
717  std::is_same_v<T, ConstRefWithInfoROSMessageCallback>||
718  std::is_same_v<T, UniquePtrCallback>||
719  std::is_same_v<T, UniquePtrROSMessageCallback>||
720  std::is_same_v<T, UniquePtrWithInfoCallback>||
721  std::is_same_v<T, UniquePtrWithInfoROSMessageCallback>||
722  std::is_same_v<T, SharedConstPtrCallback>||
723  std::is_same_v<T, SharedConstPtrROSMessageCallback>||
724  std::is_same_v<T, SharedConstPtrWithInfoCallback>||
725  std::is_same_v<T, SharedConstPtrWithInfoROSMessageCallback>||
726  std::is_same_v<T, ConstRefSharedConstPtrCallback>||
727  std::is_same_v<T, ConstRefSharedConstPtrROSMessageCallback>||
728  std::is_same_v<T, ConstRefSharedConstPtrWithInfoCallback>||
729  std::is_same_v<T, ConstRefSharedConstPtrWithInfoROSMessageCallback>||
730  std::is_same_v<T, SharedPtrCallback>||
731  std::is_same_v<T, SharedPtrROSMessageCallback>||
732  std::is_same_v<T, SharedPtrWithInfoCallback>||
733  std::is_same_v<T, SharedPtrWithInfoROSMessageCallback>)
734  {
735  throw std::runtime_error(
736  "cannot dispatch rclcpp::SerializedMessage to "
737  "non-rclcpp::SerializedMessage callbacks");
738  }
739  // condition to catch unhandled callback types
740  else { // NOLINT[readability/braces]
741  static_assert(detail::always_false_v<T>, "unhandled callback type");
742  }
743  }, callback_variant_);
744  TRACETOOLS_TRACEPOINT(callback_end, static_cast<const void *>(this));
745  }
746 
747  void
748  dispatch_intra_process(
749  std::shared_ptr<const SubscribedType> message,
750  const rclcpp::MessageInfo & message_info)
751  {
752  std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
753  if (callback_disabled_.load()) {
754  return;
755  }
756  TRACETOOLS_TRACEPOINT(callback_start, static_cast<const void *>(this), true);
757  // Check if the variant is "unset", throw if it is.
758  if (callback_variant_.index() == 0) {
759  if (std::get<0>(callback_variant_) == nullptr) {
760  // This can happen if it is default initialized, or if it is assigned nullptr.
761  throw std::runtime_error("dispatch called on an unset AnySubscriptionCallback");
762  }
763  }
764  // Dispatch.
765  std::visit(
766  [&message, &message_info, this](auto && callback) {
767  using T = std::decay_t<decltype(callback)>;
768  static constexpr bool is_ta = rclcpp::TypeAdapter<MessageT>::is_specialized::value;
769 
770  // conditions for custom type
771  if constexpr (is_ta && std::is_same_v<T, ConstRefCallback>) {
772  callback(*message);
773  } else if constexpr (is_ta && std::is_same_v<T, ConstRefWithInfoCallback>) { // NOLINT
774  callback(*message, message_info);
775  } else if constexpr ( // NOLINT[readability/braces]
776  is_ta && (
777  std::is_same_v<T, UniquePtrCallback>||
778  std::is_same_v<T, SharedPtrCallback>
779  ))
780  {
781  callback(create_custom_unique_ptr_from_custom_shared_ptr_message(message));
782  } else if constexpr ( // NOLINT[readability/braces]
783  is_ta && (
784  std::is_same_v<T, UniquePtrWithInfoCallback>||
785  std::is_same_v<T, SharedPtrWithInfoCallback>
786  ))
787  {
788  callback(create_custom_unique_ptr_from_custom_shared_ptr_message(message), message_info);
789  } else if constexpr ( // NOLINT[readability/braces]
790  is_ta && (
791  std::is_same_v<T, SharedConstPtrCallback>||
792  std::is_same_v<T, ConstRefSharedConstPtrCallback>
793  ))
794  {
795  callback(message);
796  } else if constexpr ( // NOLINT[readability/braces]
797  is_ta && (
798  std::is_same_v<T, SharedConstPtrWithInfoCallback>||
799  std::is_same_v<T, ConstRefSharedConstPtrWithInfoCallback>
800  ))
801  {
802  callback(message, message_info);
803  }
804  // conditions for ros message type
805  else if constexpr (std::is_same_v<T, ConstRefROSMessageCallback>) { // NOLINT[readability/braces]
806  if constexpr (is_ta) {
807  auto local = convert_custom_type_to_ros_message_unique_ptr(*message);
808  callback(*local);
809  } else {
810  callback(*message);
811  }
812  } else if constexpr (std::is_same_v<T, ConstRefWithInfoROSMessageCallback>) { // NOLINT[readability/braces]
813  if constexpr (is_ta) {
814  auto local = convert_custom_type_to_ros_message_unique_ptr(*message);
815  callback(*local, message_info);
816  } else {
817  callback(*message, message_info);
818  }
819  } else if constexpr ( // NOLINT[readability/braces]
820  std::is_same_v<T, UniquePtrROSMessageCallback>||
821  std::is_same_v<T, SharedPtrROSMessageCallback>)
822  {
823  if constexpr (is_ta) {
824  callback(convert_custom_type_to_ros_message_unique_ptr(*message));
825  } else {
826  callback(create_ros_unique_ptr_from_ros_shared_ptr_message(message));
827  }
828  } else if constexpr ( // NOLINT[readability/braces]
829  std::is_same_v<T, UniquePtrWithInfoROSMessageCallback>||
830  std::is_same_v<T, SharedPtrWithInfoROSMessageCallback>)
831  {
832  if constexpr (is_ta) {
833  callback(convert_custom_type_to_ros_message_unique_ptr(*message), message_info);
834  } else {
835  callback(create_ros_unique_ptr_from_ros_shared_ptr_message(message), message_info);
836  }
837  } else if constexpr ( // NOLINT[readability/braces]
838  std::is_same_v<T, SharedConstPtrROSMessageCallback>||
839  std::is_same_v<T, ConstRefSharedConstPtrROSMessageCallback>)
840  {
841  if constexpr (is_ta) {
842  callback(convert_custom_type_to_ros_message_unique_ptr(*message));
843  } else {
844  callback(message);
845  }
846  } else if constexpr ( // NOLINT[readability/braces]
847  std::is_same_v<T, SharedConstPtrWithInfoROSMessageCallback>||
848  std::is_same_v<T, ConstRefSharedConstPtrWithInfoROSMessageCallback>)
849  {
850  if constexpr (is_ta) {
851  callback(convert_custom_type_to_ros_message_unique_ptr(*message), message_info);
852  } else {
853  callback(message, message_info);
854  }
855  }
856  // condition to catch SerializedMessage types
857  else if constexpr ( // NOLINT[readability/braces]
858  std::is_same_v<T, ConstRefSerializedMessageCallback>||
859  std::is_same_v<T, ConstRefSerializedMessageWithInfoCallback>||
860  std::is_same_v<T, UniquePtrSerializedMessageCallback>||
861  std::is_same_v<T, UniquePtrSerializedMessageWithInfoCallback>||
862  std::is_same_v<T, SharedConstPtrSerializedMessageCallback>||
863  std::is_same_v<T, SharedConstPtrSerializedMessageWithInfoCallback>||
864  std::is_same_v<T, ConstRefSharedConstPtrSerializedMessageCallback>||
865  std::is_same_v<T, ConstRefSharedConstPtrSerializedMessageWithInfoCallback>||
866  std::is_same_v<T, SharedPtrSerializedMessageCallback>||
867  std::is_same_v<T, SharedPtrSerializedMessageWithInfoCallback>)
868  {
869  throw std::runtime_error(
870  "Cannot dispatch std::shared_ptr<const ROSMessageType> message "
871  "to rclcpp::SerializedMessage");
872  }
873  // condition to catch unhandled callback types
874  else { // NOLINT[readability/braces]
875  static_assert(detail::always_false_v<T>, "unhandled callback type");
876  }
877  }, callback_variant_);
878  TRACETOOLS_TRACEPOINT(callback_end, static_cast<const void *>(this));
879  }
880 
881  void
882  dispatch_intra_process(
883  std::unique_ptr<SubscribedType, SubscribedTypeDeleter> message,
884  const rclcpp::MessageInfo & message_info)
885  {
886  std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
887  if (callback_disabled_.load()) {
888  return;
889  }
890  TRACETOOLS_TRACEPOINT(callback_start, static_cast<const void *>(this), true);
891  // Check if the variant is "unset", throw if it is.
892  if (callback_variant_.index() == 0) {
893  if (std::get<0>(callback_variant_) == nullptr) {
894  // This can happen if it is default initialized, or if it is assigned nullptr.
895  throw std::runtime_error("dispatch called on an unset AnySubscriptionCallback");
896  }
897  }
898  // Dispatch.
899  std::visit(
900  [&message, &message_info, this](auto && callback) {
901  // clang complains that 'this' lambda capture is unused, which is true
902  // in *some* specializations of this template, but not others. Just
903  // quiet it down.
904  (void)this;
905 
906  using T = std::decay_t<decltype(callback)>;
907  static constexpr bool is_ta = rclcpp::TypeAdapter<MessageT>::is_specialized::value;
908 
909  // conditions for custom type
910  if constexpr (is_ta && std::is_same_v<T, ConstRefCallback>) {
911  callback(*message);
912  } else if constexpr (is_ta && std::is_same_v<T, ConstRefWithInfoCallback>) { // NOLINT
913  callback(*message, message_info);
914  } else if constexpr ( // NOLINT[readability/braces]
915  is_ta && (
916  std::is_same_v<T, UniquePtrCallback>||
917  std::is_same_v<T, SharedPtrCallback>))
918  {
919  callback(std::move(message));
920  } else if constexpr ( // NOLINT[readability/braces]
921  is_ta && (
922  std::is_same_v<T, UniquePtrWithInfoCallback>||
923  std::is_same_v<T, SharedPtrWithInfoCallback>
924  ))
925  {
926  callback(std::move(message), message_info);
927  } else if constexpr ( // NOLINT[readability/braces]
928  is_ta && (
929  std::is_same_v<T, SharedConstPtrCallback>||
930  std::is_same_v<T, ConstRefSharedConstPtrCallback>
931  ))
932  {
933  callback(std::move(message));
934  } else if constexpr ( // NOLINT[readability/braces]
935  is_ta && (
936  std::is_same_v<T, SharedConstPtrWithInfoCallback>||
937  std::is_same_v<T, ConstRefSharedConstPtrWithInfoCallback>
938  ))
939  {
940  callback(std::move(message), message_info);
941  }
942  // conditions for ros message type
943  else if constexpr (std::is_same_v<T, ConstRefROSMessageCallback>) { // NOLINT[readability/braces]
944  if constexpr (is_ta) {
945  auto local = convert_custom_type_to_ros_message_unique_ptr(*message);
946  callback(*local);
947  } else {
948  callback(*message);
949  }
950  } else if constexpr (std::is_same_v<T, ConstRefWithInfoROSMessageCallback>) { // NOLINT[readability/braces]
951  if constexpr (is_ta) {
952  auto local = convert_custom_type_to_ros_message_unique_ptr(*message);
953  callback(*local, message_info);
954  } else {
955  callback(*message, message_info);
956  }
957  } else if constexpr ( // NOLINT[readability/braces]
958  std::is_same_v<T, UniquePtrROSMessageCallback>||
959  std::is_same_v<T, SharedPtrROSMessageCallback>)
960  {
961  if constexpr (is_ta) {
962  callback(convert_custom_type_to_ros_message_unique_ptr(*message));
963  } else {
964  callback(std::move(message));
965  }
966  } else if constexpr ( // NOLINT[readability/braces]
967  std::is_same_v<T, UniquePtrWithInfoROSMessageCallback>||
968  std::is_same_v<T, SharedPtrWithInfoROSMessageCallback>)
969  {
970  if constexpr (is_ta) {
971  callback(convert_custom_type_to_ros_message_unique_ptr(*message), message_info);
972  } else {
973  callback(std::move(message), message_info);
974  }
975  } else if constexpr ( // NOLINT[readability/braces]
976  std::is_same_v<T, SharedConstPtrROSMessageCallback>||
977  std::is_same_v<T, ConstRefSharedConstPtrROSMessageCallback>)
978  {
979  if constexpr (is_ta) {
980  callback(convert_custom_type_to_ros_message_unique_ptr(*message));
981  } else {
982  callback(std::move(message));
983  }
984  } else if constexpr ( // NOLINT[readability/braces]
985  std::is_same_v<T, SharedConstPtrWithInfoROSMessageCallback>||
986  std::is_same_v<T, ConstRefSharedConstPtrWithInfoROSMessageCallback>)
987  {
988  if constexpr (is_ta) {
989  callback(convert_custom_type_to_ros_message_unique_ptr(*message), message_info);
990  } else {
991  callback(std::move(message), message_info);
992  }
993  }
994  // condition to catch SerializedMessage types
995  else if constexpr ( // NOLINT[readability/braces]
996  std::is_same_v<T, ConstRefSerializedMessageCallback>||
997  std::is_same_v<T, ConstRefSerializedMessageWithInfoCallback>||
998  std::is_same_v<T, UniquePtrSerializedMessageCallback>||
999  std::is_same_v<T, UniquePtrSerializedMessageWithInfoCallback>||
1000  std::is_same_v<T, SharedConstPtrSerializedMessageCallback>||
1001  std::is_same_v<T, SharedConstPtrSerializedMessageWithInfoCallback>||
1002  std::is_same_v<T, ConstRefSharedConstPtrSerializedMessageCallback>||
1003  std::is_same_v<T, ConstRefSharedConstPtrSerializedMessageWithInfoCallback>||
1004  std::is_same_v<T, SharedPtrSerializedMessageCallback>||
1005  std::is_same_v<T, SharedPtrSerializedMessageWithInfoCallback>)
1006  {
1007  throw std::runtime_error(
1008  "Cannot dispatch std::unique_ptr<ROSMessageType, ROSMessageTypeDeleter> message "
1009  "to rclcpp::SerializedMessage");
1010  }
1011  // condition to catch unhandled callback types
1012  else { // NOLINT[readability/braces]
1013  static_assert(detail::always_false_v<T>, "unhandled callback type");
1014  }
1015  }, callback_variant_);
1016  TRACETOOLS_TRACEPOINT(callback_end, static_cast<const void *>(this));
1017  }
1018 
1019  constexpr
1020  bool
1021  use_take_shared_method() const
1022  {
1023  return
1024  std::holds_alternative<SharedConstPtrCallback>(callback_variant_) ||
1025  std::holds_alternative<SharedConstPtrWithInfoCallback>(callback_variant_) ||
1026  std::holds_alternative<ConstRefSharedConstPtrCallback>(callback_variant_) ||
1027  std::holds_alternative<ConstRefSharedConstPtrWithInfoCallback>(callback_variant_) ||
1028  std::holds_alternative<ConstRefCallback>(callback_variant_) ||
1029  std::holds_alternative<ConstRefWithInfoCallback>(callback_variant_);
1030  }
1031 
1032  constexpr
1033  bool
1034  is_serialized_message_callback() const
1035  {
1036  return
1037  std::holds_alternative<ConstRefSerializedMessageCallback>(callback_variant_) ||
1038  std::holds_alternative<UniquePtrSerializedMessageCallback>(callback_variant_) ||
1039  std::holds_alternative<SharedConstPtrSerializedMessageCallback>(callback_variant_) ||
1040  std::holds_alternative<ConstRefSharedConstPtrSerializedMessageCallback>(callback_variant_) ||
1041  std::holds_alternative<SharedPtrSerializedMessageCallback>(callback_variant_) ||
1042  std::holds_alternative<ConstRefSerializedMessageWithInfoCallback>(callback_variant_) ||
1043  std::holds_alternative<UniquePtrSerializedMessageWithInfoCallback>(callback_variant_) ||
1044  std::holds_alternative<SharedConstPtrSerializedMessageWithInfoCallback>(callback_variant_) ||
1045  std::holds_alternative<ConstRefSharedConstPtrSerializedMessageWithInfoCallback>(
1046  callback_variant_) ||
1047  std::holds_alternative<SharedPtrSerializedMessageWithInfoCallback>(callback_variant_);
1048  }
1049 
1050  void
1051  register_callback_for_tracing()
1052  {
1053 #ifndef TRACETOOLS_DISABLED
1054  std::visit(
1055  [this](auto && callback) {
1056  if (TRACETOOLS_TRACEPOINT_ENABLED(rclcpp_callback_register)) {
1057  char * symbol = tracetools::get_symbol(callback);
1058  TRACETOOLS_DO_TRACEPOINT(
1059  rclcpp_callback_register,
1060  static_cast<const void *>(this),
1061  symbol);
1062  std::free(symbol);
1063  }
1064  }, callback_variant_);
1065 #endif // TRACETOOLS_DISABLED
1066  }
1067 
1068  typename HelperT::variant_type &
1069  get_variant()
1070  {
1071  return callback_variant_;
1072  }
1073 
1074  const typename HelperT::variant_type &
1075  get_variant() const
1076  {
1077  return callback_variant_;
1078  }
1079 
1080 private:
1081  // TODO(wjwwood): switch to inheriting from std::variant (i.e. HelperT::variant_type) once
1082  // inheriting from std::variant is realistic (maybe C++23?), see:
1083  // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2162r0.html
1084  // For now, compose the variant into this class as a private attribute.
1085  typename HelperT::variant_type callback_variant_;
1086  std::recursive_mutex callback_mutex_;
1087  std::atomic_bool callback_disabled_{false};
1088 
1089  SubscribedTypeAllocator subscribed_type_allocator_;
1090  SubscribedTypeDeleter subscribed_type_deleter_;
1091  ROSMessageTypeAllocator ros_message_type_allocator_;
1092  ROSMessageTypeDeleter ros_message_type_deleter_;
1093  SerializedMessageAllocator serialized_message_allocator_;
1094  SerializedMessageDeleter serialized_message_deleter_;
1095 };
1096 
1097 } // namespace rclcpp
1098 
1099 #endif // RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
AnySubscriptionCallback< MessageT, AllocatorT > set(CallbackT callback)
Generic function for setting the callback.
void set_deprecated(std::function< void(std::shared_ptr< SetT >, const rclcpp::MessageInfo &)> callback)
Function for shared_ptr to non-const MessageT with MessageInfo, which is deprecated.
void disable()
Disable the callback from being called during dispatch.
void set_deprecated(std::function< void(std::shared_ptr< SetT >)> callback)
Function for shared_ptr to non-const MessageT, which is deprecated.
void enable()
Enable the callback to be called during dispatch.
Additional meta data about messages taken from subscriptions.
Object oriented version of rcl_serialized_message_t with destructor to avoid memory leaks.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
Template structure used to adapt custom, user-defined types to ROS types.
Template helper to select the variant type based on whether or not MessageT is a TypeAdapter.
Struct which contains all possible callback signatures, with or without a TypeAdapter....
typename rclcpp::TypeAdapter< MessageT >::custom_type SubscribedType
MessageT::custom_type if MessageT is a TypeAdapter, otherwise just MessageT.
typename rclcpp::TypeAdapter< MessageT >::ros_message_type ROSMessageType
MessageT::ros_message_type if MessageT is a TypeAdapter, otherwise just MessageT.
Template metaprogramming helper used to resolve the callback argument into a std::function.