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 - 2024 (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
70template <typename TFieldBase, typename T, typename... TOptions>
71class IntValue : public details::AdaptBasicFieldT<basic::IntValue<TFieldBase, T>, TOptions...>
72{
73 using BaseImpl = details::AdaptBasicFieldT<basic::IntValue<TFieldBase, T>, TOptions...>;
74public:
75
77 using FieldBase = TFieldBase;
78
80 using Endian = typename BaseImpl::Endian;
81
83 using VersionType = typename BaseImpl::VersionType;
84
86 using ParsedOptions = details::OptionsParser<TOptions...>;
87
89 using CommsTag = typename BaseImpl::CommsTag;
90
93 using ValueType = typename BaseImpl::ValueType;
94
97 using UnitsType = typename ParsedOptions::UnitsType;
98
101 using ScalingRatio = typename ParsedOptions::ScalingRatio;
102
105 using UnitsRatio = typename ParsedOptions::UnitsRatio;
106
110 using FieldType = typename ParsedOptions::FieldType;
111
114 IntValue() = default;
115
117 explicit IntValue(const ValueType& val)
118 : BaseImpl(val)
119 {
120 }
121
123 IntValue(const IntValue&) = default;
124
126 ~IntValue() noexcept = default;
127
129 IntValue& operator=(const IntValue&) = default;
130
133 static constexpr bool hasFailOnInvalid()
134 {
135 return ParsedOptions::HasFailOnInvalid;
136 }
137
140 static constexpr bool hasIgnoreInvalid()
141 {
142 return ParsedOptions::HasIgnoreInvalid;
143 }
144
147 static constexpr bool hasEmptySerialization()
148 {
149 return ParsedOptions::HasEmptySerialization;
150 }
151
154 static constexpr bool hasUnits()
155 {
156 return ParsedOptions::HasUnits;
157 }
158
161 static constexpr bool hasScaling()
162 {
163 return ParsedOptions::HasScalingRatio && !std::is_same<ScalingRatio, std::ratio<1, 1> >::value;
164 }
165
168 static constexpr bool hasFieldType()
169 {
170 return ParsedOptions::HasFieldType;
171 }
172
175 static constexpr bool hasVarLength()
176 {
177 return ParsedOptions::HasVarLengthLimits;
178 }
179
187 template <typename TRet>
188 constexpr TRet getScaled() const
189 {
190 using TagTmp =
191 typename comms::util::LazyShallowConditional<
192 ParsedOptions::HasScalingRatio
193 >::template Type<
194 HasScalingRatioTag,
195 NoScalingRatioTag
196 >;
197
198 return scaleAsInternal<TRet>(TagTmp());
199 }
200
202 template <typename TRet>
203 constexpr TRet scaleAs() const
204 {
205 return getScaled<TRet>();
206 }
207
212 template <typename TScaled>
213 void setScaled(TScaled val)
214 {
215 using TagTmp =
216 typename comms::util::LazyShallowConditional<
217 ParsedOptions::HasScalingRatio
218 >::template Type<
219 HasScalingRatioTag,
220 NoScalingRatioTag
221 >;
222
223 return setScaledInternal(val, TagTmp());
224 }
225
227 const ValueType& value() const
228 {
229 return BaseImpl::value();
230 }
231
234 {
235 return BaseImpl::value();
236 }
237
240 const ValueType& getValue() const
241 {
242 return BaseImpl::getValue();
243 }
244
247 template <typename U>
248 void setValue(U&& val)
249 {
250 BaseImpl::setValue(std::forward<U>(val));
251 }
252
254 static constexpr ValueType maxValue()
255 {
256 return std::numeric_limits<ValueType>::max();
257 }
258
260 static constexpr ValueType minValue()
261 {
262 return std::numeric_limits<ValueType>::min();
263 }
264
267 constexpr std::size_t length() const
268 {
269 return BaseImpl::length();
270 }
271
274 static constexpr std::size_t minLength()
275 {
276 return BaseImpl::minLength();
277 }
278
281 static constexpr std::size_t maxLength()
282 {
283 return BaseImpl::maxLength();
284 }
285
287 bool valid() const
288 {
289 return BaseImpl::valid();
290 }
291
294 bool refresh()
295 {
296 return BaseImpl::refresh();
297 }
298
304 template <typename TIter>
305 ErrorStatus read(TIter& iter, std::size_t size)
306 {
307 return BaseImpl::read(iter, size);
308 }
309
312 static constexpr bool hasReadNoStatus()
313 {
314 return BaseImpl::hasReadNoStatus();
315 }
316
322 template <typename TIter>
323 void readNoStatus(TIter& iter)
324 {
325 BaseImpl::readNoStatus(iter);
326 }
327
329 bool canWrite() const
330 {
331 return BaseImpl::canWrite();
332 }
333
339 template <typename TIter>
340 ErrorStatus write(TIter& iter, std::size_t size) const
341 {
342 return BaseImpl::write(iter, size);
343 }
344
347 static constexpr bool hasWriteNoStatus()
348 {
349 return BaseImpl::hasWriteNoStatus();
350 }
351
357 template <typename TIter>
358 void writeNoStatus(TIter& iter) const
359 {
360 BaseImpl::writeNoStatus(iter);
361 }
362
364 static constexpr bool isVersionDependent()
365 {
366 return ParsedOptions::HasCustomVersionUpdate || BaseImpl::isVersionDependent();
367 }
368
370 static constexpr bool hasNonDefaultRefresh()
371 {
372 return BaseImpl::hasNonDefaultRefresh();
373 }
374
378 {
379 return BaseImpl::getVersion();
380 }
381
385 {
386 return BaseImpl::setVersion(version);
387 }
388
396 void setForcedLength(int len)
397 {
398 BaseImpl::setForcedLength(len);
399 }
400
403 int getForcedLength() const
404 {
405 return BaseImpl::getForcedLength();
406 }
407
408protected:
409 using BaseImpl::readData;
410 using BaseImpl::writeData;
411
412private:
413 template <typename... TParams>
414 using HasScalingRatioTag = comms::details::tag::Tag1<>;
415
416 template <typename... TParams>
417 using NoScalingRatioTag = comms::details::tag::Tag2<>;
418
419 template <typename... TParams>
420 using ScaleAsFpTag = comms::details::tag::Tag3<>;
421
422 template <typename... TParams>
423 using ScaleAsIntTag = comms::details::tag::Tag4<>;
424
425 template <typename TRet, typename... TParams>
426 TRet scaleAsInternal(HasScalingRatioTag<TParams...>) const
427 {
428 using TagTmp =
429 typename comms::util::LazyShallowConditional<
430 std::is_floating_point<TRet>::value
431 >::template Type<
432 ScaleAsFpTag,
433 ScaleAsIntTag
434 >;
435
436 return scaleAsInternal<TRet>(TagTmp());
437 }
438
439 template <typename TRet, typename... TParams>
440 TRet scaleAsInternal(ScaleAsFpTag<TParams...>) const
441 {
442 static_assert(std::is_floating_point<TRet>::value,
443 "TRet is expected to be floating point type");
444 return static_cast<TRet>(BaseImpl::value()) * (static_cast<TRet>(ParsedOptions::ScalingRatio::num) / static_cast<TRet>(ParsedOptions::ScalingRatio::den));
445 }
446
447 template <typename TRet, typename... TParams>
448 TRet scaleAsInternal(ScaleAsIntTag<TParams...>) const
449 {
450 static_assert(std::is_integral<TRet>::value,
451 "TRet is expected to be integral type");
452
453 using CastType =
455 std::is_signed<TRet>::value
456 >::template Type<
457 std::intmax_t,
458 std::uintmax_t
459 >;
460
461 return
462 static_cast<TRet>(
463 (static_cast<CastType>(BaseImpl::value()) * ParsedOptions::ScalingRatio::num) / ParsedOptions::ScalingRatio::den);
464 }
465
466 template <typename TRet, typename... TParams>
467 TRet scaleAsInternal(NoScalingRatioTag<TParams...>) const
468 {
469 return static_cast<TRet>(BaseImpl::value());
470 }
471
472 template <typename TScaled, typename... TParams>
473 void setScaledInternal(TScaled val, HasScalingRatioTag<TParams...>)
474 {
475 using TagTmp =
476 typename comms::util::LazyShallowConditional<
477 std::is_floating_point<typename std::decay<decltype(val)>::type>::value
478 >::template Type<
479 ScaleAsFpTag,
480 ScaleAsIntTag
481 >;
482
483 setScaledInternal(val, TagTmp());
484 }
485
486 template <typename TScaled, typename... TParams>
487 void setScaledInternal(TScaled val, ScaleAsFpTag<TParams...>)
488 {
489 using DecayedType = typename std::decay<decltype(val)>::type;
490 auto epsilon = DecayedType(0);
491 if (ParsedOptions::ScalingRatio::num < ParsedOptions::ScalingRatio::den) {
492 epsilon = static_cast<DecayedType>(ParsedOptions::ScalingRatio::num) / static_cast<DecayedType>(ParsedOptions::ScalingRatio::den + 1);
493 }
494
495 if (epsilon < DecayedType(0)) {
496 epsilon = -epsilon;
497 }
498
499 if (val < DecayedType(0)) {
500 epsilon = -epsilon;
501 }
502
503 BaseImpl::value() =
504 static_cast<ValueType>(
505 ((val + epsilon) * static_cast<DecayedType>(ParsedOptions::ScalingRatio::den)) / static_cast<DecayedType>(ParsedOptions::ScalingRatio::num));
506 }
507
508 template <typename TScaled, typename... TParams>
509 void setScaledInternal(TScaled val, ScaleAsIntTag<TParams...>)
510 {
511 using CastType =
513 std::is_signed<typename std::decay<decltype(val)>::type>::value
514 >::template Type<
515 std::intmax_t,
516 std::uintmax_t
517 >;
518
519 BaseImpl::value() =
520 static_cast<ValueType>(
521 (static_cast<CastType>(val) * ParsedOptions::ScalingRatio::den) / static_cast<CastType>(ParsedOptions::ScalingRatio::num));
522 }
523
524 template <typename TScaled, typename... TParams>
525 void setScaledInternal(TScaled val, NoScalingRatioTag<TParams...>)
526 {
527 BaseImpl::value() = static_cast<ValueType>(val);
528 }
529
530 static_assert(!ParsedOptions::HasSequenceElemLengthForcing,
531 "comms::option::def::SequenceElemLengthForcingEnabled option is not applicable to IntValue field");
532 static_assert(!ParsedOptions::HasSequenceSizeForcing,
533 "comms::option::def::SequenceSizeForcingEnabled option is not applicable to IntValue field");
534 static_assert(!ParsedOptions::HasSequenceLengthForcing,
535 "comms::option::def::SequenceLengthForcingEnabled option is not applicable to IntValue field");
536 static_assert(!ParsedOptions::HasSequenceFixedSize,
537 "comms::option::def::SequenceFixedSize option is not applicable to IntValue field");
538 static_assert(!ParsedOptions::HasSequenceFixedSizeUseFixedSizeStorage,
539 "comms::option::app::SequenceFixedSizeUseFixedSizeStorage option is not applicable to IntValue field");
540 static_assert(!ParsedOptions::HasSequenceSizeFieldPrefix,
541 "comms::option::def::SequenceSizeFieldPrefix option is not applicable to IntValue field");
542 static_assert(!ParsedOptions::HasSequenceSerLengthFieldPrefix,
543 "comms::option::def::SequenceSerLengthFieldPrefix option is not applicable to IntValue field");
544 static_assert(!ParsedOptions::HasSequenceElemSerLengthFieldPrefix,
545 "comms::option::def::SequenceElemSerLengthFieldPrefix option is not applicable to IntValue field");
546 static_assert(!ParsedOptions::HasSequenceElemFixedSerLengthFieldPrefix,
547 "comms::option::def::SequenceElemSerLengthFixedFieldPrefix option is not applicable to IntValue field");
548 static_assert(!ParsedOptions::HasSequenceTrailingFieldSuffix,
549 "comms::option::def::SequenceTrailingFieldSuffix option is not applicable to IntValue field");
550 static_assert(!ParsedOptions::HasSequenceTerminationFieldSuffix,
551 "comms::option::def::SequenceTerminationFieldSuffix option is not applicable to IntValue field");
552 static_assert(!ParsedOptions::HasFixedSizeStorage,
553 "comms::option::app::FixedSizeStorage option is not applicable to IntValue field");
554 static_assert(!ParsedOptions::HasCustomStorageType,
555 "comms::option::app::CustomStorageType option is not applicable to IntValue field");
556 static_assert(!ParsedOptions::HasOrigDataView,
557 "comms::option::app::OrigDataView option is not applicable to IntValue field");
558 static_assert(!ParsedOptions::HasVersionsRange,
559 "comms::option::def::ExistsBetweenVersions (or similar) option is not applicable to IntValue field");
560 static_assert(!ParsedOptions::HasMissingOnReadFail,
561 "comms::option::def::MissingOnReadFail option is not applicable to IntValue field");
562 static_assert(!ParsedOptions::HasMissingOnInvalid,
563 "comms::option::def::MissingOnInvalid option is not applicable to IntValue field");
564};
565
566
572template <typename TFieldBase, typename T, typename... TOptions>
575 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
576{
577 return field1.value() == field2.value();
578}
579
585template <typename TFieldBase, typename T, typename... TOptions>
588 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
589{
590 return field1.value() != field2.value();
591}
592
598template <typename TFieldBase, typename T, typename... TOptions>
601 const IntValue<TFieldBase, T, TOptions...>& field2) noexcept
602{
603 return field1.value() < field2.value();
604}
605
611template <typename T>
612constexpr bool isIntValue()
613{
614 return std::is_same<typename T::CommsTag, tag::Int>::value;
615}
616
620template <typename TFieldBase, typename T, typename... TOptions>
621inline
622IntValue<TFieldBase, T, TOptions...>&
624{
625 return field;
626}
627
631template <typename TFieldBase, typename T, typename... TOptions>
632inline
633const IntValue<TFieldBase, T, TOptions...>&
635{
636 return field;
637}
638
639} // namespace field
640
641} // namespace comms
642
643COMMS_MSVC_WARNING_POP
644
Contains various compiler related definitions.
This file contain definition of error statuses used by comms module.
Field that represent integral value.
Definition IntValue.h:72
static constexpr ValueType minValue()
Get minimal numeric value the field can hold.
Definition IntValue.h:260
typename BaseImpl::ValueType ValueType
Type of underlying integral value.
Definition IntValue.h:93
IntValue()=default
Default constructor.
static constexpr bool hasFieldType()
Compile time inquiry of whether comms::option::def::FieldType option has been used.
Definition IntValue.h:168
details::OptionsParser< TOptions... > ParsedOptions
All the options provided to this class bundled into struct.
Definition IntValue.h:86
void setScaled(TScaled val)
Opposite operation to getScaled().
Definition IntValue.h:213
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:623
typename BaseImpl::CommsTag CommsTag
Tag indicating type of the field.
Definition IntValue.h:89
~IntValue() noexcept=default
Destructor.
typename BaseImpl::VersionType VersionType
Version type.
Definition IntValue.h:83
bool setVersion(VersionType version)
Default implementation of version update.
Definition IntValue.h:384
typename ParsedOptions::FieldType FieldType
Type of actual extending field specified via comms::option::def::FieldType.
Definition IntValue.h:110
IntValue(const IntValue &)=default
Copy constructor.
bool valid() const
Check validity of the field value.
Definition IntValue.h:287
static constexpr bool hasScaling()
Compile time inquiry of whether scaling ratio has been provided via comms::option::def::ScalingRatio ...
Definition IntValue.h:161
typename ParsedOptions::UnitsType UnitsType
Units type defined by any of the comms::option::def::Units* option.
Definition IntValue.h:97
static constexpr bool hasWriteNoStatus()
Compile time check of whether the field has proper writeNoStatus() member function.
Definition IntValue.h:347
int getForcedLength() const
Get forced serialization length.
Definition IntValue.h:403
static constexpr bool hasIgnoreInvalid()
Compile time inquiry of whether comms::option::def::IgnoreInvalid option has been used.
Definition IntValue.h:140
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:634
bool operator==(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Equality comparison operator.
Definition IntValue.h:573
typename ParsedOptions::ScalingRatio ScalingRatio
Scaling ratio defined by the comms::option::def::ScalingRatio option.
Definition IntValue.h:101
typename ParsedOptions::UnitsRatio UnitsRatio
Scaling ratio determined by the forced units via the comms::option::def::Units* option.
Definition IntValue.h:105
VersionType getVersion() const
Get version of the field.
Definition IntValue.h:377
constexpr std::size_t length() const
Get length required to serialise the current field value.
Definition IntValue.h:267
static constexpr std::size_t maxLength()
Get maximal length that is required to serialise field of this type.
Definition IntValue.h:281
void readNoStatus(TIter &iter)
Read field value from input data sequence without error check and status report.
Definition IntValue.h:323
ValueType & value()
Get access to integral value storage.
Definition IntValue.h:233
static constexpr bool hasEmptySerialization()
Compile time inquiry of whether comms::option::def::EmptySerialization option has been used.
Definition IntValue.h:147
static constexpr std::size_t minLength()
Get minimal length that is required to serialise field of this type.
Definition IntValue.h:274
bool operator<(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Equivalence comparison operator.
Definition IntValue.h:599
TFieldBase FieldBase
Base class provided in the first template parameter.
Definition IntValue.h:77
bool operator!=(const IntValue< TFieldBase, T, TOptions... > &field1, const IntValue< TFieldBase, T, TOptions... > &field2) noexcept
Non-equality comparison operator.
Definition IntValue.h:586
static constexpr ValueType maxValue()
Get maximal numeric value the field can hold.
Definition IntValue.h:254
static constexpr bool hasReadNoStatus()
Compile time check of whether the field has proper readNoStatus() member function.
Definition IntValue.h:312
constexpr TRet getScaled() const
Scales value according to ratio specified in provided comms::option::def::ScalingRatio option.
Definition IntValue.h:188
ErrorStatus read(TIter &iter, std::size_t size)
Read field value from input data sequence.
Definition IntValue.h:305
void setForcedLength(int len)
Force serialization length of the field.
Definition IntValue.h:396
void setValue(U &&val)
Set value.
Definition IntValue.h:248
constexpr TRet scaleAs() const
Same as getScaled()
Definition IntValue.h:203
ErrorStatus write(TIter &iter, std::size_t size) const
Write current field value to output data sequence.
Definition IntValue.h:340
static constexpr bool hasNonDefaultRefresh()
Compile time check if this class has non-default refresh functionality.
Definition IntValue.h:370
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:154
const ValueType & value() const
Get access to integral value storage.
Definition IntValue.h:227
typename BaseImpl::Endian Endian
Endian used for serialisation.
Definition IntValue.h:80
void writeNoStatus(TIter &iter) const
Write current field value to output data sequence without error check and status report.
Definition IntValue.h:358
static constexpr bool isVersionDependent()
Compile time check if this class is version dependent.
Definition IntValue.h:364
bool refresh()
Refresh the field's value.
Definition IntValue.h:294
IntValue(const ValueType &val)
Constructor.
Definition IntValue.h:117
bool canWrite() const
Check of whether the field has a consistent value for writing.
Definition IntValue.h:329
static constexpr bool hasVarLength()
Compile time inquiry of whether comms::option::def::VarLength option has been used.
Definition IntValue.h:175
constexpr bool isIntValue()
Compile time check function of whether a provided type is any variant of comms::field::IntValue.
Definition IntValue.h:612
const ValueType & getValue() const
Get value.
Definition IntValue.h:240
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.