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 - 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
10
11#pragma once
12
13#include <ratio>
14#include <limits>
15#include <type_traits>
16
18#include "comms/ErrorStatus.h"
19#include "comms/options.h"
21#include "basic/IntValue.h"
22#include "details/AdaptBasicField.h"
23#include "comms/details/tag.h"
24
25COMMS_MSVC_WARNING_PUSH
26COMMS_MSVC_WARNING_DISABLE(4127) // Disable warning about constant conditional expressions
27
28namespace comms
29{
30
31namespace field
32{
33
73template <typename TFieldBase, typename T, typename... TOptions>
74class IntValue : public details::AdaptBasicFieldT<basic::IntValue<TFieldBase, T>, TOptions...>
75{
76 using BaseImpl = details::AdaptBasicFieldT<basic::IntValue<TFieldBase, T>, TOptions...>;
77public:
78
80 using FieldBase = TFieldBase;
81
83 using Endian = typename BaseImpl::Endian;
84
86 using VersionType = typename BaseImpl::VersionType;
87
89 using ParsedOptions = details::OptionsParser<TOptions...>;
90
92 using CommsTag = typename BaseImpl::CommsTag;
93
96 using ValueType = typename BaseImpl::ValueType;
97
100 using UnitsType = typename ParsedOptions::UnitsType;
101
104 using ScalingRatio = typename ParsedOptions::ScalingRatio;
105
108 using UnitsRatio = typename ParsedOptions::UnitsRatio;
109
113 using FieldType = typename ParsedOptions::FieldType;
114
117 IntValue() = default;
118
120 explicit IntValue(const ValueType& val)
121 : BaseImpl(val)
122 {
123 }
124
126 IntValue(const IntValue&) = default;
127
129 ~IntValue() noexcept = default;
130
132 IntValue& operator=(const IntValue&) = default;
133
136 static constexpr bool hasFailOnInvalid()
137 {
138 return ParsedOptions::HasFailOnInvalid;
139 }
140
143 static constexpr bool hasIgnoreInvalid()
144 {
145 return ParsedOptions::HasIgnoreInvalid;
146 }
147
150 static constexpr bool hasEmptySerialization()
151 {
152 return ParsedOptions::HasEmptySerialization;
153 }
154
157 static constexpr bool hasUnits()
158 {
159 return ParsedOptions::HasUnits;
160 }
161
164 static constexpr bool hasScaling()
165 {
166 return ParsedOptions::HasScalingRatio && !std::is_same<ScalingRatio, std::ratio<1, 1> >::value;
167 }
168
171 static constexpr bool hasFieldType()
172 {
173 return ParsedOptions::HasFieldType;
174 }
175
178 static constexpr bool hasVarLength()
179 {
180 return ParsedOptions::HasVarLengthLimits;
181 }
182
185 static constexpr bool hasFixedValue()
186 {
187 return ParsedOptions::HasFixedValue;
188 }
189
192 static constexpr bool hasDisplayOffset()
193 {
194 return ParsedOptions::HasDisplayOffset;
195 }
196
199 static constexpr bool hasName()
200 {
201 return ParsedOptions::HasName;
202 }
203
211 template <typename TRet>
212 constexpr TRet getScaled() const
213 {
214 using TagTmp =
215 typename comms::util::LazyShallowConditional<
216 ParsedOptions::HasScalingRatio
217 >::template Type<
218 HasScalingRatioTag,
219 NoScalingRatioTag
220 >;
221
222 return scaleAsInternal<TRet>(TagTmp());
223 }
224
226 template <typename TRet>
227 constexpr TRet scaleAs() const
228 {
229 return getScaled<TRet>();
230 }
231
236 template <typename TScaled>
237 void setScaled(TScaled val)
238 {
239 using TagTmp =
240 typename comms::util::LazyShallowConditional<
241 ParsedOptions::HasScalingRatio
242 >::template Type<
243 HasScalingRatioTag,
244 NoScalingRatioTag
245 >;
246
247 return setScaledInternal(val, TagTmp());
248 }
249
251 const ValueType& value() const
252 {
253 return BaseImpl::value();
254 }
255
258 {
259 return BaseImpl::value();
260 }
261
264 const ValueType& getValue() const
265 {
266 return BaseImpl::getValue();
267 }
268
271 template <typename U>
272 void setValue(U&& val)
273 {
274 BaseImpl::setValue(std::forward<U>(val));
275 }
276
281 {
282 return static_cast<ValueType>(getValue() + BaseImpl::displayOffset());
283 }
284
288 template <typename U>
289 void setDisplayValue(U&& val)
290 {
291 setValue(val - BaseImpl::displayOffset());
292 }
293
295 static constexpr ValueType maxValue()
296 {
297 return std::numeric_limits<ValueType>::max();
298 }
299
301 static constexpr ValueType minValue()
302 {
303 return std::numeric_limits<ValueType>::min();
304 }
305
308 constexpr std::size_t length() const
309 {
310 return BaseImpl::length();
311 }
312
315 static constexpr std::size_t minLength()
316 {
317 return BaseImpl::minLength();
318 }
319
322 static constexpr std::size_t maxLength()
323 {
324 return BaseImpl::maxLength();
325 }
326
328 bool valid() const
329 {
330 return BaseImpl::valid();
331 }
332
335 bool refresh()
336 {
337 return BaseImpl::refresh();
338 }
339
345 template <typename TIter>
346 ErrorStatus read(TIter& iter, std::size_t size)
347 {
348 return BaseImpl::read(iter, size);
349 }
350
353 static constexpr bool hasReadNoStatus()
354 {
355 return BaseImpl::hasReadNoStatus();
356 }
357
363 template <typename TIter>
364 void readNoStatus(TIter& iter)
365 {
366 BaseImpl::readNoStatus(iter);
367 }
368
370 bool canWrite() const
371 {
372 return BaseImpl::canWrite();
373 }
374
380 template <typename TIter>
381 ErrorStatus write(TIter& iter, std::size_t size) const
382 {
383 return BaseImpl::write(iter, size);
384 }
385
388 static constexpr bool hasWriteNoStatus()
389 {
390 return BaseImpl::hasWriteNoStatus();
391 }
392
398 template <typename TIter>
399 void writeNoStatus(TIter& iter) const
400 {
401 BaseImpl::writeNoStatus(iter);
402 }
403
405 static constexpr bool isVersionDependent()
406 {
407 return ParsedOptions::HasCustomVersionUpdate || BaseImpl::isVersionDependent();
408 }
409
411 static constexpr bool hasNonDefaultRefresh()
412 {
413 return BaseImpl::hasNonDefaultRefresh();
414 }
415
419 {
420 return BaseImpl::getVersion();
421 }
422
426 {
427 return BaseImpl::setVersion(version);
428 }
429
437 void setForcedLength(int len)
438 {
439 BaseImpl::setForcedLength(len);
440 }
441
444 int getForcedLength() const
445 {
446 return BaseImpl::getForcedLength();
447 }
448
449protected:
450 using BaseImpl::readData;
451 using BaseImpl::writeData;
452
453private:
454 template <typename... TParams>
455 using HasScalingRatioTag = comms::details::tag::Tag1<>;
456
457 template <typename... TParams>
458 using NoScalingRatioTag = comms::details::tag::Tag2<>;
459
460 template <typename... TParams>
461 using ScaleAsFpTag = comms::details::tag::Tag3<>;
462
463 template <typename... TParams>
464 using ScaleAsIntTag = comms::details::tag::Tag4<>;
465
466 template <typename TRet, typename... TParams>
467 TRet scaleAsInternal(HasScalingRatioTag<TParams...>) const
468 {
469 using TagTmp =
470 typename comms::util::LazyShallowConditional<
471 std::is_floating_point<TRet>::value
472 >::template Type<
473 ScaleAsFpTag,
474 ScaleAsIntTag
475 >;
476
477 return scaleAsInternal<TRet>(TagTmp());
478 }
479
480 template <typename TRet, typename... TParams>
481 TRet scaleAsInternal(ScaleAsFpTag<TParams...>) const
482 {
483 static_assert(std::is_floating_point<TRet>::value,
484 "TRet is expected to be floating point type");
485 return static_cast<TRet>(BaseImpl::value()) * (static_cast<TRet>(ParsedOptions::ScalingRatio::num) / static_cast<TRet>(ParsedOptions::ScalingRatio::den));
486 }
487
488 template <typename TRet, typename... TParams>
489 TRet scaleAsInternal(ScaleAsIntTag<TParams...>) const
490 {
491 static_assert(std::is_integral<TRet>::value,
492 "TRet is expected to be integral type");
493
494 using CastType =
496 std::is_signed<TRet>::value
497 >::template Type<
498 std::intmax_t,
499 std::uintmax_t
500 >;
501
502 return
503 static_cast<TRet>(
504 (static_cast<CastType>(BaseImpl::value()) * ParsedOptions::ScalingRatio::num) / ParsedOptions::ScalingRatio::den);
505 }
506
507 template <typename TRet, typename... TParams>
508 TRet scaleAsInternal(NoScalingRatioTag<TParams...>) const
509 {
510 return static_cast<TRet>(BaseImpl::value());
511 }
512
513 template <typename TScaled, typename... TParams>
514 void setScaledInternal(TScaled val, HasScalingRatioTag<TParams...>)
515 {
516 using TagTmp =
517 typename comms::util::LazyShallowConditional<
518 std::is_floating_point<typename std::decay<decltype(val)>::type>::value
519 >::template Type<
520 ScaleAsFpTag,
521 ScaleAsIntTag
522 >;
523
524 setScaledInternal(val, TagTmp());
525 }
526
527 template <typename TScaled, typename... TParams>
528 void setScaledInternal(TScaled val, ScaleAsFpTag<TParams...>)
529 {
530 using DecayedType = typename std::decay<decltype(val)>::type;
531 auto epsilon = DecayedType(0);
532 if (ParsedOptions::ScalingRatio::num < ParsedOptions::ScalingRatio::den) {
533 epsilon = static_cast<DecayedType>(ParsedOptions::ScalingRatio::num) / static_cast<DecayedType>(ParsedOptions::ScalingRatio::den + 1);
534 }
535
536 if (epsilon < DecayedType(0)) {
537 epsilon = -epsilon;
538 }
539
540 if (val < DecayedType(0)) {
541 epsilon = -epsilon;
542 }
543
544 BaseImpl::value() =
545 static_cast<ValueType>(
546 ((val + epsilon) * static_cast<DecayedType>(ParsedOptions::ScalingRatio::den)) / static_cast<DecayedType>(ParsedOptions::ScalingRatio::num));
547 }
548
549 template <typename TScaled, typename... TParams>
550 void setScaledInternal(TScaled val, ScaleAsIntTag<TParams...>)
551 {
552 using CastType =
554 std::is_signed<typename std::decay<decltype(val)>::type>::value
555 >::template Type<
556 std::intmax_t,
557 std::uintmax_t
558 >;
559
560 BaseImpl::value() =
561 static_cast<ValueType>(
562 (static_cast<CastType>(val) * ParsedOptions::ScalingRatio::den) / static_cast<CastType>(ParsedOptions::ScalingRatio::num));
563 }
564
565 template <typename TScaled, typename... TParams>
566 void setScaledInternal(TScaled val, NoScalingRatioTag<TParams...>)
567 {
568 BaseImpl::value() = static_cast<ValueType>(val);
569 }
570
571 static_assert(!ParsedOptions::HasSequenceElemLengthForcing,
572 "comms::option::def::SequenceElemLengthForcingEnabled option is not applicable to IntValue field");
573 static_assert(!ParsedOptions::HasSequenceSizeForcing,
574 "comms::option::def::SequenceSizeForcingEnabled option is not applicable to IntValue field");
575 static_assert(!ParsedOptions::HasSequenceLengthForcing,
576 "comms::option::def::SequenceLengthForcingEnabled option is not applicable to IntValue field");
577 static_assert(!ParsedOptions::HasSequenceFixedSize,
578 "comms::option::def::SequenceFixedSize option is not applicable to IntValue field");
579 static_assert(!ParsedOptions::HasSequenceFixedSizeUseFixedSizeStorage,
580 "comms::option::app::SequenceFixedSizeUseFixedSizeStorage option is not applicable to IntValue field");
581 static_assert(!ParsedOptions::HasSequenceSizeFieldPrefix,
582 "comms::option::def::SequenceSizeFieldPrefix option is not applicable to IntValue field");
583 static_assert(!ParsedOptions::HasSequenceSerLengthFieldPrefix,
584 "comms::option::def::SequenceSerLengthFieldPrefix option is not applicable to IntValue field");
585 static_assert(!ParsedOptions::HasSequenceElemSerLengthFieldPrefix,
586 "comms::option::def::SequenceElemSerLengthFieldPrefix option is not applicable to IntValue field");
587 static_assert(!ParsedOptions::HasSequenceElemFixedSerLengthFieldPrefix,
588 "comms::option::def::SequenceElemSerLengthFixedFieldPrefix option is not applicable to IntValue field");
589 static_assert(!ParsedOptions::HasSequenceTrailingFieldSuffix,
590 "comms::option::def::SequenceTrailingFieldSuffix option is not applicable to IntValue field");
591 static_assert(!ParsedOptions::HasSequenceTerminationFieldSuffix,
592 "comms::option::def::SequenceTerminationFieldSuffix option is not applicable to IntValue field");
593 static_assert(!ParsedOptions::HasFixedSizeStorage,
594 "comms::option::app::FixedSizeStorage option is not applicable to IntValue field");
595 static_assert(!ParsedOptions::HasCustomStorageType,
596 "comms::option::app::CustomStorageType option is not applicable to IntValue field");
597 static_assert(!ParsedOptions::HasOrigDataView,
598 "comms::option::app::OrigDataView option is not applicable to IntValue field");
599 static_assert(!ParsedOptions::HasVersionsRange,
600 "comms::option::def::ExistsBetweenVersions (or similar) option is not applicable to IntValue field");
601 static_assert(!ParsedOptions::HasMissingOnReadFail,
602 "comms::option::def::MissingOnReadFail option is not applicable to IntValue field");
603 static_assert(!ParsedOptions::HasMissingOnInvalid,
604 "comms::option::def::MissingOnInvalid option is not applicable to IntValue field");
605};
606
607
613template <typename TFieldBase, typename T, typename... TOptions>
616 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
617{
618 return field1.value() == field2.value();
619}
620
626template <typename TFieldBase, typename T, typename... TOptions>
629 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
630{
631 return field1.value() != field2.value();
632}
633
639template <typename TFieldBase, typename T, typename... TOptions>
642 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
643{
644 return field1.value() < field2.value();
645}
646
652template <typename T>
653constexpr bool isIntValue()
654{
655 return std::is_same<typename T::CommsTag, tag::Int>::value;
656}
657
661template <typename TFieldBase, typename T, typename... TOptions>
662inline
663IntValue<TFieldBase, T, TOptions...>&
665{
666 return field;
667}
668
672template <typename TFieldBase, typename T, typename... TOptions>
673inline
674const IntValue<TFieldBase, T, TOptions...>&
676{
677 return field;
678}
679
680} // namespace field
681
682} // namespace comms
683
684COMMS_MSVC_WARNING_POP
685
Contains various compiler related definitions.
This file contain definition of error statuses used by comms module.
Field that represent integral value.
Definition IntValue.h:75
static constexpr ValueType minValue()
Get minimal numeric value the field can hold.
Definition IntValue.h:301
typename BaseImpl::ValueType ValueType
Type of underlying integral value.
Definition IntValue.h:96
IntValue()=default
Default constructor.
static constexpr bool hasFieldType()
Compile time inquiry of whether comms::option::def::FieldType option has been used.
Definition IntValue.h:171
details::OptionsParser< TOptions... > ParsedOptions
All the options provided to this class bundled into struct.
Definition IntValue.h:89
void setScaled(TScaled val)
Opposite operation to getScaled().
Definition IntValue.h:237
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:664
ValueType getDisplayValue() const
Get display value.
Definition IntValue.h:280
typename BaseImpl::CommsTag CommsTag
Tag indicating type of the field.
Definition IntValue.h:92
~IntValue() noexcept=default
Destructor.
typename BaseImpl::VersionType VersionType
Version type.
Definition IntValue.h:86
bool setVersion(VersionType version)
Default implementation of version update.
Definition IntValue.h:425
typename ParsedOptions::FieldType FieldType
Type of actual extending field specified via comms::option::def::FieldType.
Definition IntValue.h:113
IntValue(const IntValue &)=default
Copy constructor.
bool valid() const
Check validity of the field value.
Definition IntValue.h:328
static constexpr bool hasScaling()
Compile time inquiry of whether scaling ratio has been provided via comms::option::def::ScalingRatio ...
Definition IntValue.h:164
typename ParsedOptions::UnitsType UnitsType
Units type defined by any of the comms::option::def::Units* option.
Definition IntValue.h:100
void setDisplayValue(U &&val)
Set display value.
Definition IntValue.h:289
static constexpr bool hasWriteNoStatus()
Compile time check of whether the field has proper writeNoStatus() member function.
Definition IntValue.h:388
int getForcedLength() const
Get forced serialization length.
Definition IntValue.h:444
static constexpr bool hasIgnoreInvalid()
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used.
Definition IntValue.h:143
static constexpr bool hasDisplayOffset()
Compile time inquiry of whether comms::option::def::DisplayOffset option has been used.
Definition IntValue.h:192
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:675
bool operator==(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Equality comparison operator.
Definition IntValue.h:614
typename ParsedOptions::ScalingRatio ScalingRatio
Scaling ratio defined by the comms::option::def::ScalingRatio option.
Definition IntValue.h:104
typename ParsedOptions::UnitsRatio UnitsRatio
Scaling ratio determined by the forced units via the comms::option::def::Units* option.
Definition IntValue.h:108
VersionType getVersion() const
Get version of the field.
Definition IntValue.h:418
constexpr std::size_t length() const
Get length required to serialise the current field value.
Definition IntValue.h:308
static constexpr std::size_t maxLength()
Get maximal length that is required to serialise field of this type.
Definition IntValue.h:322
void readNoStatus(TIter &iter)
Read field value from input data sequence without error check and status report.
Definition IntValue.h:364
ValueType & value()
Get access to integral value storage.
Definition IntValue.h:257
static constexpr bool hasFixedValue()
Compile time inquiry of whether comms::option::def::FixedValue option has been used.
Definition IntValue.h:185
static constexpr bool hasEmptySerialization()
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used.
Definition IntValue.h:150
static constexpr std::size_t minLength()
Get minimal length that is required to serialise field of this type.
Definition IntValue.h:315
bool operator<(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition IntValue.h:640
static constexpr bool hasName()
Compile time inquiry of whether comms::option::def::HasName option has been used.
Definition IntValue.h:199
TFieldBase FieldBase
Base class provided in the first template parameter.
Definition IntValue.h:80
bool operator!=(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Non-equality comparison operator.
Definition IntValue.h:627
static constexpr ValueType maxValue()
Get maximal numeric value the field can hold.
Definition IntValue.h:295
static constexpr bool hasReadNoStatus()
Compile time check of whether the field has proper readNoStatus() member function.
Definition IntValue.h:353
constexpr TRet getScaled() const
Scales value according to ratio specified in provided comms::option::def::ScalingRatio option.
Definition IntValue.h:212
ErrorStatus read(TIter &iter, std::size_t size)
Read field value from input data sequence.
Definition IntValue.h:346
void setForcedLength(int len)
Force serialization length of the field.
Definition IntValue.h:437
void setValue(U &&val)
Set value.
Definition IntValue.h:272
constexpr TRet scaleAs() const
Same as getScaled()
Definition IntValue.h:227
ErrorStatus write(TIter &iter, std::size_t size) const
Write current field value to output data sequence.
Definition IntValue.h:381
static constexpr bool hasNonDefaultRefresh()
Compile time check if this class has non-default refresh functionality.
Definition IntValue.h:411
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:157
const ValueType & value() const
Get access to integral value storage.
Definition IntValue.h:251
typename BaseImpl::Endian Endian
Endian used for serialisation.
Definition IntValue.h:83
void writeNoStatus(TIter &iter) const
Write current field value to output data sequence without error check and status report.
Definition IntValue.h:399
static constexpr bool isVersionDependent()
Compile time check if this class is version dependent.
Definition IntValue.h:405
bool refresh()
Refresh the field's value.
Definition IntValue.h:335
IntValue(const ValueType &val)
Constructor.
Definition IntValue.h:120
bool canWrite() const
Check of whether the field has a consistent value for writing.
Definition IntValue.h:370
static constexpr bool hasVarLength()
Compile time inquiry of whether comms::option::def::VarLength option has been used.
Definition IntValue.h:178
constexpr bool isIntValue()
Compile time check function of whether a provided type is any variant of comms::field::IntValue.
Definition IntValue.h:653
const ValueType & getValue() const
Get value.
Definition IntValue.h:264
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:64
Contains definition of all the options used by the COMMS library.
Replacement to std::conditional.
Definition type_traits.h:28
Replacement to some types from standard type_traits.