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