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"
20#include "iox2/port_name.hpp"
22#include "iox2/service_type.hpp"
24
25namespace iox2 {
27template <ServiceType Service,
28 typename RequestPayload,
29 typename RequestUserHeader,
30 typename ResponsePayload,
31 typename ResponseUserHeader>
32class Client {
33 using ValueType = typename PayloadInfo<RequestPayload>::ValueType;
34
35 public:
36 Client(Client&& rhs) noexcept;
37 auto operator=(Client&& rhs) noexcept -> Client&;
38 ~Client() noexcept;
39
40 Client(const Client&) noexcept = delete;
41 auto operator=(const Client&) noexcept -> Client& = delete;
42
44 auto id() const -> UniqueClientId;
45
47 auto name() const -> PortNameView;
48
52
54 auto max_active_requests() const -> uint64_t;
55
57 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
58 auto initial_max_slice_len() const -> uint64_t;
59
63 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
64 auto send_copy(const RequestPayload& payload) const -> bb::Expected<
65 PendingResponse<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>,
67
71 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
72 auto send_slice_copy(bb::ImmutableSlice<ValueType>& payload) const -> bb::Expected<
73 PendingResponse<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>,
75
78 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
79 auto loan_uninit() -> bb::Expected<
80 RequestMutUninit<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>,
81 LoanError>;
82
85 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
86 auto loan_slice_uninit(uint64_t number_of_elements)
87 -> bb::Expected<RequestMutUninit<Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader>,
88 LoanError>;
89
93 template <typename T = RequestPayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
94 auto loan()
95 -> bb::Expected<RequestMut<Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader>, LoanError>;
96
100 template <typename T = RequestPayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
101 auto loan_slice(uint64_t number_of_elements)
102 -> bb::Expected<RequestMut<Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader>, LoanError>;
103
104 private:
105 template <ServiceType, typename, typename, typename, typename>
106 friend class PortFactoryClient;
107
108 explicit Client(iox2_client_h handle) noexcept;
109
110 void drop();
111
112 iox2_client_h m_handle = nullptr;
113};
114
115template <ServiceType Service,
116 typename RequestPayload,
117 typename RequestUserHeader,
118 typename ResponsePayload,
119 typename ResponseUserHeader>
120inline Client<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::Client(
121 Client&& rhs) noexcept {
122 *this = std::move(rhs);
123}
124
125template <ServiceType Service,
126 typename RequestPayload,
127 typename RequestUserHeader,
128 typename ResponsePayload,
129 typename ResponseUserHeader>
131 Client&& rhs) noexcept -> Client& {
132 if (this != &rhs) {
133 drop();
134 m_handle = rhs.m_handle;
135 rhs.m_handle = nullptr;
136 }
137
138 return *this;
139}
140
141template <ServiceType Service,
142 typename RequestPayload,
143 typename RequestUserHeader,
144 typename ResponsePayload,
145 typename ResponseUserHeader>
149
150template <ServiceType Service,
151 typename RequestPayload,
152 typename RequestUserHeader,
153 typename ResponsePayload,
154 typename ResponseUserHeader>
156 -> UniqueClientId {
157 iox2_unique_client_id_h id_handle = nullptr;
158 iox2_client_id(&m_handle, nullptr, &id_handle);
159 return UniqueClientId { id_handle };
160}
161
162template <ServiceType Service,
163 typename RequestPayload,
164 typename RequestHeader,
165 typename ResponsePayload,
166 typename ResponseHeader>
168 -> PortNameView {
169 const auto* port_name_ptr = iox2_client_name(&m_handle);
170 return PortNameView::from_native_ptr(port_name_ptr);
171}
172
173template <ServiceType Service,
174 typename RequestPayload,
175 typename RequestUserHeader,
176 typename ResponsePayload,
177 typename ResponseUserHeader>
178inline auto
181 return iox2::bb::into<BackpressureStrategy>(static_cast<int>(iox2_client_backpressure_strategy(&m_handle)));
182}
183
184template <ServiceType Service,
185 typename RequestPayload,
186 typename RequestUserHeader,
187 typename ResponsePayload,
188 typename ResponseUserHeader>
189inline auto
191 -> uint64_t {
192 return iox2_client_max_active_requests(&m_handle);
193}
194
195template <ServiceType Service,
196 typename RequestPayload,
197 typename RequestUserHeader,
198 typename ResponsePayload,
199 typename ResponseUserHeader>
200template <typename T, typename>
201inline auto
203 -> uint64_t {
204 return iox2_client_initial_max_slice_len(&m_handle);
205}
206
207template <ServiceType Service,
208 typename RequestPayload,
209 typename RequestUserHeader,
210 typename ResponsePayload,
211 typename ResponseUserHeader>
212template <typename T, typename>
215 LoanError> {
216 constexpr uint64_t NUMBER_OF_ELEMENTS = 1;
218 auto result = iox2_client_loan_slice_uninit(
219 &m_handle, &request.m_request.m_request, &request.m_request.m_handle, NUMBER_OF_ELEMENTS);
221 if (result == IOX2_OK) {
222 return request;
223 }
224 return bb::err(bb::into<LoanError>(result));
225}
226
227template <ServiceType Service,
228 typename RequestPayload,
229 typename RequestUserHeader,
230 typename ResponsePayload,
231 typename ResponseUserHeader>
232template <typename T, typename>
234 uint64_t number_of_elements)
237 auto result = iox2_client_loan_slice_uninit(
238 &m_handle, &request.m_request.m_request, &request.m_request.m_handle, number_of_elements);
240 if (result == IOX2_OK) {
241 return request;
242 }
243 return bb::err(bb::into<LoanError>(result));
244}
245
246template <ServiceType Service,
247 typename RequestPayload,
248 typename RequestUserHeader,
249 typename ResponsePayload,
250 typename ResponseUserHeader>
251template <typename T, typename>
253 const RequestPayload& payload) const
256 static_assert(std::is_trivially_copyable<RequestPayload>::value,
257 "The client supports only trivially copyable request payload types.");
258
259 iox2_pending_response_h pending_response_handle {};
260 auto result = iox2_client_send_copy(
261 &m_handle, static_cast<const void*>(&payload), sizeof(RequestPayload), 1, nullptr, &pending_response_handle);
262
263 if (result == IOX2_OK) {
265 pending_response_handle);
266 }
267
268 return bb::err(bb::into<RequestSendError>(result));
269}
270
271template <ServiceType Service,
272 typename RequestPayload,
273 typename RequestUserHeader,
274 typename ResponsePayload,
275 typename ResponseUserHeader>
276template <typename T, typename>
278 bb::ImmutableSlice<ValueType>& payload) const
281 static_assert(std::is_trivially_copyable<ValueType>::value,
282 "The client supports only trivially copyable request payload types.");
283
284 iox2_pending_response_h pending_response_handle {};
285 auto result = iox2_client_send_copy(&m_handle,
286 payload.data(),
287 sizeof(typename RequestPayload::ValueType),
288 payload.number_of_elements(),
289 nullptr,
290 &pending_response_handle);
291
292 if (result == IOX2_OK) {
294 pending_response_handle);
295 }
296
297 return bb::err(bb::into<RequestSendError>(result));
298}
299
300template <ServiceType Service,
301 typename RequestPayload,
302 typename RequestUserHeader,
303 typename ResponsePayload,
304 typename ResponseUserHeader>
305template <typename T, typename>
308 auto request = loan_uninit();
309 if (!request.has_value()) {
310 return bb::err(request.error());
311 }
312
313 new (&request->payload_mut()) RequestPayload();
314 return assume_init(std::move(*request));
315}
316
317template <ServiceType Service,
318 typename RequestPayload,
319 typename RequestUserHeader,
320 typename ResponsePayload,
321 typename ResponseUserHeader>
322template <typename T, typename>
324 uint64_t number_of_elements)
326 auto request_uninit = loan_slice_uninit(number_of_elements);
327 if (!request_uninit.has_value()) {
328 return bb::err(request_uninit.error());
329 }
330
331 auto request_init = std::move(request_uninit.value());
332 for (auto& item : request_init.payload_mut()) {
333 new (&item) ValueType();
334 }
335
336 return assume_init(std::move(request_init));
337}
338
339template <ServiceType Service,
340 typename RequestPayload,
341 typename RequestUserHeader,
342 typename ResponsePayload,
343 typename ResponseUserHeader>
345 iox2_client_h handle) noexcept
346 : m_handle { handle } {
347}
348
349template <ServiceType Service,
350 typename RequestPayload,
351 typename RequestUserHeader,
352 typename ResponsePayload,
353 typename ResponseUserHeader>
354inline void Client<Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader>::drop() {
355 if (m_handle != nullptr) {
356 iox2_client_drop(m_handle);
357 m_handle = nullptr;
358 }
359}
360} // namespace iox2
361
362#endif
Sends [RequestMut]s to a [Server] in a request-response based communication.
Definition client.hpp:32
auto loan_slice_uninit(uint64_t number_of_elements) -> bb::Expected< RequestMutUninit< Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader >, LoanError >
Definition client.hpp:233
Client(const Client &) noexcept=delete
auto backpressure_strategy() const -> BackpressureStrategy
Definition client.hpp:179
auto loan_slice(uint64_t number_of_elements) -> bb::Expected< RequestMut< Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader >, LoanError >
Definition client.hpp:323
auto send_slice_copy(bb::ImmutableSlice< ValueType > &payload) const -> bb::Expected< PendingResponse< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >, RequestSendError >
Definition client.hpp:277
Client(Client &&rhs) noexcept
Definition client.hpp:120
auto operator=(const Client &) noexcept -> Client &=delete
auto loan_uninit() -> bb::Expected< RequestMutUninit< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >, LoanError >
Definition client.hpp:213
auto loan() -> bb::Expected< RequestMut< Service, T, RequestUserHeader, ResponsePayload, ResponseUserHeader >, LoanError >
Definition client.hpp:306
auto send_copy(const RequestPayload &payload) const -> bb::Expected< PendingResponse< Service, RequestPayload, RequestUserHeader, ResponsePayload, ResponseUserHeader >, RequestSendError >
Definition client.hpp:252
auto name() const -> PortNameView
Returns the [PortNameView] of the [Client].
Definition client.hpp:167
auto operator=(Client &&rhs) noexcept -> Client &
Definition client.hpp:130
auto id() const -> UniqueClientId
Returns the [UniqueClientId] of the [Client].
Definition client.hpp:155
auto max_active_requests() const -> uint64_t
Returns the maximal active requests a [Client] can send.
Definition client.hpp:190
~Client() noexcept
Definition client.hpp:146
auto initial_max_slice_len() const -> uint64_t
Returns the maximum number of elements that can be loaned in a slice.
Definition client.hpp:202
Non-owning view of a [PortName].
Definition port_name.hpp:25
static auto from_native_ptr(iox2_port_name_ptr m_ptr) -> PortNameView
Creates a [PortNameView] from a native [iox2_port_name_ptr].
Request header used by [MessagingPattern::RequestResponse].
Response 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 >
RequestSendError
Failure that can be emitted when a [RequestMut] is sent.
static void placement_default(S &payload)
Definition helper.hpp:22