cc_tools_qt
Common Environment for Protocol Analysis.
Loading...
Searching...
No Matches
ToolsIntFieldImpl.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/ToolsIntField.h"
24
25#include "comms/field/IntValue.h"
26
27#include <cstdint>
28#include <cassert>
29#include <memory>
30#include <type_traits>
31
32namespace cc_tools_qt
33{
34
35namespace details
36{
37
38template <typename TField>
39class ToolsIntFieldImpl : public ToolsNumericFieldImpl<cc_tools_qt::field::ToolsIntField, TField>
40{
41 using Base = ToolsNumericFieldImpl<cc_tools_qt::field::ToolsIntField, TField>;
42 using Field = TField;
43 static_assert(comms::field::isIntValue<Field>(), "Must be of comms::field::IntValue type");
44
45public:
46
47 using UnderlyingType = typename Base::UnderlyingType;
48 using Ptr = typename Base::Ptr;
49 using ActPtr = typename Base::ActPtr;
50 using SpecialsList = typename Base::SpecialsList;
51
52 explicit ToolsIntFieldImpl(Field& fieldRef)
53 : Base(fieldRef)
54 {
55 }
56
57 ToolsIntFieldImpl(const ToolsIntFieldImpl&) = default;
58 ToolsIntFieldImpl(ToolsIntFieldImpl&&) = default;
59 virtual ~ToolsIntFieldImpl() noexcept = default;
60
61 ToolsIntFieldImpl& operator=(const ToolsIntFieldImpl&) = delete;
62
63protected:
64 virtual UnderlyingType minValueImpl() const override
65 {
66 return std::numeric_limits<typename Field::ValueType>::min();
67 }
68
69 virtual UnderlyingType maxValueImpl() const override
70 {
71 return std::numeric_limits<typename Field::ValueType>::max();
72 }
73
74 virtual double getScaledImpl() const override
75 {
76 return Base::field().template scaleAs<double>();
77 }
78
79 virtual void setScaledImpl(double value) override
80 {
81 using Tag =
82 std::conditional_t<
83 Field::hasFixedValue(),
84 NoFeatureTag,
85 HasFeatureTag
86 >;
87
88 setScaledInternal(value, Tag());
89 }
90
91 virtual double scaleValueImpl(UnderlyingType value) const override
92 {
93 using Tag =
94 std::conditional_t<
95 Field::hasFixedValue(),
96 NoFeatureTag,
97 HasFeatureTag
98 >;
99 return scaleValueInternal(value, Tag());
100 }
101
102 virtual bool isSignedImpl() const override
103 {
104 return std::is_signed<typename Field::ValueType>::value;
105 }
106
107 virtual std::size_t valueTypeSizeImpl() const override
108 {
109 return sizeof(typename Field::ValueType);
110 }
111
112 virtual Ptr cloneImpl() override
113 {
114 return ActPtr(new ToolsIntFieldImpl<TField>(Base::field()));
115 }
116
117 virtual const SpecialsList& specialsImpl() const override
118 {
119 using Tag =
120 std::conditional_t<
121 Field::hasSpecials(),
122 HasFeatureTag,
123 NoFeatureTag
124 >;
125
126 return specialsInternal(Tag());
127 }
128
129 virtual int scaledDecimalsImpl() const override
130 {
131 using Tag =
132 std::conditional_t<
133 Field::hasScaling(),
134 HasFeatureTag,
135 NoFeatureTag
136 >;
137
138 return scaledDecimalsInternal(Tag());
139 }
140
141 virtual UnderlyingType getDisplayValueImpl() const override
142 {
143 return static_cast<UnderlyingType>(Base::field().getDisplayValue());
144 }
145
146 virtual void setDisplayValueImpl(UnderlyingType value) override
147 {
148 using Tag =
149 std::conditional_t<
150 Field::hasFixedValue(),
151 NoFeatureTag,
152 HasFeatureTag
153 >;
154
155 setDisplayValueInternal(value, Tag());
156 }
157
158private:
159 struct HasFeatureTag{};
160 struct NoFeatureTag{};
161
162 static const SpecialsList& specialsInternal(HasFeatureTag)
163 {
164 static const SpecialsList List = createSpecialsList();
165 return List;
166 }
167
168 static const SpecialsList& specialsInternal(NoFeatureTag)
169 {
170 static const SpecialsList List;
171 return List;
172 }
173
174 static int scaledDecimalsInternal(HasFeatureTag)
175 {
176 return Field::displayDecimals();
177 }
178
179 static int scaledDecimalsInternal(NoFeatureTag)
180 {
181 return 0;
182 }
183
184 static SpecialsList createSpecialsList()
185 {
186 SpecialsList result;
187 auto mapInfo = Field::specialNamesMap();
188 for (auto idx = 0U; idx < mapInfo.second; ++idx) {
189 auto& sInfo = mapInfo.first[idx];
190 result.append(qMakePair(sInfo.second, static_cast<UnderlyingType>(sInfo.first)));
191 }
192
193 return result;
194 }
195
196 void setScaledInternal(double value, HasFeatureTag)
197 {
198 Base::field().setScaled(value);
199 }
200
201 void setScaledInternal([[maybe_unused]] double value, NoFeatureTag)
202 {
203 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
204 assert(Must_not_be_called);
205 }
206
207 static double scaleValueInternal(UnderlyingType value, HasFeatureTag)
208 {
209 Field fieldTmp;
210 fieldTmp.setValue(value);
211 return fieldTmp.template scaleAs<double>();
212 }
213
214 static double scaleValueInternal([[maybe_unused]] UnderlyingType value, NoFeatureTag)
215 {
216 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
217 assert(Must_not_be_called);
218 return 0.0;
219 }
220
221 void setDisplayValueInternal(UnderlyingType value, HasFeatureTag)
222 {
223 Base::field().setDisplayValue(value);
224 }
225
226 void setDisplayValueInternal([[maybe_unused]] UnderlyingType value, NoFeatureTag)
227 {
228 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
229 assert(Must_not_be_called);
230 }
231
232};
233
234template <typename TField>
235auto makeIntField(TField& field)
236{
237 return std::make_unique<ToolsIntFieldImpl<TField>>(field);
238}
239
240} // namespace details
241
242} // namespace cc_tools_qt
Main namespace for all classes / functions of the shared library.