COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
IntValue.h
Go to the documentation of this file.
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
12
13#pragma once
14
16#include "comms/ErrorStatus.h"
17#include "comms/details/tag.h"
18#include "comms/field/basic/IntValue.h"
19#include "comms/field/details/AdaptBasicField.h"
20#include "comms/options.h"
22
23#include <cstddef>
24#include <limits>
25#include <ratio>
26#include <type_traits>
27#include <utility>
28
29COMMS_MSVC_WARNING_PUSH
30COMMS_MSVC_WARNING_DISABLE(4127) // Disable warning about constant conditional expressions
31
32namespace comms
33{
34
35namespace field
36{
37
77template <typename TFieldBase, typename T, typename... TOptions>
78class IntValue : public details::AdaptBasicFieldT<basic::IntValue<TFieldBase, T>, TOptions...>
79{
80 using BaseImpl = details::AdaptBasicFieldT<basic::IntValue<TFieldBase, T>, TOptions...>;
81public:
82
84 using FieldBase = TFieldBase;
85
87 using Endian = typename BaseImpl::Endian;
88
90 using VersionType = typename BaseImpl::VersionType;
91
93 using ParsedOptions = details::OptionsParser<TOptions...>;
94
96 using CommsTag = typename BaseImpl::CommsTag;
97
100 using ValueType = typename BaseImpl::ValueType;
101
104 using UnitsType = typename ParsedOptions::UnitsType;
105
108 using ScalingRatio = typename ParsedOptions::ScalingRatio;
109
112 using UnitsRatio = typename ParsedOptions::UnitsRatio;
113
117 using FieldType = typename ParsedOptions::FieldType;
118
121 IntValue() = default;
122
124 explicit IntValue(const ValueType& val)
125 : BaseImpl(val)
126 {
127 }
128
130 IntValue(const IntValue&) = default;
131
133 ~IntValue() noexcept = default;
134
136 IntValue& operator=(const IntValue&) = default;
137
140 static constexpr bool hasFailOnInvalid()
141 {
142 return ParsedOptions::HasFailOnInvalid;
143 }
144
147 static constexpr bool hasIgnoreInvalid()
148 {
149 return ParsedOptions::HasIgnoreInvalid;
150 }
151
154 static constexpr bool hasEmptySerialization()
155 {
156 return ParsedOptions::HasEmptySerialization;
157 }
158
161 static constexpr bool hasUnits()
162 {
163 return ParsedOptions::HasUnits;
164 }
165
168 static constexpr bool hasScaling()
169 {
170 return ParsedOptions::HasScalingRatio && !std::is_same<ScalingRatio, std::ratio<1, 1> >::value;
171 }
172
175 static constexpr bool hasFieldType()
176 {
177 return ParsedOptions::HasFieldType;
178 }
179
182 static constexpr bool hasVarLength()
183 {
184 return ParsedOptions::HasVarLengthLimits;
185 }
186
189 static constexpr bool hasFixedValue()
190 {
191 return ParsedOptions::HasFixedValue;
192 }
193
196 static constexpr bool hasDisplayOffset()
197 {
198 return ParsedOptions::HasDisplayOffset;
199 }
200
203 static constexpr bool hasName()
204 {
205 return ParsedOptions::HasName;
206 }
207
215 template <typename TRet>
216 constexpr TRet getScaled() const
217 {
218 using TagTmp =
219 typename comms::util::LazyShallowConditional<
220 ParsedOptions::HasScalingRatio
221 >::template Type<
222 HasScalingRatioTag,
223 NoScalingRatioTag
224 >;
225
226 return scaleAsInternal<TRet>(TagTmp());
227 }
228
230 template <typename TRet>
231 constexpr TRet scaleAs() const
232 {
233 return getScaled<TRet>();
234 }
235
240 template <typename TScaled>
241 void setScaled(TScaled val)
242 {
243 using TagTmp =
244 typename comms::util::LazyShallowConditional<
245 ParsedOptions::HasScalingRatio
246 >::template Type<
247 HasScalingRatioTag,
248 NoScalingRatioTag
249 >;
250
251 return setScaledInternal(val, TagTmp());
252 }
253
255 const ValueType& value() const
256 {
257 return BaseImpl::value();
258 }
259
262 {
263 return BaseImpl::value();
264 }
265
268 const ValueType& getValue() const
269 {
270 return BaseImpl::getValue();
271 }
272
275 template <typename U>
276 void setValue(U&& val)
277 {
278 BaseImpl::setValue(std::forward<U>(val));
279 }
280
285 {
286 return static_cast<ValueType>(getValue() + BaseImpl::displayOffset());
287 }
288
292 template <typename U>
293 void setDisplayValue(U&& val)
294 {
295 setValue(val - BaseImpl::displayOffset());
296 }
297
299 static constexpr ValueType maxValue()
300 {
301 return std::numeric_limits<ValueType>::max();
302 }
303
305 static constexpr ValueType minValue()
306 {
307 return std::numeric_limits<ValueType>::min();
308 }
309
312 constexpr std::size_t length() const
313 {
314 return BaseImpl::length();
315 }
316
319 static constexpr std::size_t minLength()
320 {
321 return BaseImpl::minLength();
322 }
323
326 static constexpr std::size_t maxLength()
327 {
328 return BaseImpl::maxLength();
329 }
330
332 bool valid() const
333 {
334 return BaseImpl::valid();
335 }
336
339 bool refresh()
340 {
341 return BaseImpl::refresh();
342 }
343
349 template <typename TIter>
350 ErrorStatus read(TIter& iter, std::size_t size)
351 {
352 return BaseImpl::read(iter, size);
353 }
354
357 static constexpr bool hasReadNoStatus()
358 {
359 return BaseImpl::hasReadNoStatus();
360 }
361
367 template <typename TIter>
368 void readNoStatus(TIter& iter)
369 {
370 BaseImpl::readNoStatus(iter);
371 }
372
374 bool canWrite() const
375 {
376 return BaseImpl::canWrite();
377 }
378
384 template <typename TIter>
385 ErrorStatus write(TIter& iter, std::size_t size) const
386 {
387 return BaseImpl::write(iter, size);
388 }
389
392 static constexpr bool hasWriteNoStatus()
393 {
394 return BaseImpl::hasWriteNoStatus();
395 }
396
402 template <typename TIter>
403 void writeNoStatus(TIter& iter) const
404 {
405 BaseImpl::writeNoStatus(iter);
406 }
407
409 static constexpr bool isVersionDependent()
410 {
411 return ParsedOptions::HasCustomVersionUpdate || BaseImpl::isVersionDependent();
412 }
413
415 static constexpr bool hasNonDefaultRefresh()
416 {
417 return BaseImpl::hasNonDefaultRefresh();
418 }
419
423 {
424 return BaseImpl::getVersion();
425 }
426
430 {
431 return BaseImpl::setVersion(version);
432 }
433
441 void setForcedLength(int len)
442 {
443 BaseImpl::setForcedLength(len);
444 }
445
448 int getForcedLength() const
449 {
450 return BaseImpl::getForcedLength();
451 }
452
453protected:
454 using BaseImpl::readData;
455 using BaseImpl::writeData;
456
457private:
458 template <typename... TParams>
459 using HasScalingRatioTag = comms::details::tag::Tag1<>;
460
461 template <typename... TParams>
462 using NoScalingRatioTag = comms::details::tag::Tag2<>;
463
464 template <typename... TParams>
465 using ScaleAsFpTag = comms::details::tag::Tag3<>;
466
467 template <typename... TParams>
468 using ScaleAsIntTag = comms::details::tag::Tag4<>;
469
470 template <typename TRet, typename... TParams>
471 TRet scaleAsInternal(HasScalingRatioTag<TParams...>) const
472 {
473 using TagTmp =
474 typename comms::util::LazyShallowConditional<
475 std::is_floating_point<TRet>::value
476 >::template Type<
477 ScaleAsFpTag,
478 ScaleAsIntTag
479 >;
480
481 return scaleAsInternal<TRet>(TagTmp());
482 }
483
484 template <typename TRet, typename... TParams>
485 TRet scaleAsInternal(ScaleAsFpTag<TParams...>) const
486 {
487 static_assert(std::is_floating_point<TRet>::value,
488 "TRet is expected to be floating point type");
489 return static_cast<TRet>(BaseImpl::value()) * (static_cast<TRet>(ParsedOptions::ScalingRatio::num) / static_cast<TRet>(ParsedOptions::ScalingRatio::den));
490 }
491
492 template <typename TRet, typename... TParams>
493 TRet scaleAsInternal(ScaleAsIntTag<TParams...>) const
494 {
495 static_assert(std::is_integral<TRet>::value,
496 "TRet is expected to be integral type");
497
498 using CastType =
500 std::is_signed<TRet>::value
501 >::template Type<
502 std::intmax_t,
503 std::uintmax_t
504 >;
505
506 return
507 static_cast<TRet>(
508 (static_cast<CastType>(BaseImpl::value()) * ParsedOptions::ScalingRatio::num) / ParsedOptions::ScalingRatio::den);
509 }
510
511 template <typename TRet, typename... TParams>
512 TRet scaleAsInternal(NoScalingRatioTag<TParams...>) const
513 {
514 return static_cast<TRet>(BaseImpl::value());
515 }
516
517 template <typename TScaled, typename... TParams>
518 void setScaledInternal(TScaled val, HasScalingRatioTag<TParams...>)
519 {
520 using TagTmp =
521 typename comms::util::LazyShallowConditional<
522 std::is_floating_point<typename std::decay<decltype(val)>::type>::value
523 >::template Type<
524 ScaleAsFpTag,
525 ScaleAsIntTag
526 >;
527
528 setScaledInternal(val, TagTmp());
529 }
530
531 template <typename TScaled, typename... TParams>
532 void setScaledInternal(TScaled val, ScaleAsFpTag<TParams...>)
533 {
534 using DecayedType = typename std::decay<decltype(val)>::type;
535 auto epsilon = DecayedType(0);
536 if (ParsedOptions::ScalingRatio::num < ParsedOptions::ScalingRatio::den) {
537 epsilon = static_cast<DecayedType>(ParsedOptions::ScalingRatio::num) / static_cast<DecayedType>(ParsedOptions::ScalingRatio::den + 1);
538 }
539
540 if (epsilon < DecayedType(0)) {
541 epsilon = -epsilon;
542 }
543
544 if (val < DecayedType(0)) {
545 epsilon = -epsilon;
546 }
547
548 BaseImpl::value() =
549 static_cast<ValueType>(
550 ((val + epsilon) * static_cast<DecayedType>(ParsedOptions::ScalingRatio::den)) / static_cast<DecayedType>(ParsedOptions::ScalingRatio::num));
551 }
552
553 template <typename TScaled, typename... TParams>
554 void setScaledInternal(TScaled val, ScaleAsIntTag<TParams...>)
555 {
556 using CastType =
558 std::is_signed<typename std::decay<decltype(val)>::type>::value
559 >::template Type<
560 std::intmax_t,
561 std::uintmax_t
562 >;
563
564 BaseImpl::value() =
565 static_cast<ValueType>(
566 (static_cast<CastType>(val) * ParsedOptions::ScalingRatio::den) / static_cast<CastType>(ParsedOptions::ScalingRatio::num));
567 }
568
569 template <typename TScaled, typename... TParams>
570 void setScaledInternal(TScaled val, NoScalingRatioTag<TParams...>)
571 {
572 BaseImpl::value() = static_cast<ValueType>(val);
573 }
574
575 static_assert(!ParsedOptions::HasSequenceElemLengthForcing,
576 "comms::option::def::SequenceElemLengthForcingEnabled option is not applicable to IntValue field");
577 static_assert(!ParsedOptions::HasSequenceSizeForcing,
578 "comms::option::def::SequenceSizeForcingEnabled option is not applicable to IntValue field");
579 static_assert(!ParsedOptions::HasSequenceLengthForcing,
580 "comms::option::def::SequenceLengthForcingEnabled option is not applicable to IntValue field");
581 static_assert(!ParsedOptions::HasSequenceFixedSize,
582 "comms::option::def::SequenceFixedSize option is not applicable to IntValue field");
583 static_assert(!ParsedOptions::HasSequenceFixedSizeUseFixedSizeStorage,
584 "comms::option::app::SequenceFixedSizeUseFixedSizeStorage option is not applicable to IntValue field");
585 static_assert(!ParsedOptions::HasSequenceSizeFieldPrefix,
586 "comms::option::def::SequenceSizeFieldPrefix option is not applicable to IntValue field");
587 static_assert(!ParsedOptions::HasSequenceSerLengthFieldPrefix,
588 "comms::option::def::SequenceSerLengthFieldPrefix option is not applicable to IntValue field");
589 static_assert(!ParsedOptions::HasSequenceElemSerLengthFieldPrefix,
590 "comms::option::def::SequenceElemSerLengthFieldPrefix option is not applicable to IntValue field");
591 static_assert(!ParsedOptions::HasSequenceElemFixedSerLengthFieldPrefix,
592 "comms::option::def::SequenceElemSerLengthFixedFieldPrefix option is not applicable to IntValue field");
593 static_assert(!ParsedOptions::HasSequenceTrailingFieldSuffix,
594 "comms::option::def::SequenceTrailingFieldSuffix option is not applicable to IntValue field");
595 static_assert(!ParsedOptions::HasSequenceTerminationFieldSuffix,
596 "comms::option::def::SequenceTerminationFieldSuffix option is not applicable to IntValue field");
597 static_assert(!ParsedOptions::HasFixedSizeStorage,
598 "comms::option::app::FixedSizeStorage option is not applicable to IntValue field");
599 static_assert(!ParsedOptions::HasCustomStorageType,
600 "comms::option::app::CustomStorageType option is not applicable to IntValue field");
601 static_assert(!ParsedOptions::HasOrigDataView,
602 "comms::option::app::OrigDataView option is not applicable to IntValue field");
603 static_assert(!ParsedOptions::HasVersionsRange,
604 "comms::option::def::ExistsBetweenVersions (or similar) option is not applicable to IntValue field");
605 static_assert(!ParsedOptions::HasMissingOnReadFail,
606 "comms::option::def::MissingOnReadFail option is not applicable to IntValue field");
607 static_assert(!ParsedOptions::HasMissingOnInvalid,
608 "comms::option::def::MissingOnInvalid option is not applicable to IntValue field");
609};
610
616template <typename TFieldBase, typename T, typename... TOptions>
619 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
620{
621 return field1.value() == field2.value();
622}
623
629template <typename TFieldBase, typename T, typename... TOptions>
632 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
633{
634 return field1.value() != field2.value();
635}
636
642template <typename TFieldBase, typename T, typename... TOptions>
645 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
646{
647 return field1.value() < field2.value();
648}
649
655template <typename T>
656constexpr bool isIntValue()
657{
658 return std::is_same<typename T::CommsTag, tag::Int>::value;
659}
660
664template <typename TFieldBase, typename T, typename... TOptions>
665inline
666IntValue<TFieldBase, T, TOptions...>&
668{
669 return field;
670}
671
675template <typename TFieldBase, typename T, typename... TOptions>
676inline
677const IntValue<TFieldBase, T, TOptions...>&
679{
680 return field;
681}
682
683} // namespace field
684
685} // namespace comms
686
687COMMS_MSVC_WARNING_POP
688
Contains various compiler related definitions.
This file contain definition of error statuses used by comms module.
Field that represent integral value.
Definition IntValue.h:79
static constexpr ValueType minValue()
Get minimal numeric value the field can hold.
Definition IntValue.h:305
typename BaseImpl::ValueType ValueType
Type of underlying integral value.
Definition IntValue.h:100
IntValue()=default
Default constructor.
static constexpr bool hasFieldType()
Compile time inquiry of whether comms::option::def::FieldType option has been used.
Definition IntValue.h:175
details::OptionsParser< TOptions... > ParsedOptions
All the options provided to this class bundled into struct.
Definition IntValue.h:93
void setScaled(TScaled val)
Opposite operation to getScaled().
Definition IntValue.h:241
IntValue< TFieldBase, T, TOptions... > & toFieldBase(IntValue< TFieldBase, T, TOptions... > &field)
Upcast type of the field definition to its parent comms::field::IntValue type in order to have access...
Definition IntValue.h:667
ValueType getDisplayValue() const
Get display value.
Definition IntValue.h:284
typename BaseImpl::CommsTag CommsTag
Tag indicating type of the field.
Definition IntValue.h:96
~IntValue() noexcept=default
Destructor.
typename BaseImpl::VersionType VersionType
Version type.
Definition IntValue.h:90
bool setVersion(VersionType version)
Default implementation of version update.
Definition IntValue.h:429
typename ParsedOptions::FieldType FieldType
Type of actual extending field specified via comms::option::def::FieldType.
Definition IntValue.h:117
IntValue(const IntValue &)=default
Copy constructor.
bool valid() const
Check validity of the field value.
Definition IntValue.h:332
static constexpr bool hasScaling()
Compile time inquiry of whether scaling ratio has been provided via comms::option::def::ScalingRatio ...
Definition IntValue.h:168
typename ParsedOptions::UnitsType UnitsType
Units type defined by any of the comms::option::def::Units* option.
Definition IntValue.h:104
void setDisplayValue(U &&val)
Set display value.
Definition IntValue.h:293
static constexpr bool hasWriteNoStatus()
Compile time check of whether the field has proper writeNoStatus() member function.
Definition IntValue.h:392
int getForcedLength() const
Get forced serialization length.
Definition IntValue.h:448
static constexpr bool hasIgnoreInvalid()
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used.
Definition IntValue.h:147
static constexpr bool hasDisplayOffset()
Compile time inquiry of whether comms::option::def::DisplayOffset option has been used.
Definition IntValue.h:196
const IntValue< TFieldBase, T, TOptions... > & toFieldBase(const IntValue< TFieldBase, T, TOptions... > &field)
Upcast type of the field definition to its parent comms::field::IntValue type in order to have access...
Definition IntValue.h:678
bool operator==(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Equality comparison operator.
Definition IntValue.h:617
typename ParsedOptions::ScalingRatio ScalingRatio
Scaling ratio defined by the comms::option::def::ScalingRatio option.
Definition IntValue.h:108
typename ParsedOptions::UnitsRatio UnitsRatio
Scaling ratio determined by the forced units via the comms::option::def::Units* option.
Definition IntValue.h:112
VersionType getVersion() const
Get version of the field.
Definition IntValue.h:422
constexpr std::size_t length() const
Get length required to serialise the current field value.
Definition IntValue.h:312
static constexpr std::size_t maxLength()
Get maximal length that is required to serialise field of this type.
Definition IntValue.h:326
void readNoStatus(TIter &iter)
Read field value from input data sequence without error check and status report.
Definition IntValue.h:368
ValueType & value()
Get access to integral value storage.
Definition IntValue.h:261
static constexpr bool hasFixedValue()
Compile time inquiry of whether comms::option::def::FixedValue option has been used.
Definition IntValue.h:189
static constexpr bool hasEmptySerialization()
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used.
Definition IntValue.h:154
static constexpr std::size_t minLength()
Get minimal length that is required to serialise field of this type.
Definition IntValue.h:319
bool operator<(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition IntValue.h:643
static constexpr bool hasName()
Compile time inquiry of whether comms::option::def::HasName option has been used.
Definition IntValue.h:203
TFieldBase FieldBase
Base class provided in the first template parameter.
Definition IntValue.h:84
bool operator!=(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Non-equality comparison operator.
Definition IntValue.h:630
static constexpr ValueType maxValue()
Get maximal numeric value the field can hold.
Definition IntValue.h:299
static constexpr bool hasReadNoStatus()
Compile time check of whether the field has proper readNoStatus() member function.
Definition IntValue.h:357
constexpr TRet getScaled() const
Scales value according to ratio specified in provided comms::option::def::ScalingRatio option.
Definition IntValue.h:216
ErrorStatus read(TIter &iter, std::size_t size)
Read field value from input data sequence.
Definition IntValue.h:350
void setForcedLength(int len)
Force serialization length of the field.
Definition IntValue.h:441
void setValue(U &&val)
Set value.
Definition IntValue.h:276
constexpr TRet scaleAs() const
Same as getScaled()
Definition IntValue.h:231
ErrorStatus write(TIter &iter, std::size_t size) const
Write current field value to output data sequence.
Definition IntValue.h:385
static constexpr bool hasNonDefaultRefresh()
Compile time check if this class has non-default refresh functionality.
Definition IntValue.h:415
static constexpr bool hasUnits()
Compile time inquiry of whether units have been set via any of the comms::option::def::Units* options...
Definition IntValue.h:161
const ValueType & value() const
Get access to integral value storage.
Definition IntValue.h:255
typename BaseImpl::Endian Endian
Endian used for serialisation.
Definition IntValue.h:87
void writeNoStatus(TIter &iter) const
Write current field value to output data sequence without error check and status report.
Definition IntValue.h:403
static constexpr bool isVersionDependent()
Compile time check if this class is version dependent.
Definition IntValue.h:409
bool refresh()
Refresh the field's value.
Definition IntValue.h:339
IntValue(const ValueType &val)
Constructor.
Definition IntValue.h:124
bool canWrite() const
Check of whether the field has a consistent value for writing.
Definition IntValue.h:374
static constexpr bool hasVarLength()
Compile time inquiry of whether comms::option::def::VarLength option has been used.
Definition IntValue.h:182
constexpr bool isIntValue()
Compile time check function of whether a provided type is any variant of comms::field::IntValue.
Definition IntValue.h:656
const ValueType & getValue() const
Get value.
Definition IntValue.h:268
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:19
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:66
Contains definition of all the options used by the COMMS library.
Replacement to std::conditional.
Definition type_traits.h:32
Replacement to some types from standard type_traits.