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