iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
client.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_CLIENT_HPP
14#define IOX2_CLIENT_HPP
15
16#include "iox2/bb/expected.hpp"
17#include "iox2/bb/slice.hpp"
19#include "iox2/payload_info.hpp"
21#include "iox2/service_type.hpp"
23
24namespace iox2 {
26template <ServiceType Service,
27 typename RequestPayload,
28 typename RequestUserHeader,
29 typename ResponsePayload,
30 typename ResponseUserHeader>
31class Client {
32 using ValueType = typename PayloadInfo<RequestPayload>::ValueType;
33
34 public:
35 Client(Client&& rhs) noexcept;
36 auto operator=(Client&& rhs) noexcept -> Client&;
37 ~Client() noexcept;
38
39 Client(const Client&) noexcept = delete;
40 auto operator=(const Client&) noexcept -> Client& = delete;
41
43 auto id() const -> UniqueClientId;
44
48
50 auto max_active_requests() const -> uint64_t;
51
53 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
54 auto initial_max_slice_len() const -> uint64_t;
55
59 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
60 auto send_copy(const RequestPayload& payload) const -> bb::Expected<
61 PendingResponse<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>,
63
67 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
68 auto send_slice_copy(bb::ImmutableSlice<ValueType>& payload) const -> bb::Expected<
69 PendingResponse<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>,
71
74 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
75 auto loan_uninit() -> bb::Expected<
76 RequestMutUninit<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>,
77 LoanError>;
78
81 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
82 auto loan_slice_uninit(uint64_t number_of_elements)
83 -> bb::Expected<RequestMutUninit<Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader>,
84 LoanError>;
85
89 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
90 auto loan()
91 -> bb::Expected<RequestMut<Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader>, LoanError>;
92
96 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
97 auto loan_slice(uint64_t number_of_elements)
98 -> bb::Expected<RequestMut<Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader>, LoanError>;
99
100 private:
101 template <ServiceType, typename, typename, typename, typename>
102 friend class PortFactoryClient;
103
104 explicit Client(iox2_client_h handle) noexcept;
105
106 void drop();
107
108 iox2_client_h m_handle = nullptr;
109};
110
111template <ServiceType Service,
112 typename RequestPayload,
113 typename RequestUserHeader,
114 typename ResponsePayload,
115 typename ResponseUserHeader>
116inline Client<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::Client(
117 Client&& rhs) noexcept {
118 *this = std::move(rhs);
119}
120
121template <ServiceType Service,
122 typename RequestPayload,
123 typename RequestUserHeader,
124 typename ResponsePayload,
125 typename ResponseUserHeader>
127 Client&& rhs) noexcept -> Client& {
128 if (this != &rhs) {
129 drop();
130 m_handle = rhs.m_handle;
131 rhs.m_handle = nullptr;
132 }
133
134 return *this;
135}
136
137template <ServiceType Service,
138 typename RequestPayload,
139 typename RequestUserHeader,
140 typename ResponsePayload,
141 typename ResponseUserHeader>
145
146template <ServiceType Service,
147 typename RequestPayload,
148 typename RequestUserHeader,
149 typename ResponsePayload,
150 typename ResponseUserHeader>
152 -> UniqueClientId {
153 iox2_unique_client_id_h id_handle = nullptr;
154 iox2_client_id(&m_handle, nullptr, &id_handle);
155 return UniqueClientId { id_handle };
156}
157
158template <ServiceType Service,
159 typename RequestPayload,
160 typename RequestUserHeader,
161 typename ResponsePayload,
162 typename ResponseUserHeader>
163inline auto
166 return iox2::bb::into<BackpressureStrategy>(static_cast<int>(iox2_client_backpressure_strategy(&m_handle)));
167}
168
169template <ServiceType Service,
170 typename RequestPayload,
171 typename RequestUserHeader,
172 typename ResponsePayload,
173 typename ResponseUserHeader>
174inline auto
176 -> uint64_t {
177 return iox2_client_max_active_requests(&m_handle);
178}
179
180template <ServiceType Service,
181 typename RequestPayload,
182 typename RequestUserHeader,
183 typename ResponsePayload,
184 typename ResponseUserHeader>
185template <typename T, typename>
186inline auto
188 -> uint64_t {
189 return iox2_client_initial_max_slice_len(&m_handle);
190}
191
192template <ServiceType Service,
193 typename RequestPayload,
194 typename RequestUserHeader,
195 typename ResponsePayload,
196 typename ResponseUserHeader>
197template <typename T, typename>
200 LoanError> {
201 constexpr uint64_t NUMBER_OF_ELEMENTS = 1;
203 auto result = iox2_client_loan_slice_uninit(
204 &m_handle, &request.m_request.m_request, &request.m_request.m_handle, NUMBER_OF_ELEMENTS);
206 if (result == IOX2_OK) {
207 return request;
208 }
209 return bb::err(bb::into<LoanError>(result));
210}
211
212template <ServiceType Service,
213 typename RequestPayload,
214 typename RequestUserHeader,
215 typename ResponsePayload,
216 typename ResponseUserHeader>
217template <typename T, typename>
219 uint64_t number_of_elements)
222 auto result = iox2_client_loan_slice_uninit(
223 &m_handle, &request.m_request.m_request, &request.m_request.m_handle, number_of_elements);
225 if (result == IOX2_OK) {
226 return request;
227 }
228 return bb::err(bb::into<LoanError>(result));
229}
230
231template <ServiceType Service,
232 typename RequestPayload,
233 typename RequestUserHeader,
234 typename ResponsePayload,
235 typename ResponseUserHeader>
236template <typename T, typename>
238 const RequestPayload& payload) const
241 static_assert(std::is_trivially_copyable<RequestPayload>::value,
242 "The client supports only trivially copyable request payload types.");
243
244 iox2_pending_response_h pending_response_handle {};
245 auto result = iox2_client_send_copy(
246 &m_handle, static_cast<const void*>(&payload), sizeof(RequestPayload), 1, nullptr, &pending_response_handle);
247
248 if (result == IOX2_OK) {
250 pending_response_handle);
251 }
252
253 return bb::err(bb::into<RequestSendError>(result));
254}
255
256template <ServiceType Service,
257 typename RequestPayload,
258 typename RequestUserHeader,
259 typename ResponsePayload,
260 typename ResponseUserHeader>
261template <typename T, typename>
263 bb::ImmutableSlice<ValueType>& payload) const
266 static_assert(std::is_trivially_copyable<ValueType>::value,
267 "The client supports only trivially copyable request payload types.");
268
269 iox2_pending_response_h pending_response_handle {};
270 auto result = iox2_client_send_copy(&m_handle,
271 payload.data(),
272 sizeof(typename RequestPayload::ValueType),
273 payload.number_of_elements(),
274 nullptr,
275 &pending_response_handle);
276
277 if (result == IOX2_OK) {
279 pending_response_handle);
280 }
281
282 return bb::err(bb::into<RequestSendError>(result));
283}
284
285template <ServiceType Service,
286 typename RequestPayload,
287 typename RequestUserHeader,
288 typename ResponsePayload,
289 typename ResponseUserHeader>
290template <typename T, typename>
293 auto request = loan_uninit();
294 if (!request.has_value()) {
295 return bb::err(request.error());
296 }
297
298 new (&request->payload_mut()) RequestPayload();
299 return assume_init(std::move(*request));
300}
301
302template <ServiceType Service,
303 typename RequestPayload,
304 typename RequestUserHeader,
305 typename ResponsePayload,
306 typename ResponseUserHeader>
307template <typename T, typename>
309 uint64_t number_of_elements)
311 auto request_uninit = loan_slice_uninit(number_of_elements);
312 if (!request_uninit.has_value()) {
313 return bb::err(request_uninit.error());
314 }
315
316 auto request_init = std::move(request_uninit.value());
317 for (auto& item : request_init.payload_mut()) {
318 new (&item) ValueType();
319 }
320
321 return assume_init(std::move(request_init));
322}
323
324template <ServiceType Service,
325 typename RequestPayload,
326 typename RequestUserHeader,
327 typename ResponsePayload,
328 typename ResponseUserHeader>
330 iox2_client_h handle) noexcept
331 : m_handle { handle } {
332}
333
334template <ServiceType Service,
335 typename RequestPayload,
336 typename RequestUserHeader,
337 typename ResponsePayload,
338 typename ResponseUserHeader>
339inline void Client<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::drop() {
340 if (m_handle != nullptr) {
341 iox2_client_drop(m_handle);
342 m_handle = nullptr;
343 }
344}
345} // namespace iox2
346
347#endif
Sends [RequestMut]s to a [Server] in a request-response based communication.
Definition client.hpp:31
auto loan_slice_uninit(uint64_t number_of_elements) -> bb::Expected< RequestMutUninit< Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader >, LoanError >
Definition client.hpp:218
Client(const Client &) noexcept=delete
auto backpressure_strategy() const -> BackpressureStrategy
Definition client.hpp:164
auto loan_slice(uint64_t number_of_elements) -> bb::Expected< RequestMut< Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader >, LoanError >
Definition client.hpp:308
auto send_slice_copy(bb::ImmutableSlice< ValueType > &payload) const -> bb::Expected< PendingResponse< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >, RequestSendError >
Definition client.hpp:262
Client(Client &&rhs) noexcept
Definition client.hpp:116
auto operator=(const Client &) noexcept -> Client &=delete
auto loan_uninit() -> bb::Expected< RequestMutUninit< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >, LoanError >
Definition client.hpp:198
auto loan() -> bb::Expected< RequestMut< Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader >, LoanError >
Definition client.hpp:291
auto send_copy(const RequestPayload &payload) const -> bb::Expected< PendingResponse< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >, RequestSendError >
Definition client.hpp:237
auto operator=(Client &&rhs) noexcept -> Client &
Definition client.hpp:126
auto id() const -> UniqueClientId
Returns the [UniqueClientId] of the [Client].
Definition client.hpp:151
auto max_active_requests() const -> uint64_t
Returns the maximal active requests a [Client] can send.
Definition client.hpp:175
~Client() noexcept
Definition client.hpp:142
auto initial_max_slice_len() const -> uint64_t
Returns the maximum number of elements that can be loaned in a slice.
Definition client.hpp:187
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 >
RequestSendError
Failure that can be emitted when a [RequestMut] is sent.
static void placement_default(S &payload)
Definition helper.hpp:22