COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
FieldOpHelpers.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 <limits>
12
14#include "comms/ErrorStatus.h"
15
16COMMS_MSVC_WARNING_PUSH
17COMMS_MSVC_WARNING_DISABLE(4100) // Disable warning about unreferenced parameters
18
19namespace comms
20{
21
22namespace field
23{
24
25namespace details
26{
27
28template <typename...>
29struct FieldVersionDependentCheckHelper
30{
31 template <typename TField>
32 constexpr bool operator()() const
33 {
34 return TField::isVersionDependent();
35 }
36
37 template <typename TField>
38 constexpr bool operator()(bool soFar) const
39 {
40 return TField::isVersionDependent() || soFar;
41 }
42};
43
44template <typename...>
45struct FieldMaxLengthCalcHelper
46{
47 template <typename TField>
48 constexpr std::size_t operator()(std::size_t val) const
49 {
50 return val >= TField::maxLength() ? val : TField::maxLength();
51 }
52};
53
54template <typename...>
55struct FieldMinLengthSumCalcHelper
56{
57 template <typename TField>
58 constexpr std::size_t operator()(std::size_t sum) const
59 {
60 return sum + TField::minLength();
61 }
62};
63
64template <typename...>
65struct FieldMaxLengthSumCalcHelper
66{
67 template <typename TField>
68 constexpr std::size_t operator()(std::size_t sum) const
69 {
70 return sum + TField::maxLength();
71 }
72};
73
74template <bool THasBitLengthLimit>
75struct FieldBitLengthRetrieveHelper
76{
77 template <typename TField>
78 using Type =
79 std::integral_constant<
80 std::size_t,
81 TField::ParsedOptions::FixedBitLength
82 >;
83};
84
85template <>
86struct FieldBitLengthRetrieveHelper<false>
87{
88 template <typename TField>
89 using Type =
90 std::integral_constant<
91 std::size_t,
92 TField::maxLength() * std::numeric_limits<std::uint8_t>::digits
93 >;
94};
95
96
97template <typename...>
98struct FieldTotalBitLengthSumCalcHelper
99{
100 template <typename TField>
101 constexpr std::size_t operator()(std::size_t sum) const
102 {
103 return sum + FieldBitLengthRetrieveHelper<TField::ParsedOptions::HasFixedBitLengthLimit>::template Type<TField>::value;
104 }
105};
106
107template <typename...>
108struct FieldLengthSumCalcHelper
109{
110 template <typename TField>
111 constexpr std::size_t operator()(std::size_t sum, const TField& field) const
112 {
113 return sum + field.length();
114 }
115};
116
117template <typename...>
118struct FieldHasWriteNoStatusHelper
119{
120 constexpr FieldHasWriteNoStatusHelper() = default;
121
122 template <typename TField>
123 constexpr bool operator()(bool soFar) const
124 {
125 return TField::hasWriteNoStatus() && soFar;
126 }
127};
128
129template<typename...>
130struct FieldNonDefaultRefreshCheckHelper
131{
132 template <typename TField>
133 constexpr bool operator()() const
134 {
135 return TField::hasNonDefaultRefresh();
136 }
137
138 template <typename TField>
139 constexpr bool operator()(bool soFar) const
140 {
141 return TField::hasNonDefaultRefresh() || soFar;
142 }
143};
144
145template<typename...>
146struct FieldValidCheckHelper
147{
148 template <typename TField>
149 constexpr bool operator()(bool soFar, const TField& field) const
150 {
151 return soFar && field.valid();
152 }
153};
154
155template <typename...>
156struct FieldRefreshHelper
157{
158 template <typename TField>
159 bool operator()(bool soFar, TField& field) const
160 {
161 return field.refresh() || soFar;
162 }
163};
164
165template <typename TIter>
166class FieldReadHelper
167{
168public:
169 FieldReadHelper(ErrorStatus& es, TIter& iter, std::size_t& len)
170 : es_(es),
171 iter_(iter),
172 len_(len)
173 {
174 }
175
176 template <typename TField>
177 void operator()(TField& field)
178 {
179 if (es_ != comms::ErrorStatus::Success) {
180 return;
181 }
182
183 auto fromIter = iter_;
184 es_ = field.read(iter_, len_);
185 if (es_ == comms::ErrorStatus::Success) {
186 len_ -= static_cast<std::size_t>(std::distance(fromIter, iter_));
187 }
188 }
189
190
191private:
192 ErrorStatus& es_;
193 TIter& iter_;
194 std::size_t& len_;
195};
196
197template <typename TIter>
198class FieldReadNoStatusHelper
199{
200public:
201 FieldReadNoStatusHelper(TIter& iter)
202 : iter_(iter)
203 {
204 }
205
206 template <typename TField>
207 void operator()(TField& field)
208 {
209 field.readNoStatus(iter_);
210 }
211
212private:
213 TIter& iter_;
214};
215
216template <typename TIter>
217class FieldWriteHelper
218{
219public:
220 FieldWriteHelper(ErrorStatus& es, TIter& iter, std::size_t len)
221 : es_(es),
222 iter_(iter),
223 len_(len)
224 {
225 }
226
227 template <typename TField>
228 void operator()(const TField& field)
229 {
230 if (es_ != comms::ErrorStatus::Success) {
231 return;
232 }
233
234 es_ = field.write(iter_, len_);
235 if (es_ == comms::ErrorStatus::Success) {
236 len_ -= field.length();
237 }
238 }
239
240private:
241 ErrorStatus& es_;
242 TIter& iter_;
243 std::size_t len_;
244};
245
246template <typename TIter>
247class FieldWriteNoStatusHelper
248{
249public:
250 FieldWriteNoStatusHelper(TIter& iter)
251 : iter_(iter)
252 {
253 }
254
255 template <typename TField>
256 void operator()(const TField& field)
257 {
258 field.writeNoStatus(iter_);
259 }
260
261private:
262 TIter& iter_;
263};
264
265template <typename...>
266struct FieldReadNoStatusDetectHelper
267{
268 template <typename TField>
269 constexpr bool operator()() const
270 {
271 return TField::hasReadNoStatus();
272 }
273
274 template <typename TField>
275 constexpr bool operator()(bool soFar) const
276 {
277 return TField::hasReadNoStatus() && soFar;
278 }
279};
280
281template<typename...>
282struct FieldWriteNoStatusDetectHelper
283{
284 template <typename TField>
285 constexpr bool operator()() const
286 {
287 return TField::hasWriteNoStatus();
288 }
289
290 template <typename TField>
291 constexpr bool operator()(bool soFar) const
292 {
293 return TField::hasWriteNoStatus() && soFar;
294 }
295};
296
297template <typename...>
298struct FieldCanWriteCheckHelper
299{
300 template <typename TField>
301 constexpr bool operator()(bool soFar, const TField& field) const
302 {
303 return soFar && field.canWrite();
304 }
305};
306
307template <typename TVersionType>
308struct FieldVersionUpdateHelper
309{
310 FieldVersionUpdateHelper(TVersionType version) : version_(version) {}
311
312 template <typename TField>
313 bool operator()(bool updated, TField& field) const
314 {
315 using FieldVersionType = typename std::decay<decltype(field)>::type::VersionType;
316 return field.setVersion(static_cast<FieldVersionType>(version_)) || updated;
317 }
318
319private:
320 const TVersionType version_ = static_cast<TVersionType>(0);
321};
322
323} // namespace details
324
325} // namespace field
326
327} // namespace comms
328
329COMMS_MSVC_WARNING_POP
Contains various compiler related definitions.
This file contain definition of error statuses used by comms module.
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