iceoryx2
C++ Language 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"
21#include "iox2/payload_info.hpp"
23#include "iox2/port_error.hpp"
24#include "iox2/service_type.hpp"
25
26#include <type_traits>
27
28namespace iox2 {
29
32template <ServiceType Service,
33 typename RequestPayload,
34 typename RequestUserHeader,
35 typename ResponsePayload,
36 typename ResponseUserHeader>
37// 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
39 using ValueType = typename PayloadInfo<RequestPayload>::ValueType;
40
41 public:
42 RequestMut(RequestMut&& rhs) noexcept;
43 auto operator=(RequestMut&& rhs) noexcept -> RequestMut&;
44 ~RequestMut() noexcept;
45
46 RequestMut(const RequestMut&) = delete;
47 auto operator=(const RequestMut&) -> RequestMut& = delete;
48
50 auto header() const -> RequestHeader;
51
53 template <typename T = RequestUserHeader,
54 typename = std::enable_if_t<!std::is_same<void, RequestUserHeader>::value, T>>
55 auto user_header() const -> const T&;
56
58 template <typename T = RequestUserHeader,
59 typename = std::enable_if_t<!std::is_same<void, RequestUserHeader>::value, T>>
60 auto user_header_mut() -> T&;
61
63 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
64 auto payload() const -> const RequestPayload&;
65
67 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
68 auto payload() const -> bb::ImmutableSlice<ValueType>;
69
71 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
72 auto payload_mut() -> RequestPayload&;
73
75 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
76 auto payload_mut() -> bb::MutableSlice<ValueType>;
77
78 private:
79 template <ServiceType, typename, typename, typename, typename>
80 friend class Client;
81 template <ServiceType, typename, typename, typename, typename>
82 friend class RequestMutUninit;
83
87 template <ServiceType S,
88 typename RequestPayloadT,
89 typename RequestUserHeaderT,
90 typename ResponsePayloadT,
91 typename ResponseUserHeaderT>
92 friend auto
93 send(RequestMut<S, RequestPayloadT, RequestUserHeaderT, ResponsePayloadT, ResponseUserHeaderT>&& request)
94 -> bb::Expected<PendingResponse<S, RequestPayloadT, RequestUserHeaderT, ResponsePayloadT, ResponseUserHeaderT>,
96
97 explicit RequestMut() = default;
98 void drop();
99
100 iox2_request_mut_t m_request;
101 iox2_request_mut_h m_handle = nullptr;
102};
103
104// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) m_request will be initialized in the move assignment operator
105template <ServiceType Service,
106 typename RequestPayload,
107 typename RequestUserHeader,
108 typename ResponsePayload,
109 typename ResponseUserHeader>
110inline RequestMut<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::RequestMut(
111 RequestMut&& rhs) noexcept {
112 *this = std::move(rhs);
113}
114
115namespace internal {
116extern "C" {
117void iox2_request_mut_move(iox2_request_mut_t*, iox2_request_mut_t*, iox2_request_mut_h*);
118}
119} // namespace internal
120
121template <ServiceType Service,
122 typename RequestPayload,
123 typename RequestUserHeader,
124 typename ResponsePayload,
125 typename ResponseUserHeader>
127 RequestMut&& rhs) noexcept -> RequestMut& {
128 if (this != &rhs) {
129 drop();
130
131 internal::iox2_request_mut_move(&rhs.m_request, &m_request, &m_handle);
132 rhs.m_handle = nullptr;
133 }
134 return *this;
135}
136
137template <ServiceType Service,
138 typename RequestPayload,
139 typename RequestUserHeader,
140 typename ResponsePayload,
141 typename ResponseUserHeader>
146
147template <ServiceType Service,
148 typename RequestPayload,
149 typename RequestUserHeader,
150 typename ResponsePayload,
151 typename ResponseUserHeader>
153 -> RequestHeader {
154 iox2_request_header_h header_handle = nullptr;
155 iox2_request_mut_header(&m_handle, nullptr, &header_handle);
156 return RequestHeader { header_handle };
157}
158
159template <ServiceType Service,
160 typename RequestPayload,
161 typename RequestUserHeader,
162 typename ResponsePayload,
163 typename ResponseUserHeader>
164template <typename T, typename>
165inline auto
167 -> const T& {
168 const void* ptr = nullptr;
169 iox2_request_mut_user_header(&m_handle, &ptr);
170 return *static_cast<const T*>(ptr);
171}
172
173template <ServiceType Service,
174 typename RequestPayload,
175 typename RequestUserHeader,
176 typename ResponsePayload,
177 typename ResponseUserHeader>
178template <typename T, typename>
179inline auto
181 void* ptr = nullptr;
182 iox2_request_mut_user_header_mut(&m_handle, &ptr);
183 return *static_cast<T*>(ptr);
184}
185
186template <ServiceType Service,
187 typename RequestPayload,
188 typename RequestUserHeader,
189 typename ResponsePayload,
190 typename ResponseUserHeader>
191template <typename T, typename>
193 -> const RequestPayload& {
194 const void* ptr = nullptr;
195 iox2_request_mut_payload(&m_handle, &ptr, nullptr);
196 return *static_cast<const RequestPayload*>(ptr);
197}
198
199template <ServiceType Service,
200 typename RequestPayload,
201 typename RequestUserHeader,
202 typename ResponsePayload,
203 typename ResponseUserHeader>
204template <typename T, typename>
206 -> bb::ImmutableSlice<ValueType> {
207 const void* ptr = nullptr;
208 size_t number_of_elements = 0;
209 iox2_request_mut_payload(&m_handle, &ptr, &number_of_elements);
210
211 // for the custom payload marker, the slice length is the
212 // runtime payload byte size
213 auto length = number_of_elements;
214 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
215 length = iox2_request_mut_payload_number_of_bytes(&m_handle);
216 }
217
218 return bb::ImmutableSlice<ValueType>(static_cast<const ValueType*>(ptr), length);
219}
220
221template <ServiceType Service,
222 typename RequestPayload,
223 typename RequestUserHeader,
224 typename ResponsePayload,
225 typename ResponseUserHeader>
226template <typename T, typename>
228 -> RequestPayload& {
229 void* ptr = nullptr;
230 iox2_request_mut_payload_mut(&m_handle, &ptr, nullptr);
231 return *static_cast<RequestPayload*>(ptr);
232}
233
234template <ServiceType Service,
235 typename RequestPayload,
236 typename RequestUserHeader,
237 typename ResponsePayload,
238 typename ResponseUserHeader>
239template <typename T, typename>
242 void* ptr = nullptr;
243 size_t number_of_elements = 0;
244 iox2_request_mut_payload_mut(&m_handle, &ptr, &number_of_elements);
245
246 // for the custom payload marker, the slice length is the
247 // runtime payload byte size
248 auto length = number_of_elements;
249 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
250 length = iox2_request_mut_payload_number_of_bytes(&m_handle);
251 }
252
253 return bb::MutableSlice<ValueType>(static_cast<ValueType*>(ptr), length);
254}
255
256template <ServiceType Service,
257 typename RequestPayload,
258 typename RequestUserHeader,
259 typename ResponsePayload,
260 typename ResponseUserHeader>
264 iox2_pending_response_h pending_response_handle {};
265 auto result = iox2_request_mut_send(request.m_handle, nullptr, &pending_response_handle);
266 request.m_handle = nullptr;
267
268 if (result == IOX2_OK) {
270 pending_response_handle);
271 }
272 return bb::err(bb::into<RequestSendError>(result));
273}
274
275template <ServiceType Service,
276 typename RequestPayload,
277 typename RequestUserHeader,
278 typename ResponsePayload,
279 typename ResponseUserHeader>
280inline void RequestMut<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::drop() {
281 if (m_handle != nullptr) {
282 iox2_request_mut_drop(m_handle);
283 m_handle = nullptr;
284 }
285}
286
287} // namespace iox2
288
289#endif
Sends [RequestMut]s to a [Server] in a request-response based communication.
Definition client.hpp:31
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 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.
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
RequestSendError
Failure that can be emitted when a [RequestMut] is sent.