iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
sample_mut.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13#ifndef IOX2_SAMPLE_MUT_HPP
14#define IOX2_SAMPLE_MUT_HPP
15
16#include "iox2/bb/expected.hpp"
17#include "iox2/bb/slice.hpp"
19#include "iox2/iceoryx2.h"
20#include "iox2/iceoryx2_cxx_deployment.hpp"
22#include "iox2/marker.hpp"
23#include "iox2/payload_info.hpp"
24#include "iox2/service_type.hpp"
25
26#include <type_traits>
27
28#if IOX2_FEATURE_FLATBUFFERS
29#include <flatbuffers/flatbuffers.h>
30#endif
31
32namespace iox2 {
33
52template <ServiceType S, typename Payload, typename UserHeader>
53// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) 'm_sample' is not used directly but only via the initialized 'm_handle'; furthermore, it will be initialized on the call site
54class SampleMut {
55 using ValueType = typename PayloadInfo<Payload>::ValueType;
56
57 public:
58 SampleMut(SampleMut&& rhs) noexcept;
59 auto operator=(SampleMut&& rhs) noexcept -> SampleMut&;
60 ~SampleMut() noexcept;
61
62 SampleMut(const SampleMut&) = delete;
63 auto operator=(const SampleMut&) -> SampleMut& = delete;
64
66 auto header() const -> HeaderPublishSubscribe;
67
69 template <typename T = UserHeader, typename = std::enable_if_t<!std::is_same<void, UserHeader>::value, T>>
70 auto user_header() const -> const T&;
71
73 template <typename T = UserHeader, typename = std::enable_if_t<!std::is_same<void, UserHeader>::value, T>>
74 auto user_header_mut() -> T&;
75
77 template <typename T = Payload,
78 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
79 auto payload() const -> const ValueType&;
80
82 template <typename T = Payload,
83 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
84 auto payload_mut() -> ValueType&;
85
86#if IOX2_FEATURE_FLATBUFFERS
88 template <typename T = Payload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
89 auto payload_bytes() const -> bb::ImmutableSlice<uint8_t>;
90
92 template <typename T = Payload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
93 auto payload_root() const -> const typename T::ValueType*;
94#endif // IOX2_FEATURE_FLATBUFFERS
95
97 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
98 auto payload() const -> bb::ImmutableSlice<ValueType>;
99
101 template <typename T = Payload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
102 auto payload_mut() -> bb::MutableSlice<ValueType>;
103
104 private:
105 template <ServiceType, typename, typename>
106 friend class Publisher;
107 template <ServiceType, typename, typename>
108 friend class SampleMutUninit;
109
110 template <ServiceType ST, typename PayloadT, typename UserHeaderT>
111 friend auto send(SampleMut<ST, PayloadT, UserHeaderT>&& sample) -> bb::Expected<size_t, SendError>;
112
113 // The sample is defaulted since both members are initialized in Publisher::loan() or
114 // Publisher::loan_slice()
115 explicit SampleMut() = default;
116 void drop();
117
118 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) will not be accessed directly but only via m_handle and will be set together with m_handle
119 iox2_sample_mut_t m_sample;
120 iox2_sample_mut_h m_handle = nullptr;
121};
122
123template <ServiceType S, typename Payload, typename UserHeader>
124inline void SampleMut<S, Payload, UserHeader>::drop() {
125 if (m_handle != nullptr) {
126 iox2_sample_mut_drop(m_handle);
127 m_handle = nullptr;
128 }
129}
130
131// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) m_sample will be initialized in the move assignment operator
132template <ServiceType S, typename Payload, typename UserHeader>
134 *this = std::move(rhs);
135}
136
137namespace internal {
138extern "C" {
139void iox2_sample_mut_move(iox2_sample_mut_t*, iox2_sample_mut_t*, iox2_sample_mut_h*);
140}
141} // namespace internal
142
143template <ServiceType S, typename Payload, typename UserHeader>
145 if (this != &rhs) {
146 drop();
147
148 internal::iox2_sample_mut_move(&rhs.m_sample, &m_sample, &m_handle);
149 rhs.m_handle = nullptr;
150 }
151
152 return *this;
153}
154
155template <ServiceType S, typename Payload, typename UserHeader>
157 drop();
158}
159
160template <ServiceType S, typename Payload, typename UserHeader>
162 iox2_publish_subscribe_header_h header_handle = nullptr;
163 iox2_sample_mut_header(&m_handle, nullptr, &header_handle);
164
165 return HeaderPublishSubscribe { header_handle };
166}
167
168template <ServiceType S, typename Payload, typename UserHeader>
169template <typename T, typename>
170inline auto SampleMut<S, Payload, UserHeader>::user_header() const -> const T& {
171 const void* ptr = nullptr;
172
173 iox2_sample_mut_user_header(&m_handle, &ptr);
174
175 return *static_cast<const T*>(ptr);
176}
177
178template <ServiceType S, typename Payload, typename UserHeader>
179template <typename T, typename>
181 void* ptr = nullptr;
182
183 iox2_sample_mut_user_header_mut(&m_handle, &ptr);
184
185 return *static_cast<T*>(ptr);
186}
187
188template <ServiceType S, typename Payload, typename UserHeader>
189template <typename T, typename>
190inline auto SampleMut<S, Payload, UserHeader>::payload() const -> const ValueType& {
191 const void* ptr = nullptr;
192
193 iox2_sample_mut_payload(&m_handle, &ptr, nullptr);
194
195 return *static_cast<const ValueType*>(ptr);
196}
197
198template <ServiceType S, typename Payload, typename UserHeader>
199template <typename T, typename>
201 void* ptr = nullptr;
202
203 iox2_sample_mut_payload_mut(&m_handle, &ptr, nullptr);
204
205 return *static_cast<ValueType*>(ptr);
206}
207
208template <ServiceType S, typename Payload, typename UserHeader>
209template <typename T, typename>
210inline auto SampleMut<S, Payload, UserHeader>::payload() const -> bb::ImmutableSlice<ValueType> {
211 const void* ptr = nullptr;
212 size_t number_of_elements = 0;
213
214 iox2_sample_mut_payload(&m_handle, &ptr, &number_of_elements);
215
216 // for the custom payload marker, the slice length is the
217 // runtime payload byte size
218 auto length = number_of_elements;
219 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
220 length = iox2_sample_mut_payload_number_of_bytes(&m_handle);
221 }
222
223 return bb::ImmutableSlice<ValueType>(static_cast<const ValueType*>(ptr), length);
224}
225
226template <ServiceType S, typename Payload, typename UserHeader>
227template <typename T, typename>
228inline auto SampleMut<S, Payload, UserHeader>::payload_mut() -> bb::MutableSlice<ValueType> {
229 void* ptr = nullptr;
230 size_t number_of_elements = 0;
231
232 iox2_sample_mut_payload_mut(&m_handle, &ptr, &number_of_elements);
233
234 auto length = number_of_elements;
235 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
236 length = iox2_sample_mut_payload_number_of_bytes(&m_handle);
237 }
238
239 return bb::MutableSlice<ValueType>(static_cast<ValueType*>(ptr), length);
240}
241
242#if IOX2_FEATURE_FLATBUFFERS
243
244template <ServiceType S, typename Payload, typename UserHeader>
245template <typename T, typename>
246inline auto SampleMut<S, Payload, UserHeader>::payload_bytes() const -> bb::ImmutableSlice<uint8_t> {
247 const void* ptr = nullptr;
248 size_t number_of_elements = 0;
249
250 iox2_sample_mut_payload(&m_handle, &ptr, &number_of_elements);
251 auto payload_offset = header().payload_offset();
252 auto payload_len = header().number_of_elements();
253
254 return bb::ImmutableSlice<uint8_t>(static_cast<const uint8_t*>(ptr) + payload_offset, payload_len - payload_offset);
255}
256
257template <ServiceType S, typename Payload, typename UserHeader>
258template <typename T, typename>
259auto SampleMut<S, Payload, UserHeader>::payload_root() const -> const typename T::ValueType* {
260 return flatbuffers::GetRoot<typename T::ValueType>(payload_bytes().data());
261}
262
263#endif // IOX2_FEATURE_FLATBUFFERS
264
265template <ServiceType S, typename Payload, typename UserHeader>
267 size_t number_of_recipients = 0;
268 auto result = iox2_sample_mut_send(sample.m_handle, &number_of_recipients);
269 sample.m_handle = nullptr;
270
271 if (result == IOX2_OK) {
272 return number_of_recipients;
273 }
274
275 return bb::err(bb::into<SendError>(result));
276}
277
278} // namespace iox2
279
280#endif
Sample header used by [MessagingPattern::PublishSubscribe].
Sending endpoint of a publish-subscriber based communication.
Definition publisher.hpp:40
auto user_header_mut() -> T &
Returns a mutable reference to the user_header of the [Sample].
~SampleMut() noexcept
auto header() const -> HeaderPublishSubscribe
Returns a reference to the [Header] of the [Sample].
SampleMut(const SampleMut &)=delete
auto payload_mut() -> ValueType &
Returns a reference to the payload of the sample.
friend auto send(SampleMut< ST, PayloadT, UserHeaderT > &&sample) -> bb::Expected< size_t, SendError >
auto payload() const -> const ValueType &
Returns a reference to the const payload of the sample.
auto payload() const -> bb::ImmutableSlice< ValueType >
Returns an immutable slice to the payload of the sample.
auto user_header() const -> const T &
Returns a reference to the user_header of the [Sample].
auto operator=(const SampleMut &) -> SampleMut &=delete
auto operator=(SampleMut &&rhs) noexcept -> SampleMut &
constexpr auto err(const E &error) -> Unexpected< E >
Definition expected.hpp:33
iox2::bb::variation::Expected< T, E > Expected
Definition expected.hpp:22
constexpr auto has_flatbuffer_marker() -> bool
Definition marker.hpp:49
SendError
Failure that can be emitted when data is sent.