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
11#include "comms/ErrorStatus.h"
12
13#include <cstdint>
14#include <iterator>
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
98template <typename...>
99struct FieldTotalBitLengthSumCalcHelper
100{
101 template <typename TField>
102 constexpr std::size_t operator()(std::size_t sum) const
103 {
104 return sum + FieldBitLengthRetrieveHelper<TField::ParsedOptions::HasFixedBitLengthLimit>::template Type<TField>::value;
105 }
106};
107
108template <typename...>
109struct FieldLengthSumCalcHelper
110{
111 template <typename TField>
112 constexpr std::size_t operator()(std::size_t sum, const TField& field) const
113 {
114 return sum + field.length();
115 }
116};
117
118template <typename...>
119struct FieldHasWriteNoStatusHelper
120{
121 constexpr FieldHasWriteNoStatusHelper() = default;
122
123 template <typename TField>
124 constexpr bool operator()(bool soFar) const
125 {
126 return TField::hasWriteNoStatus() && soFar;
127 }
128};
129
130template<typename...>
131struct FieldNonDefaultRefreshCheckHelper
132{
133 template <typename TField>
134 constexpr bool operator()() const
135 {
136 return TField::hasNonDefaultRefresh();
137 }
138
139 template <typename TField>
140 constexpr bool operator()(bool soFar) const
141 {
142 return TField::hasNonDefaultRefresh() || soFar;
143 }
144};
145
146template<typename...>
147struct FieldValidCheckHelper
148{
149 template <typename TField>
150 constexpr bool operator()(bool soFar, const TField& field) const
151 {
152 return soFar && field.valid();
153 }
154};
155
156template <typename...>
157struct FieldRefreshHelper
158{
159 template <typename TField>
160 bool operator()(bool soFar, TField& field) const
161 {
162 return field.refresh() || soFar;
163 }
164};
165
166template <typename TIter>
167class FieldReadHelper
168{
169public:
170 FieldReadHelper(ErrorStatus& es, TIter& iter, std::size_t& len) :
171 m_es(es),
172 m_iter(iter),
173 m_len(len)
174 {
175 }
176
177 template <typename TField>
178 void operator()(TField& field)
179 {
180 if (m_es != comms::ErrorStatus::Success) {
181 return;
182 }
183
184 auto fromIter = m_iter;
185 m_es = field.read(m_iter, m_len);
186 if (m_es == comms::ErrorStatus::Success) {
187 m_len -= static_cast<std::size_t>(std::distance(fromIter, m_iter));
188 }
189 }
190
191private:
192 ErrorStatus& m_es;
193 TIter& m_iter;
194 std::size_t& m_len;
195};
196
197template <typename TIter>
198class FieldReadNoStatusHelper
199{
200public:
201 FieldReadNoStatusHelper(TIter& iter)
202 : m_iter(iter)
203 {
204 }
205
206 template <typename TField>
207 void operator()(TField& field)
208 {
209 field.readNoStatus(m_iter);
210 }
211
212private:
213 TIter& m_iter;
214};
215
216template <typename TIter>
217class FieldWriteHelper
218{
219public:
220 FieldWriteHelper(ErrorStatus& es, TIter& iter, std::size_t len)
221 : m_es(es),
222 m_iter(iter),
223 m_len(len)
224 {
225 }
226
227 template <typename TField>
228 void operator()(const TField& field)
229 {
230 if (m_es != comms::ErrorStatus::Success) {
231 return;
232 }
233
234 m_es = field.write(m_iter, m_len);
235 if (m_es == comms::ErrorStatus::Success) {
236 m_len -= field.length();
237 }
238 }
239
240private:
241 ErrorStatus& m_es;
242 TIter& m_iter;
243 std::size_t m_len;
244};
245
246template <typename TIter>
247class FieldWriteNoStatusHelper
248{
249public:
250 FieldWriteNoStatusHelper(TIter& iter)
251 : m_iter(iter)
252 {
253 }
254
255 template <typename TField>
256 void operator()(const TField& field)
257 {
258 field.writeNoStatus(m_iter);
259 }
260
261private:
262 TIter& m_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) : m_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>(m_version)) || updated;
317 }
318
319private:
320 const TVersionType m_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