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