iceoryx2
C++ Bindings
Loading...
Searching...
No Matches
request_mut.hpp
Go to the documentation of this file.
1// Copyright (c) 2025 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_REQUEST_MUT_HPP
14#define IOX2_REQUEST_MUT_HPP
15
16#include "iox2/bb/expected.hpp"
17#include "iox2/bb/slice.hpp"
18#include "iox2/deployment/iceoryx2_cxx_feature_flags.hpp"
21#include "iox2/marker.hpp"
22#include "iox2/payload_info.hpp"
24#include "iox2/port_error.hpp"
25#include "iox2/service_type.hpp"
26
27#if IOX2_FEATURE_FLATBUFFERS
28#include <flatbuffers/flatbuffers.h>
29#endif // IOX2_FEATURE_FLATBUFFERS
30
31#include <type_traits>
32
33namespace iox2 {
34
37template <ServiceType Service,
38 typename RequestPayload,
39 typename RequestUserHeader,
40 typename ResponsePayload,
41 typename ResponseUserHeader>
42// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) 'm_request' is not used directly but only via the initialized 'm_handle'; furthermore, it will be initialized on the call site
44 using ValueType = typename PayloadInfo<RequestPayload>::ValueType;
45
46 public:
47 RequestMut(RequestMut&& rhs) noexcept;
48 auto operator=(RequestMut&& rhs) noexcept -> RequestMut&;
49 ~RequestMut() noexcept;
50
51 RequestMut(const RequestMut&) = delete;
52 auto operator=(const RequestMut&) -> RequestMut& = delete;
53
55 auto header() const -> RequestHeader;
56
58 template <typename T = RequestUserHeader,
59 typename = std::enable_if_t<!std::is_same<void, RequestUserHeader>::value, T>>
60 auto user_header() const -> const T&;
61
63 template <typename T = RequestUserHeader,
64 typename = std::enable_if_t<!std::is_same<void, RequestUserHeader>::value, T>>
65 auto user_header_mut() -> T&;
66
68 template <typename T = RequestPayload,
69 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
70 auto payload() const -> const RequestPayload&;
71
73 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
74 auto payload() const -> bb::ImmutableSlice<ValueType>;
75
77 template <typename T = RequestPayload,
78 typename = std::enable_if_t<!bb::IsSlice<T>::VALUE && !has_flatbuffer_marker<T>(), void>>
79 auto payload_mut() -> RequestPayload&;
80
82 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
83 auto payload_mut() -> bb::MutableSlice<ValueType>;
84
85#if IOX2_FEATURE_FLATBUFFERS
87 template <typename T = RequestPayload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
88 auto payload_bytes() const -> bb::ImmutableSlice<uint8_t>;
89
91 template <typename T = RequestPayload, typename = std::enable_if_t<has_flatbuffer_marker<T>(), void>>
92 auto payload_root() const -> const typename T::ValueType*;
93#endif // IOX2_FEATURE_FLATBUFFERS
94
95 private:
96 template <ServiceType, typename, typename, typename, typename>
97 friend class Client;
98 template <ServiceType, typename, typename, typename, typename>
99 friend class RequestMutUninit;
100
104 template <ServiceType S,
105 typename RequestPayloadT,
106 typename RequestUserHeaderT,
107 typename ResponsePayloadT,
108 typename ResponseUserHeaderT>
109 friend auto
113
114 explicit RequestMut() = default;
115 void drop();
116
117 iox2_request_mut_t m_request;
118 iox2_request_mut_h m_handle = nullptr;
119};
120
121// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) m_request will be initialized in the move assignment operator
122template <ServiceType Service,
123 typename RequestPayload,
124 typename RequestUserHeader,
125 typename ResponsePayload,
126 typename ResponseUserHeader>
131
132namespace internal {
133extern "C" {
134void iox2_request_mut_move(iox2_request_mut_t*, iox2_request_mut_t*, iox2_request_mut_h*);
135}
136} // namespace internal
137
138template <ServiceType Service,
139 typename RequestPayload,
140 typename RequestUserHeader,
141 typename ResponsePayload,
142 typename ResponseUserHeader>
144 RequestMut&& rhs) noexcept -> RequestMut& {
145 if (this != &rhs) {
146 drop();
147
148 internal::iox2_request_mut_move(&rhs.m_request, &m_request, &m_handle);
149 rhs.m_handle = nullptr;
150 }
151 return *this;
152}
153
154template <ServiceType Service,
155 typename RequestPayload,
156 typename RequestUserHeader,
157 typename ResponsePayload,
158 typename ResponseUserHeader>
163
164#if IOX2_FEATURE_FLATBUFFERS
165template <ServiceType Service,
166 typename RequestPayload,
167 typename RequestUserHeader,
168 typename ResponsePayload,
169 typename ResponseUserHeader>
170template <typename T, typename>
171inline auto
173 -> bb::ImmutableSlice<uint8_t> {
174 const void* ptr = nullptr;
175 size_t number_of_elements = 0;
176
177 iox2_request_mut_payload(&m_handle, &ptr, &number_of_elements);
178 auto payload_offset = header().payload_offset();
179 auto payload_len = header().number_of_elements();
180
181 return bb::ImmutableSlice<uint8_t>(static_cast<const uint8_t*>(ptr) + payload_offset, payload_len - payload_offset);
182}
183
184template <ServiceType Service,
185 typename RequestPayload,
186 typename RequestUserHeader,
187 typename ResponsePayload,
188 typename ResponseUserHeader>
189template <typename T, typename>
190inline auto
192 -> const typename T::ValueType* {
193 return flatbuffers::GetRoot<typename T::ValueType>(payload_bytes().data());
194}
195#endif // IOX2_FEATURE_FLATBUFFERS
196
197template <ServiceType Service,
198 typename RequestPayload,
199 typename RequestUserHeader,
200 typename ResponsePayload,
201 typename ResponseUserHeader>
203 -> RequestHeader {
204 iox2_request_header_h header_handle = nullptr;
205 iox2_request_mut_header(&m_handle, nullptr, &header_handle);
206 return RequestHeader { header_handle };
207}
208
209template <ServiceType Service,
210 typename RequestPayload,
211 typename RequestUserHeader,
212 typename ResponsePayload,
213 typename ResponseUserHeader>
214template <typename T, typename>
215inline auto
217 -> const T& {
218 const void* ptr = nullptr;
219 iox2_request_mut_user_header(&m_handle, &ptr);
220 return *static_cast<const T*>(ptr);
221}
222
223template <ServiceType Service,
224 typename RequestPayload,
225 typename RequestUserHeader,
226 typename ResponsePayload,
227 typename ResponseUserHeader>
228template <typename T, typename>
229inline auto
231 void* ptr = nullptr;
232 iox2_request_mut_user_header_mut(&m_handle, &ptr);
233 return *static_cast<T*>(ptr);
234}
235
236template <ServiceType Service,
237 typename RequestPayload,
238 typename RequestUserHeader,
239 typename ResponsePayload,
240 typename ResponseUserHeader>
241template <typename T, typename>
243 -> const RequestPayload& {
244 const void* ptr = nullptr;
245 iox2_request_mut_payload(&m_handle, &ptr, nullptr);
246 return *static_cast<const RequestPayload*>(ptr);
247}
248
249template <ServiceType Service,
250 typename RequestPayload,
251 typename RequestUserHeader,
252 typename ResponsePayload,
253 typename ResponseUserHeader>
254template <typename T, typename>
256 -> bb::ImmutableSlice<ValueType> {
257 const void* ptr = nullptr;
258 size_t number_of_elements = 0;
259 iox2_request_mut_payload(&m_handle, &ptr, &number_of_elements);
260
261 // for the custom payload marker, the slice length is the
262 // runtime payload byte size
263 auto length = number_of_elements;
264 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
265 length = iox2_request_mut_payload_number_of_bytes(&m_handle);
266 }
267
268 return bb::ImmutableSlice<ValueType>(static_cast<const ValueType*>(ptr), length);
269}
270
271template <ServiceType Service,
272 typename RequestPayload,
273 typename RequestUserHeader,
274 typename ResponsePayload,
275 typename ResponseUserHeader>
276template <typename T, typename>
278 -> RequestPayload& {
279 void* ptr = nullptr;
280 iox2_request_mut_payload_mut(&m_handle, &ptr, nullptr);
281 return *static_cast<RequestPayload*>(ptr);
282}
283
284template <ServiceType Service,
285 typename RequestPayload,
286 typename RequestUserHeader,
287 typename ResponsePayload,
288 typename ResponseUserHeader>
289template <typename T, typename>
292 void* ptr = nullptr;
293 size_t number_of_elements = 0;
294 iox2_request_mut_payload_mut(&m_handle, &ptr, &number_of_elements);
295
296 // for the custom payload marker, the slice length is the
297 // runtime payload byte size
298 auto length = number_of_elements;
299 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
300 length = iox2_request_mut_payload_number_of_bytes(&m_handle);
301 }
302
303 return bb::MutableSlice<ValueType>(static_cast<ValueType*>(ptr), length);
304}
305
306template <ServiceType Service,
307 typename RequestPayload,
308 typename RequestUserHeader,
309 typename ResponsePayload,
310 typename ResponseUserHeader>
314 iox2_pending_response_h pending_response_handle {};
315 auto result = iox2_request_mut_send(request.m_handle, nullptr, &pending_response_handle);
316 request.m_handle = nullptr;
317
318 if (result == IOX2_OK) {
320 pending_response_handle);
321 }
322 return bb::err(bb::into<RequestSendError>(result));
323}
324
325template <ServiceType Service,
326 typename RequestPayload,
327 typename RequestUserHeader,
328 typename ResponsePayload,
329 typename ResponseUserHeader>
330inline void RequestMut<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::drop() {
331 if (m_handle != nullptr) {
332 iox2_request_mut_drop(m_handle);
333 m_handle = nullptr;
334 }
335}
336
337} // namespace iox2
338
339#endif
Sends [RequestMut]s to a [Server] in a request-response based communication.
Definition client.hpp:33
Request header used by [MessagingPattern::RequestResponse].
auto payload() const -> const RequestPayload &
Returns a reference to the user defined request payload.
auto payload_mut() -> RequestPayload &
Returns a mutable reference to the user defined request payload.
auto payload_bytes() const -> bb::ImmutableSlice< uint8_t >
Returns the serialized flatbuffer data as bytes.
auto user_header() const -> const T &
Returns a reference to the user defined request header.
auto operator=(RequestMut &&rhs) noexcept -> RequestMut &
auto user_header_mut() -> T &
Returns a mutable reference to the user defined request header.
auto payload_root() const -> const typename T::ValueType *
Returns the root of the flatbuffer.
friend auto send(RequestMut< S, RequestPayloadT, RequestUserHeaderT, ResponsePayloadT, ResponseUserHeaderT > &&request) -> bb::Expected< PendingResponse< S, RequestPayloadT, RequestUserHeaderT, ResponsePayloadT, ResponseUserHeaderT >, RequestSendError >
RequestMut(const RequestMut &)=delete
~RequestMut() noexcept
auto operator=(const RequestMut &) -> RequestMut &=delete
auto header() const -> RequestHeader
Returns a reference to the iceoryx2 internal [RequestHeader].
A class representing a slice of contiguous elements of type T.
Definition slice.hpp:31
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:53
auto send(RequestMut< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader > &&request) -> bb::Expected< PendingResponse< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >, RequestSendError >
RequestSendError
Failure that can be emitted when a [RequestMut] is sent.