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