iceoryx2
C++ Language Bindings
Loading...
Searching...
No Matches
response_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_RESPONSE_MUT_HPP
14#define IOX2_RESPONSE_MUT_HPP
15
16#include "iox2/bb/expected.hpp"
17#include "iox2/bb/slice.hpp"
20#include "iox2/payload_info.hpp"
21#include "iox2/port_error.hpp"
22#include "iox2/service_type.hpp"
23
24#include <type_traits>
25
26namespace iox2 {
27
36template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
37// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) 'm_response' 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<ResponsePayload>::ValueType;
40
41 public:
42 ResponseMut(ResponseMut&& rhs) noexcept;
43 auto operator=(ResponseMut&& rhs) noexcept -> ResponseMut&;
44 ~ResponseMut() noexcept;
45
46 ResponseMut(const ResponseMut&) = delete;
47 auto operator=(const ResponseMut&) -> ResponseMut& = delete;
48
50 auto header() const -> ResponseHeader;
51
53 template <typename T = ResponseUserHeader,
54 typename = std::enable_if_t<!std::is_same<void, ResponseUserHeader>::value, T>>
55 auto user_header() const -> const T&;
56
58 template <typename T = ResponseUserHeader,
59 typename = std::enable_if_t<!std::is_same<void, ResponseUserHeader>::value, T>>
60 auto user_header_mut() -> T&;
61
63 template <typename T = ResponsePayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
64 auto payload() const -> const ResponsePayload&;
65
67 template <typename T = ResponsePayload, typename = std::enable_if_t<bb::IsSlice<T>::VALUE, void>>
68 auto payload() const -> bb::ImmutableSlice<ValueType>;
69
71 template <typename T = ResponsePayload, typename = std::enable_if_t<!bb::IsSlice<T>::VALUE, void>>
72 auto payload_mut() -> ResponsePayload&;
73
75 template <typename T = ResponsePayload, 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>
80 friend class ResponseMutUninit;
81 template <ServiceType, typename, typename, typename, typename>
82 friend class ActiveRequest;
83
86 template <ServiceType S, typename ResponsePayloadT, typename ResponseUserHeaderT>
87 friend auto send(ResponseMut<S, ResponsePayloadT, ResponseUserHeaderT>&& response) -> bb::Expected<void, SendError>;
88
89 explicit ResponseMut() = default;
90 void drop();
91
92 iox2_response_mut_t m_response;
93 iox2_response_mut_h m_handle = nullptr;
94};
95
96// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init,hicpp-member-init) m_response will be initialized in the move assignment operator
97template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
98inline ResponseMut<Service, ResponsePayload, ResponseUserHeader>::ResponseMut(ResponseMut&& rhs) noexcept {
99 *this = std::move(rhs);
100}
101
102namespace internal {
103extern "C" {
104void iox2_response_mut_move(iox2_response_mut_t*, iox2_response_mut_t*, iox2_response_mut_h*);
105}
106} // namespace internal
107
108template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
110 -> ResponseMut& {
111 if (this != &rhs) {
112 drop();
113
114 internal::iox2_response_mut_move(&rhs.m_response, &m_response, &m_handle);
115 rhs.m_handle = nullptr;
116 }
117
118 return *this;
119}
120
121template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
125
126template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
128 iox2_response_header_h header_handle = nullptr;
129 iox2_response_mut_header(&m_handle, nullptr, &header_handle);
130 return ResponseHeader { header_handle };
131}
132
133template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
134template <typename T, typename>
136 const void* ptr = nullptr;
137 iox2_response_mut_user_header(&m_handle, &ptr);
138 return *static_cast<const T*>(ptr);
139}
140
141template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
142template <typename T, typename>
144 void* ptr = nullptr;
145 iox2_response_mut_user_header_mut(&m_handle, &ptr);
146 return *static_cast<T*>(ptr);
147}
148
149template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
150template <typename T, typename>
151inline auto ResponseMut<Service, ResponsePayload, ResponseUserHeader>::payload() const -> const ResponsePayload& {
152 const void* ptr = nullptr;
153 iox2_response_mut_payload(&m_handle, &ptr, nullptr);
154 return *static_cast<const T*>(ptr);
155}
156
157template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
158template <typename T, typename>
160 -> bb::ImmutableSlice<ValueType> {
161 const void* ptr = nullptr;
162 size_t number_of_elements = 0;
163 iox2_response_mut_payload(&m_handle, &ptr, &number_of_elements);
164
165 // for the custom payload marker, the slice length is the
166 // runtime payload byte size
167 auto length = number_of_elements;
168 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
169 length = iox2_response_mut_payload_number_of_bytes(&m_handle);
170 }
171
172 return bb::ImmutableSlice<ValueType>(static_cast<const ValueType*>(ptr), length);
173}
174
175template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
176template <typename T, typename>
178 void* ptr = nullptr;
179 iox2_response_mut_payload_mut(&m_handle, &ptr, nullptr);
180 return *static_cast<ResponsePayload*>(ptr);
181}
182
183template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
184template <typename T, typename>
186 void* ptr = nullptr;
187 size_t number_of_elements = 0;
188 iox2_response_mut_payload_mut(&m_handle, &ptr, &number_of_elements);
189
190 // for the custom payload marker, the slice length is the
191 // runtime payload byte size
192 auto length = number_of_elements;
193 if (std::is_same<ValueType, CustomPayloadMarker>::value) {
194 length = iox2_response_mut_payload_number_of_bytes(&m_handle);
195 }
196
197 return bb::MutableSlice<ValueType>(static_cast<ValueType*>(ptr), length);
198}
199
200
201template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
204 auto result = iox2_response_mut_send(response.m_handle);
205 response.m_handle = nullptr;
206
207 if (result == IOX2_OK) {
208 return {};
209 }
210 return bb::err(bb::into<SendError>(result));
211}
212
213template <ServiceType Service, typename ResponsePayload, typename ResponseUserHeader>
214inline void ResponseMut<Service, ResponsePayload, ResponseUserHeader>::drop() {
215 if (m_handle != nullptr) {
216 iox2_response_mut_drop(m_handle);
217 m_handle = nullptr;
218 }
219}
220
221} // namespace iox2
222
223#endif
Response header used by [MessagingPattern::RequestResponse].
friend auto send(ResponseMut< S, ResponsePayloadT, ResponseUserHeaderT > &&response) -> bb::Expected< void, SendError >
auto header() const -> ResponseHeader
Returns a reference to the [ResponseHeader].
auto user_header() const -> const T &
Returns a reference to the user header of the response.
auto user_header_mut() -> T &
Returns a mutable reference to the user header of the response.
auto operator=(ResponseMut &&rhs) noexcept -> ResponseMut &
~ResponseMut() noexcept
auto payload_mut() -> ResponsePayload &
Returns a mutable reference to the payload of the response.
ResponseMut(const ResponseMut &)=delete
auto operator=(const ResponseMut &) -> ResponseMut &=delete
auto payload() const -> const ResponsePayload &
Returns a reference to the payload of the response.
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
SendError
Failure that can be emitted when data is sent.