cc_tools_qt
Common Environment for Protocol Analysis.
Loading...
Searching...
No Matches
ToolsFloatFieldImpl.h
1//
2// Copyright 2014 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: GPL-3.0-or-later
5//
6
7// This file is free software: you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20#pragma once
21
22#include "cc_tools_qt/details/ToolsNumericFieldImpl.h"
23#include "cc_tools_qt/field/ToolsFloatField.h"
24
25#include "comms/field/FloatValue.h"
26
27#include <cstdint>
28#include <cassert>
29#include <cmath>
30#include <limits>
31
32namespace cc_tools_qt
33{
34
35namespace details
36{
37
38template <typename TField>
39class ToolsFloatFieldImpl : public ToolsNumericFieldImpl<cc_tools_qt::field::ToolsFloatField, TField>
40{
41 using Base = ToolsNumericFieldImpl<cc_tools_qt::field::ToolsFloatField, TField>;
42 using Field = TField;
43 static_assert(comms::field::isFloatValue<Field>(), "Must be of FloatValueField type");
44
45public:
46 using UnderlyingType = typename Base::UnderlyingType;
47 using Ptr = typename Base::Ptr;
48 using ActPtr = typename Base::ActPtr;
49 using SpecialsList = typename Base::SpecialsList;
50
51 explicit ToolsFloatFieldImpl(Field& fieldRef)
52 : Base(fieldRef)
53 {
54 }
55
56 ToolsFloatFieldImpl(const ToolsFloatFieldImpl&) = default;
57 ToolsFloatFieldImpl(ToolsFloatFieldImpl&&) = default;
58 virtual ~ToolsFloatFieldImpl() noexcept = default;
59
60 ToolsFloatFieldImpl& operator=(const ToolsFloatFieldImpl&) = delete;
61
62protected:
63 virtual Ptr cloneImpl() override
64 {
65 return ActPtr(new ToolsFloatFieldImpl<TField>(Base::field()));
66 }
67
68 virtual bool isNanImpl() const override
69 {
70 return std::isnan(Base::field().getValue());
71 }
72
73 virtual void setNanImpl() override
74 {
75 setFieldValueInternal(std::numeric_limits<typename TField::ValueType>::quiet_NaN());
76 }
77
78 virtual bool isInfImpl() const override
79 {
80 return std::isinf(Base::field().getValue()) && (0 < Base::field().getValue());
81 }
82
83 virtual void setInfImpl() override
84 {
85 setFieldValueInternal(std::numeric_limits<typename TField::ValueType>::infinity());
86 }
87
88 virtual bool isMinusInfImpl() const override
89 {
90 return std::isinf(Base::field().getValue()) && (Base::field().getValue() < 0);
91 }
92
93 virtual void setMinusInfImpl() override
94 {
95 setFieldValueInternal(-std::numeric_limits<typename TField::ValueType>::infinity());
96 }
97
98 virtual double getEpsilonImpl() const override
99 {
100 return static_cast<double>(std::numeric_limits<typename TField::ValueType>::epsilon());
101 }
102
103 virtual const SpecialsList& specialsImpl() const override
104 {
105 using Tag =
106 std::conditional_t<
107 Field::hasSpecials(),
108 HasFeatureTag,
109 NoFeatureTag
110 >;
111
112 return specialsInternal(Tag());
113 }
114
115 virtual int decimalsImpl() const override
116 {
117 return Field::displayDecimals();
118 }
119
120private:
121 struct HasFeatureTag{};
122 struct NoFeatureTag{};
123
124 void setFieldValueInternal(typename TField::ValueType val)
125 {
126 using Tag =
127 std::conditional_t<
128 Field::hasFixedValue(),
129 NoFeatureTag,
130 HasFeatureTag
131 >;
132
133 setFieldValueInternal(val, Tag());
134 }
135
136 void setFieldValueInternal(typename TField::ValueType val, HasFeatureTag)
137 {
138 Base::field().setValue(val);
139 }
140
141 void setFieldValueInternal([[maybe_unused]] typename TField::ValueType val, NoFeatureTag)
142 {
143 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
144 assert(Must_not_be_called);
145 }
146
147 static const SpecialsList& specialsInternal(HasFeatureTag)
148 {
149 static const SpecialsList List = createSpecialsList();
150 return List;
151 }
152
153 static const SpecialsList& specialsInternal(NoFeatureTag)
154 {
155 static const SpecialsList List;
156 return List;
157 }
158
159 static SpecialsList createSpecialsList()
160 {
161 SpecialsList result;
162 auto mapInfo = Field::specialNamesMap();
163 for (auto idx = 0U; idx < mapInfo.second; ++idx) {
164 auto& sInfo = mapInfo.first[idx];
165 result.append(qMakePair(sInfo.second, static_cast<UnderlyingType>(sInfo.first)));
166 }
167
168 return result;
169 }
170};
171
172template <typename TField>
173auto makeFloatField(TField& field)
174{
175 return std::make_unique<ToolsFloatFieldImpl<TField>>(field);
176}
177
178} // namespace details
179
180} // namespace cc_tools_qt
Main namespace for all classes / functions of the shared library.