iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
active_request.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_ACTIVE_REQUEST_HPP
14#define IOX2_ACTIVE_REQUEST_HPP
15
16#include "internal/helper.hpp"
17#include "iox2/bb/expected.hpp"
20#include "iox2/payload_info.hpp"
22#include "iox2/service_type.hpp"
23
24#include <type_traits>
25
26namespace iox2 {
31template <ServiceType Service,
32 typename RequestPayload,
33 typename RequestUserHeader,
34 typename ResponsePayload,
35 typename ResponseUserHeader>
37 using ValueType = typename PayloadInfo<RequestPayload>::ValueType;
38
39 public:
40 ActiveRequest(ActiveRequest&& rhs) noexcept;
41 auto operator=(ActiveRequest&& rhs) noexcept -> ActiveRequest&;
42 ~ActiveRequest() noexcept;
43
44 ActiveRequest(const ActiveRequest&) = delete;
45 auto operator=(const ActiveRequest&) noexcept -> ActiveRequest& = delete;
46
48 template <typename T = ResponsePayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
50
52 template <typename T = ResponsePayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
53 auto loan_slice_uninit(uint64_t number_of_elements)
55
58 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
59 auto send_copy(const ResponsePayload& payload) const -> bb::Expected<void, SendError>;
60
63 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
65
67 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
68 auto payload() const -> const T&;
69
71 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
72 auto payload() const -> bb::ImmutableSlice<ValueType>;
73
75 template <typename T = RequestUserHeader,
76 typename = std::enable_if_t<!std::is_same<void, RequestUserHeader>::value, T>>
77 auto user_header() const -> const T&;
78
80 auto header() const -> RequestHeader;
81
83 auto origin() const -> UniqueClientId;
84
87 auto is_connected() const -> bool;
88
93 auto has_disconnect_hint() const -> bool;
94
97 template <typename T = ResponsePayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
98 auto loan() -> bb::Expected<ResponseMut<Service, ResponsePayload, ResponseUserHeader>, LoanError>;
99
102 template <typename T = ResponsePayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
103 auto loan_slice(uint64_t number_of_elements)
104 -> bb::Expected<ResponseMut<Service, ResponsePayload, ResponseUserHeader>, LoanError>;
105
106 private:
107 template <ServiceType, typename, typename, typename, typename>
108 friend class Server;
109
110 explicit ActiveRequest(iox2_active_request_h handle) noexcept;
111
112 void drop();
113
114 iox2_active_request_h m_handle = nullptr;
115};
116
117template <ServiceType Service,
118 typename RequestPayload,
119 typename RequestUserHeader,
120 typename ResponsePayload,
121 typename ResponseUserHeader>
122inline ActiveRequest<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::ActiveRequest(
123 ActiveRequest&& rhs) noexcept {
124 *this = std::move(rhs);
125}
126
127template <ServiceType Service,
128 typename RequestPayload,
129 typename RequestUserHeader,
130 typename ResponsePayload,
131 typename ResponseUserHeader>
133 ActiveRequest&& rhs) noexcept -> ActiveRequest& {
134 if (this != &rhs) {
135 drop();
136 m_handle = rhs.m_handle;
137 rhs.m_handle = nullptr;
138 }
139
140 return *this;
141}
142
143template <ServiceType Service,
144 typename RequestPayload,
145 typename RequestUserHeader,
146 typename ResponsePayload,
147 typename ResponseUserHeader>
152
153template <ServiceType Service,
154 typename RequestPayload,
155 typename RequestUserHeader,
156 typename ResponsePayload,
157 typename ResponseUserHeader>
158template <typename T, typename>
159inline auto
162 constexpr uint64_t NUMBER_OF_ELEMENTS = 1;
164 auto result = iox2_active_request_loan_slice_uninit(
165 &m_handle, &response.m_response.m_response, &response.m_response.m_handle, NUMBER_OF_ELEMENTS);
167 if (result == IOX2_OK) {
168 return response;
169 }
170 return bb::err(bb::into<LoanError>(result));
171}
172
173template <ServiceType Service,
174 typename RequestPayload,
175 typename RequestUserHeader,
176 typename ResponsePayload,
177 typename ResponseUserHeader>
178template <typename T, typename>
179inline auto
181 uint64_t number_of_elements)
184 auto result = iox2_active_request_loan_slice_uninit(
185 &m_handle, &response.m_response.m_response, &response.m_response.m_handle, number_of_elements);
187 if (result == IOX2_OK) {
188 return response;
189 }
190 return bb::err(bb::into<LoanError>(result));
191}
192
193template <ServiceType Service,
194 typename RequestPayload,
195 typename RequestUserHeader,
196 typename ResponsePayload,
197 typename ResponseUserHeader>
198template <typename T, typename>
200 const ResponsePayload& payload) const -> bb::Expected<void, SendError> {
201 static_assert(std::is_trivially_copyable<ResponsePayload>::value,
202 "The server supports only trivially copyable response payload types.");
203 constexpr uint64_t NUMBER_OF_ELEMENTS = 1;
204
205 auto result = iox2_active_request_send_copy(
206 &m_handle, static_cast<const void*>(&payload), sizeof(ResponsePayload), NUMBER_OF_ELEMENTS);
207 if (result == IOX2_OK) {
208 return {};
209 }
210 return bb::err(bb::into<SendError>(result));
211}
212
213template <ServiceType Service,
214 typename RequestPayload,
215 typename RequestUserHeader,
216 typename ResponsePayload,
217 typename ResponseUserHeader>
218template <typename T, typename>
219inline auto
222 static_assert(std::is_trivially_copyable<ValueType>::value,
223 "The server supports only trivially copyable response payload types.");
224
225 auto result = iox2_active_request_send_copy(
226 &m_handle, payload.data(), sizeof(typename ResponsePayload::ValueType), payload.number_of_elements());
227 if (result == IOX2_OK) {
228 return {};
229 }
230 return bb::err(bb::into<SendError>(result));
231}
232
233template <ServiceType Service,
234 typename RequestPayload,
235 typename RequestUserHeader,
236 typename ResponsePayload,
237 typename ResponseUserHeader>
238template <typename T, typename>
239inline auto
241 -> const T& {
242 const void* ptr = nullptr;
243 iox2_active_request_payload(&m_handle, &ptr, nullptr);
244 return *static_cast<const T*>(ptr);
245}
246
247template <ServiceType Service,
248 typename RequestPayload,
249 typename RequestUserHeader,
250 typename ResponsePayload,
251 typename ResponseUserHeader>
252template <typename T, typename>
253inline auto
255 -> bb::ImmutableSlice<ValueType> {
256 const void* ptr = nullptr;
257 size_t number_of_elements = 0;
258
259 iox2_active_request_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_active_request_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>
277inline auto
279 -> const T& {
280 const void* ptr = nullptr;
281 iox2_active_request_user_header(&m_handle, &ptr);
282 return *static_cast<const T*>(ptr);
283}
284
285template <ServiceType Service,
286 typename RequestPayload,
287 typename RequestUserHeader,
288 typename ResponsePayload,
289 typename ResponseUserHeader>
290inline auto
292 -> RequestHeader {
293 iox2_request_header_h header_handle = nullptr;
294 iox2_active_request_header(&m_handle, nullptr, &header_handle);
295 return RequestHeader { header_handle };
296}
297
298template <ServiceType Service,
299 typename RequestPayload,
300 typename RequestUserHeader,
301 typename ResponsePayload,
302 typename ResponseUserHeader>
303inline auto
308
309template <ServiceType Service,
310 typename RequestPayload,
311 typename RequestUserHeader,
312 typename ResponsePayload,
313 typename ResponseUserHeader>
314inline auto
316 -> bool {
317 return iox2_active_request_is_connected(&m_handle);
318}
319
320template <ServiceType Service,
321 typename RequestPayload,
322 typename RequestUserHeader,
323 typename ResponsePayload,
324 typename ResponseUserHeader>
325inline auto
327 const -> bool {
328 return iox2_active_request_has_disconnect_hint(&m_handle);
329}
330
331template <ServiceType Service,
332 typename RequestPayload,
333 typename RequestUserHeader,
334 typename ResponsePayload,
335 typename ResponseUserHeader>
336template <typename T, typename>
339 auto response = loan_uninit();
340 if (!response.has_value()) {
341 return bb::err(response.error());
342 }
343
344 new (&response->payload_mut()) ResponsePayload();
345 return assume_init(std::move(*response));
346}
347
348template <ServiceType Service,
349 typename RequestPayload,
350 typename RequestUserHeader,
351 typename ResponsePayload,
352 typename ResponseUserHeader>
353template <typename T, typename>
356 auto response_uninit = loan_slice_uninit(number_of_elements);
357 if (!response_uninit.has_value()) {
358 return bb::err(response_uninit.error());
359 }
360
361 auto response_init = std::move(response_uninit.value());
362 for (auto& item : response_init.payload_mut()) {
363 new (&item) ValueType();
364 }
365
366 return assume_init(std::move(response_init));
367}
368
369template <ServiceType Service,
370 typename RequestPayload,
371 typename RequestUserHeader,
372 typename ResponsePayload,
373 typename ResponseUserHeader>
375 iox2_active_request_h handle) noexcept
376 : m_handle(handle) {
377}
378
379template <ServiceType Service,
380 typename RequestPayload,
381 typename RequestUserHeader,
382 typename ResponsePayload,
383 typename ResponseUserHeader>
384inline void ActiveRequest<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::drop() {
385 if (m_handle != nullptr) {
386 iox2_active_request_drop(m_handle);
387 m_handle = nullptr;
388 }
389}
390} // namespace iox2
391
392#endif
auto operator=(const ActiveRequest &) noexcept -> ActiveRequest &=delete
auto loan_uninit() -> bb::Expected< ResponseMutUninit< Service, ResponsePayload, ResponseUserHeader >, LoanError >
Loans uninitialized memory for a [ResponseMutUninit] where the user can write its payload to.
auto origin() const -> UniqueClientId
Returns the [UniqueClientId] of the [Client].
auto is_connected() const -> bool
auto header() const -> RequestHeader
Returns a reference to the [RequestHeader] of the received [RequestMut].
auto has_disconnect_hint() const -> bool
auto loan() -> bb::Expected< ResponseMut< Service, ResponsePayload, ResponseUserHeader >, LoanError >
auto user_header() const -> const T &
Returns a reference to the user_header of the received [RequestMut].
auto loan_slice_uninit(uint64_t number_of_elements) -> bb::Expected< ResponseMutUninit< Service, ResponsePayload, ResponseUserHeader >, LoanError >
Loans uninitialized memory for a [ResponseMutUninit] where the user can write its payload to.
auto send_slice_copy(const bb::ImmutableSlice< ValueType > &payload) const -> bb::Expected< void, SendError >
auto loan_slice(uint64_t number_of_elements) -> bb::Expected< ResponseMut< Service, ResponsePayload, ResponseUserHeader >, LoanError >
auto send_copy(const ResponsePayload &payload) const -> bb::Expected< void, SendError >
ActiveRequest(const ActiveRequest &)=delete
ActiveRequest(ActiveRequest &&rhs) noexcept
auto payload() const -> const T &
Returns a reference to the payload of the received [RequestMut].
auto operator=(ActiveRequest &&rhs) noexcept -> ActiveRequest &
Request header used by [MessagingPattern::RequestResponse].
The system-wide unique id of a [Client].
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
auto assume_init(RequestMutUninit< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader > &&self) -> RequestMut< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >
static void placement_default(S &payload)
Definition helper.hpp:22