15 #ifndef RCLCPP__EXPERIMENTAL__BUFFERS__INTRA_PROCESS_BUFFER_HPP_
16 #define RCLCPP__EXPERIMENTAL__BUFFERS__INTRA_PROCESS_BUFFER_HPP_
20 #include <type_traits>
24 #include "rclcpp/allocator/allocator_common.hpp"
25 #include "rclcpp/allocator/allocator_deleter.hpp"
26 #include "rclcpp/experimental/buffers/buffer_implementation_base.hpp"
27 #include "rclcpp/macros.hpp"
28 #include "tracetools/tracetools.h"
32 namespace experimental
44 virtual void clear() = 0;
46 virtual bool has_data()
const = 0;
47 virtual bool use_take_shared_method()
const = 0;
48 virtual size_t available_capacity()
const = 0;
53 typename Alloc = std::allocator<void>,
54 typename MessageDeleter = std::default_delete<MessageT>>
62 using MessageUniquePtr = std::unique_ptr<MessageT, MessageDeleter>;
63 using MessageSharedPtr = std::shared_ptr<const MessageT>;
65 virtual void add_shared(MessageSharedPtr msg) = 0;
66 virtual void add_unique(MessageUniquePtr msg) = 0;
68 virtual MessageSharedPtr consume_shared() = 0;
69 virtual MessageUniquePtr consume_unique() = 0;
71 virtual std::vector<MessageSharedPtr> get_all_data_shared() = 0;
72 virtual std::vector<MessageUniquePtr> get_all_data_unique() = 0;
77 typename Alloc = std::allocator<void>,
78 typename MessageDeleter = std::default_delete<MessageT>,
79 typename BufferT = std::unique_ptr<MessageT>>
85 using MessageAllocTraits = allocator::AllocRebind<MessageT, Alloc>;
86 using MessageAlloc =
typename MessageAllocTraits::allocator_type;
87 using MessageUniquePtr = std::unique_ptr<MessageT, MessageDeleter>;
88 using MessageSharedPtr = std::shared_ptr<const MessageT>;
93 std::shared_ptr<Alloc> allocator =
nullptr)
95 bool valid_type = (std::is_same<BufferT, MessageSharedPtr>::value ||
96 std::is_same<BufferT, MessageUniquePtr>::value);
98 throw std::runtime_error(
"Creating TypedIntraProcessBuffer with not valid BufferT");
101 buffer_ = std::move(buffer_impl);
103 TRACETOOLS_TRACEPOINT(
104 rclcpp_buffer_to_ipb,
105 static_cast<const void *
>(buffer_.get()),
106 static_cast<const void *
>(
this));
108 message_allocator_ = std::make_shared<MessageAlloc>();
110 message_allocator_ = std::make_shared<MessageAlloc>(*allocator.get());
116 void add_shared(MessageSharedPtr msg)
override
118 add_shared_impl<BufferT>(std::move(msg));
121 void add_unique(MessageUniquePtr msg)
override
123 buffer_->enqueue(std::move(msg));
126 MessageSharedPtr consume_shared()
override
128 return consume_shared_impl<BufferT>();
131 MessageUniquePtr consume_unique()
override
133 return consume_unique_impl<BufferT>();
136 std::vector<MessageSharedPtr> get_all_data_shared()
override
138 return get_all_data_shared_impl();
141 std::vector<MessageUniquePtr> get_all_data_unique()
override
143 return get_all_data_unique_impl();
146 bool has_data()
const override
148 return buffer_->has_data();
151 void clear()
override
156 bool use_take_shared_method()
const override
158 return std::is_same<BufferT, MessageSharedPtr>::value;
161 size_t available_capacity()
const override
163 return buffer_->available_capacity();
167 std::unique_ptr<BufferImplementationBase<BufferT>> buffer_;
169 std::shared_ptr<MessageAlloc> message_allocator_;
172 template<
typename DestinationT>
173 typename std::enable_if<
174 std::is_same<DestinationT, MessageSharedPtr>::value
176 add_shared_impl(MessageSharedPtr shared_msg)
178 buffer_->enqueue(std::move(shared_msg));
182 template<
typename DestinationT>
183 typename std::enable_if<
184 std::is_same<DestinationT, MessageUniquePtr>::value
186 add_shared_impl(MessageSharedPtr shared_msg)
191 MessageUniquePtr unique_msg;
192 MessageDeleter * deleter = std::get_deleter<MessageDeleter, const MessageT>(shared_msg);
193 auto ptr = MessageAllocTraits::allocate(*message_allocator_.get(), 1);
194 MessageAllocTraits::construct(*message_allocator_.get(), ptr, *shared_msg);
196 unique_msg = MessageUniquePtr(ptr, *deleter);
198 unique_msg = MessageUniquePtr(ptr);
201 buffer_->enqueue(std::move(unique_msg));
205 template<
typename OriginT>
206 typename std::enable_if<
207 std::is_same<OriginT, MessageSharedPtr>::value,
210 consume_shared_impl()
212 return buffer_->dequeue();
216 template<
typename OriginT>
217 typename std::enable_if<
218 (std::is_same<OriginT, MessageUniquePtr>::value),
221 consume_shared_impl()
224 return buffer_->dequeue();
228 template<
typename OriginT>
229 typename std::enable_if<
230 (std::is_same<OriginT, MessageSharedPtr>::value),
233 consume_unique_impl()
235 MessageSharedPtr buffer_msg = buffer_->dequeue();
237 MessageUniquePtr unique_msg;
238 MessageDeleter * deleter = std::get_deleter<MessageDeleter, const MessageT>(buffer_msg);
239 auto ptr = MessageAllocTraits::allocate(*message_allocator_.get(), 1);
240 MessageAllocTraits::construct(*message_allocator_.get(), ptr, *buffer_msg);
242 unique_msg = MessageUniquePtr(ptr, *deleter);
244 unique_msg = MessageUniquePtr(ptr);
251 template<
typename OriginT>
252 typename std::enable_if<
253 (std::is_same<OriginT, MessageUniquePtr>::value),
256 consume_unique_impl()
258 return buffer_->dequeue();
262 template<
typename T = BufferT>
263 typename std::enable_if<
264 std::is_same<T, MessageSharedPtr>::value,
265 std::vector<MessageSharedPtr>
267 get_all_data_shared_impl()
269 return buffer_->get_all_data();
273 template<
typename T = BufferT>
274 typename std::enable_if<
275 std::is_same<T, MessageUniquePtr>::value,
276 std::vector<MessageSharedPtr>
278 get_all_data_shared_impl()
280 std::vector<MessageSharedPtr> result;
281 auto uni_ptr_vec = buffer_->get_all_data();
282 result.reserve(uni_ptr_vec.size());
283 for (MessageUniquePtr & uni_ptr : uni_ptr_vec) {
284 result.emplace_back(std::move(uni_ptr));
290 template<
typename T = BufferT>
291 typename std::enable_if<
292 std::is_same<T, MessageSharedPtr>::value,
293 std::vector<MessageUniquePtr>
295 get_all_data_unique_impl()
297 std::vector<MessageUniquePtr> result;
298 auto shared_ptr_vec = buffer_->get_all_data();
299 result.reserve(shared_ptr_vec.size());
300 for (MessageSharedPtr shared_msg : shared_ptr_vec) {
301 MessageUniquePtr unique_msg;
302 MessageDeleter * deleter = std::get_deleter<MessageDeleter, const MessageT>(shared_msg);
303 auto ptr = MessageAllocTraits::allocate(*message_allocator_.get(), 1);
304 MessageAllocTraits::construct(*message_allocator_.get(), ptr, *shared_msg);
306 unique_msg = MessageUniquePtr(ptr, *deleter);
308 unique_msg = MessageUniquePtr(ptr);
310 result.push_back(std::move(unique_msg));
316 template<
typename T = BufferT>
317 typename std::enable_if<
318 std::is_same<T, MessageUniquePtr>::value,
319 std::vector<MessageUniquePtr>
321 get_all_data_unique_impl()
323 return buffer_->get_all_data();
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.