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