COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
Bundle.h
1//
2// Copyright 2015 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: MPL-2.0
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#pragma once
11
12#include "comms/Assert.h"
13#include "comms/ErrorStatus.h"
14#include "comms/field/basic/CommonFuncs.h"
15#include "comms/field/details/FieldOpHelpers.h"
16#include "comms/field/details/MembersVersionDependency.h"
17#include "comms/field/tag.h"
18#include "comms/util/Tuple.h"
19
20#include <cstddef>
21#include <tuple>
22#include <utility>
23
24namespace comms
25{
26
27namespace field
28{
29
30namespace basic
31{
32
33namespace details
34{
35
36template <comms::field::details::MembersVersionDependency TVersionDependency, typename... TMembers>
37struct BundleVersionDependencyDetectHelper;
38
39template <typename... TMembers>
40struct BundleVersionDependencyDetectHelper<comms::field::details::MembersVersionDependency_NotSpecified, TMembers...>
41{
42 static constexpr bool Value = CommonFuncs::IsAnyFieldVersionDependentBoolType<TMembers...>::value;
43};
44
45template <typename... TMembers>
46struct BundleVersionDependencyDetectHelper<comms::field::details::MembersVersionDependency_Independent, TMembers...>
47{
48 static constexpr bool Value = false;
49};
50
51template <typename... TMembers>
52struct BundleVersionDependencyDetectHelper<comms::field::details::MembersVersionDependency_Dependent, TMembers...>
53{
54 static constexpr bool Value = true;
55};
56
57} // namespace details
58
59template <typename TFieldBase, comms::field::details::MembersVersionDependency TVersionDependency, typename TMembers>
60class Bundle;
61
62template <typename TFieldBase, comms::field::details::MembersVersionDependency TVersionDependency, typename... TMembers>
63class Bundle<TFieldBase, TVersionDependency, std::tuple<TMembers...> > : public TFieldBase
64{
65public:
66 using ValueType = std::tuple<TMembers...>;
67 using Members = ValueType;
68 using VersionType = typename TFieldBase::VersionType;
69 using CommsTag = comms::field::tag::Bundle;
70
71 Bundle() = default;
72 explicit Bundle(const ValueType& val)
73 : m_members(val)
74 {
75 }
76
77 explicit Bundle(ValueType&& val)
78 : m_members(std::move(val))
79 {
80 }
81
82 Bundle(const Bundle&) = default;
83 Bundle(Bundle&&) = default;
84 ~Bundle() noexcept = default;
85
86 Bundle& operator=(const Bundle&) = default;
87 Bundle& operator=(Bundle&&) = default;
88
89 const ValueType& value() const
90 {
91 return m_members;
92 }
93
94 ValueType& value()
95 {
96 return m_members;
97 }
98
99 const ValueType& getValue() const
100 {
101 return value();
102 }
103
104 template <typename T>
105 void setValue(T&& val)
106 {
107 value() = std::forward<T>(val);
108 }
109
110 constexpr std::size_t length() const
111 {
113 value(), std::size_t(0), comms::field::details::FieldLengthSumCalcHelper<>());
114 }
115
116 template <std::size_t TFromIdx>
117 constexpr std::size_t lengthFrom() const
118 {
119 return
120 comms::util::tupleAccumulateFromUntil<TFromIdx, std::tuple_size<ValueType>::value>(
121 value(),
122 std::size_t(0),
123 comms::field::details::FieldLengthSumCalcHelper<>());
124 }
125
126 template <std::size_t TUntilIdx>
127 constexpr std::size_t lengthUntil() const
128 {
129 return
130 comms::util::tupleAccumulateFromUntil<0, TUntilIdx>(
131 value(),
132 std::size_t(0),
133 comms::field::details::FieldLengthSumCalcHelper<>());
134 }
135
136 template <std::size_t TFromIdx, std::size_t TUntilIdx>
137 constexpr std::size_t lengthFromUntil() const
138 {
139 return
140 comms::util::tupleAccumulateFromUntil<TFromIdx, TUntilIdx>(
141 value(),
142 std::size_t(0),
143 comms::field::details::FieldLengthSumCalcHelper<>());
144 }
145
146 static constexpr std::size_t minLength()
147 {
148 return
149 comms::util::tupleTypeAccumulate<Members>(
150 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
151 }
152
153 template <std::size_t TFromIdx>
154 static constexpr std::size_t minLengthFrom()
155 {
156 return
157 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, std::tuple_size<ValueType>::value, Members>(
158 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
159 }
160
161 template <std::size_t TUntilIdx>
162 static constexpr std::size_t minLengthUntil()
163 {
164 return
165 comms::util::tupleTypeAccumulateFromUntil<0, TUntilIdx, Members>(
166 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
167 }
168
169 template <std::size_t TFromIdx, std::size_t TUntilIdx>
170 static constexpr std::size_t minLengthFromUntil()
171 {
172 return
173 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, TUntilIdx, Members>(
174 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
175 }
176
177 static constexpr std::size_t maxLength()
178 {
179 return
180 comms::util::tupleTypeAccumulate<Members>(
181 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
182 }
183
184 template <std::size_t TFromIdx>
185 static constexpr std::size_t maxLengthFrom()
186 {
187 return
188 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, std::tuple_size<ValueType>::value, Members>(
189 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
190 }
191
192 template <std::size_t TUntilIdx>
193 static constexpr std::size_t maxLengthUntil()
194 {
195 return
196 comms::util::tupleTypeAccumulateFromUntil<0, TUntilIdx, Members>(
197 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
198 }
199
200 template <std::size_t TFromIdx, std::size_t TUntilIdx>
201 static constexpr std::size_t maxLengthFromUntil()
202 {
203 return
204 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, TUntilIdx, Members>(
205 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
206 }
207
208 constexpr bool valid() const
209 {
210 return comms::util::tupleAccumulate(value(), true, comms::field::details::FieldValidCheckHelper<>());
211 }
212
213 bool refresh()
214 {
215 return comms::util::tupleAccumulate(value(), false, comms::field::details::FieldRefreshHelper<>());
216 }
217
218 template <typename TIter>
219 ErrorStatus read(TIter& iter, std::size_t len)
220 {
221 auto es = ErrorStatus::Success;
222 comms::util::tupleForEach(value(), makeReadHelper(es, iter, len));
223 return es;
224 }
225
226 template <std::size_t TFromIdx, typename TIter>
227 ErrorStatus readFrom(TIter& iter, std::size_t len)
228 {
229 return readFromAndUpdateLen<TFromIdx>(iter, len);
230 }
231
232 template <std::size_t TFromIdx, typename TIter>
233 ErrorStatus readFromAndUpdateLen(TIter& iter, std::size_t& len)
234 {
235 auto es = ErrorStatus::Success;
236 comms::util::template tupleForEachFrom<TFromIdx>(value(), makeReadHelper(es, iter, len));
237 return es;
238 }
239
240 template <std::size_t TUntilIdx, typename TIter>
241 ErrorStatus readUntil(TIter& iter, std::size_t len)
242 {
243 return readUntilAndUpdateLen<TUntilIdx>(iter, len);
244 }
245
246 template <std::size_t TUntilIdx, typename TIter>
247 ErrorStatus readUntilAndUpdateLen(TIter& iter, std::size_t& len)
248 {
249 auto es = ErrorStatus::Success;
250 comms::util::template tupleForEachUntil<TUntilIdx>(value(), makeReadHelper(es, iter, len));
251 return es;
252 }
253
254 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
255 ErrorStatus readFromUntil(TIter& iter, std::size_t len)
256 {
257 return readFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
258 }
259
260 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
261 ErrorStatus readFromUntilAndUpdateLen(TIter& iter, std::size_t& len)
262 {
263 auto es = ErrorStatus::Success;
264 comms::util::template tupleForEachFromUntil<TFromIdx, TUntilIdx>(value(), makeReadHelper(es, iter, len));
265 return es;
266 }
267
268 static constexpr bool hasReadNoStatus()
269 {
270 return CommonFuncs::AllFieldsHaveReadNoStatusBoolType<TMembers...>::value;
271 }
272
273 template <typename TIter>
274 void readNoStatus(TIter& iter)
275 {
276 comms::util::tupleForEach(value(), makeReadNoStatusHelper(iter));
277 }
278
279 template <std::size_t TFromIdx, typename TIter>
280 void readFromNoStatus(TIter& iter)
281 {
282 comms::util::template tupleForEachFrom<TFromIdx>(value(), makeReadNoStatusHelper(iter));
283 }
284
285 template <std::size_t TUntilIdx, typename TIter>
286 void readUntilNoStatus(TIter& iter)
287 {
288 comms::util::template tupleForEachUntil<TUntilIdx>(value(), makeReadNoStatusHelper(iter));
289 }
290
291 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
292 void readFromUntilNoStatus(TIter& iter)
293 {
294 comms::util::template tupleForEachFromUntil<TFromIdx, TUntilIdx>(value(), makeReadNoStatusHelper(iter));
295 }
296
297 bool canWrite() const
298 {
299 return
301 value(), true, comms::field::details::FieldCanWriteCheckHelper<>());
302 }
303
304 template <typename TIter>
305 ErrorStatus write(TIter& iter, std::size_t len) const
306 {
307 auto es = ErrorStatus::Success;
308 comms::util::tupleForEach(value(), makeWriteHelper(es, iter, len));
309 return es;
310 }
311
312 template <std::size_t TFromIdx, typename TIter>
313 ErrorStatus writeFrom(TIter& iter, std::size_t len) const
314 {
315 auto es = ErrorStatus::Success;
316 comms::util::template tupleForEachFrom<TFromIdx>(value(), makeWriteHelper(es, iter, len));
317 return es;
318 }
319
320 template <std::size_t TUntilIdx, typename TIter>
321 ErrorStatus writeUntil(TIter& iter, std::size_t len) const
322 {
323 auto es = ErrorStatus::Success;
324 comms::util::template tupleForEachUntil<TUntilIdx>(value(), makeWriteHelper(es, iter, len));
325 return es;
326 }
327
328 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
329 ErrorStatus writeFromUntil(TIter& iter, std::size_t len) const
330 {
331 auto es = ErrorStatus::Success;
332 comms::util::template tupleForEachFromUntil<TFromIdx, TUntilIdx>(value(), makeWriteHelper(es, iter, len));
333 return es;
334 }
335
336 static constexpr bool hasWriteNoStatus()
337 {
338 return CommonFuncs::AllFieldsHaveWriteNoStatusBoolType<TMembers...>::value;
339 }
340
341 template <typename TIter>
342 void writeNoStatus(TIter& iter) const
343 {
344 comms::util::tupleForEach(value(), makeWriteNoStatusHelper(iter));
345 }
346
347 template <std::size_t TFromIdx, typename TIter>
348 void writeFromNoStatus(TIter& iter) const
349 {
350 comms::util::template tupleForEachFrom<TFromIdx>(value(), makeWriteNoStatusHelper(iter));
351 }
352
353 template <std::size_t TUntilIdx, typename TIter>
354 void writeUntilNoStatus(TIter& iter) const
355 {
356 comms::util::template tupleForEachUntil<TUntilIdx>(value(), makeWriteNoStatusHelper(iter));
357 }
358
359 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
360 void writeFromUntilNoStatus(TIter& iter) const
361 {
362 comms::util::template tupleForEachFromUntil<TFromIdx, TUntilIdx>(value(), makeWriteNoStatusHelper(iter));
363 }
364
365 static constexpr bool isVersionDependent()
366 {
367 return details::BundleVersionDependencyDetectHelper<TVersionDependency, TMembers...>::Value;
368 }
369
370 static constexpr bool hasNonDefaultRefresh()
371 {
372 return CommonFuncs::AnyFieldHasNonDefaultRefreshBoolType<TMembers...>::value;
373 }
374
375 bool setVersion(VersionType version)
376 {
377 return CommonFuncs::setVersionForMembers(value(), version);
378 }
379
380private:
381 template <typename TIter>
382 static comms::field::details::FieldReadHelper<TIter> makeReadHelper(comms::ErrorStatus& es, TIter& iter, std::size_t& len)
383 {
384 return comms::field::details::FieldReadHelper<TIter>(es, iter, len);
385 }
386
387 template <typename TIter>
388 static comms::field::details::FieldReadNoStatusHelper<TIter> makeReadNoStatusHelper(TIter& iter)
389 {
390 return comms::field::details::FieldReadNoStatusHelper<TIter>(iter);
391 }
392
393 template <typename TIter>
394 static comms::field::details::FieldWriteHelper<TIter> makeWriteHelper(ErrorStatus& es, TIter& iter, std::size_t len)
395 {
396 return comms::field::details::FieldWriteHelper<TIter>(es, iter, len);
397 }
398
399 template <typename TIter>
400 static comms::field::details::FieldWriteNoStatusHelper<TIter> makeWriteNoStatusHelper(TIter& iter)
401 {
402 return comms::field::details::FieldWriteNoStatusHelper<TIter>(iter);
403 }
404
405 static_assert(comms::util::IsTuple<ValueType>::Value, "ValueType must be tuple");
406 ValueType m_members;
407};
408
409} // namespace basic
410
411} // namespace field
412
413} // namespace comms
414
This file contains classes required for generic custom assertion functionality.
This file contain definition of error statuses used by comms module.
Contains various tuple type manipulation classes and functions.
Contains definition of various tag classes.
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition options.h:1930
void tupleForEach(TTuple &&tuple, TFunc &&func)
Invoke provided functor for every element in the tuple.
Definition Tuple.h:242
constexpr TValue tupleAccumulate(TTuple &&tuple, const TValue &value, TFunc &&func)
Performs "accumulate" algorithm on every element of the tuple.
Definition Tuple.h:587
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:19
@ Success
Used to indicate successful outcome of the operation.
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:66
STL namespace.
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:39