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