ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
FixedPointConverter.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4
5#include "Exception.h"
7
8#include <boost/fusion/algorithm.hpp>
9#include <boost/fusion/container.hpp>
10#include <boost/fusion/sequence.hpp>
11#include <boost/numeric/conversion/cast.hpp>
12
13#include <bit>
14#include <cassert>
15#include <cmath>
16#include <cstdint>
17#include <iostream>
18#include <limits>
19#include <sstream>
20#include <stdexcept>
21#include <string>
22#include <type_traits>
23
24namespace ChimeraTK {
25
30 template<typename RawType>
32 public:
47 std::string variableName, unsigned int nBits = 32, int fractionalBits = 0, bool isSignedFlag = true);
48
56 template<typename UserType>
57 RawType toRaw(UserType cookedValue) const;
58
63 template<typename UserType, typename RAW_ITERATOR, typename COOKED_ITERATOR>
65 const RAW_ITERATOR& raw_begin, const RAW_ITERATOR& raw_end, const COOKED_ITERATOR& cooked_begin) const {
66 static_assert(std::is_same<typename std::iterator_traits<RAW_ITERATOR>::iterator_category,
67 std::random_access_iterator_tag>::value,
68 "RAW_ITERATOR template argument must be a random access iterator.");
69 static_assert(std::is_same<typename std::iterator_traits<COOKED_ITERATOR>::iterator_category,
70 std::random_access_iterator_tag>::value,
71 "COOKED_ITERATOR template argument must be a random access iterator.");
72 static_assert(std::is_same<typename std::iterator_traits<RAW_ITERATOR>::value_type, int8_t>::value ||
73 std::is_same<typename std::iterator_traits<RAW_ITERATOR>::value_type, int16_t>::value ||
74 std::is_same<typename std::iterator_traits<RAW_ITERATOR>::value_type, int32_t>::value ||
75 std::is_same<typename std::iterator_traits<RAW_ITERATOR>::value_type, int64_t>::value,
76 "RAW_ITERATOR template argument must be an iterator with value type equal to int8_t, int16_t, int32_t or "
77 "int64_t");
78 static_assert(std::is_same<typename std::iterator_traits<COOKED_ITERATOR>::value_type, UserType>::value,
79 "COOKED_ITERATOR template argument must be an iterator with value type equal to the UserType template "
80 "argument.");
81 vectorToCooked_impl<UserType, RAW_ITERATOR, COOKED_ITERATOR>::impl(*this, raw_begin, raw_end, cooked_begin);
82 }
83 template<typename UserType, typename RAW_ITERATOR, typename COOKED_ITERATOR>
85 static void impl(const FixedPointConverter& fpc, const RAW_ITERATOR& raw_begin, const RAW_ITERATOR& raw_end,
86 COOKED_ITERATOR cooked_begin);
87 };
88
90 template<typename UserType>
91 UserType scalarToCooked(RawType const& raw) const {
92 UserType cooked;
93 vectorToCooked<UserType>(&raw, (&raw) + 1, &cooked);
94 return cooked;
95 }
96
98 [[nodiscard]] unsigned int getNBits() const { return _nBits; }
99
101 [[nodiscard]] int getFractionalBits() const { return _fractionalBits; }
102
104 [[nodiscard]] bool isSigned() const { return _isSigned; }
105
108 bool operator==(const FixedPointConverter& other) const {
109 return _nBits == other._nBits && _fractionalBits == other._fractionalBits && _isSigned == other._isSigned;
110 }
111 bool operator!=(const FixedPointConverter& other) const { return !operator==(other); }
112
113 private:
114 std::string _variableName;
115 unsigned int _nBits;
116 int _fractionalBits;
117 bool _isSigned;
118
121 double _fractionalBitsCoefficient;
122
126 double _inverseFractionalBitsCoefficient;
127
128 RawType _signBitMask{};
129 RawType _usedBitsMask{};
130 RawType _unusedBitsMask{};
131
132 RawType _maxRawValue{};
133 RawType _minRawValue{};
134
136 userTypeMap _maxCookedValues;
137
139 userTypeMap _minCookedValues;
140
143 FixedUserTypeMap<int> conversionBranch_toCooked;
144
147 const static int zero;
148
150 class initCoefficients {
151 public:
152 explicit initCoefficients(FixedPointConverter* fpc) : _fpc(fpc) {}
153
154 template<typename Pair>
155 void operator()(Pair) const {
156 // obtain UserType from given fusion::pair type
157 using UserType = typename Pair::first_type;
158
159 // compute conversion branches. Needs to be done before the subsequent calls to toCooked()!
160 if(_fpc->_nBits == 16 && _fpc->_fractionalBits == 0 && !_fpc->_isSigned) {
161 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 9;
162 }
163 else if(_fpc->_nBits == 16 && _fpc->_fractionalBits == 0 && _fpc->_isSigned) {
164 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 10;
165 }
166 else if(std::numeric_limits<UserType>::is_integer && _fpc->_fractionalBits == 0 && !_fpc->_isSigned) {
167 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 1;
168 }
169 else if(std::numeric_limits<UserType>::is_integer && _fpc->_fractionalBits == 0 && _fpc->_isSigned) {
170 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 2;
171 }
172 else if(_fpc->_nBits == 16 && _fpc->_fractionalBits < 0 && _fpc->_fractionalBits > -16 && !_fpc->_isSigned) {
173 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 7;
174 }
175 else if(_fpc->_nBits == 16 && _fpc->_fractionalBits < 0 && _fpc->_fractionalBits > -16 && _fpc->_isSigned) {
176 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 8;
177 }
178 else if(_fpc->_nBits == 16 && !_fpc->_isSigned) {
179 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 5;
180 }
181 else if(_fpc->_nBits == 16 && _fpc->_isSigned) {
182 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 6;
183 }
184 else if(!_fpc->_isSigned) {
185 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 3;
186 }
187 else if(_fpc->_isSigned) {
188 boost::fusion::at_key<UserType>(_fpc->conversionBranch_toCooked.table) = 4;
189 }
190
191 // compute minimum and maximum values in cooked representation
192 try {
193 boost::fusion::at_key<UserType>(_fpc->_minCookedValues) = _fpc->scalarToCooked<UserType>(_fpc->_minRawValue);
194 }
195 catch(boost::numeric::negative_overflow& e) {
196 boost::fusion::at_key<UserType>(_fpc->_minCookedValues) = std::numeric_limits<UserType>::min();
197 }
198 try {
199 boost::fusion::at_key<UserType>(_fpc->_maxCookedValues) = _fpc->scalarToCooked<UserType>(_fpc->_maxRawValue);
200 }
201 catch(boost::numeric::positive_overflow& e) {
202 boost::fusion::at_key<UserType>(_fpc->_maxCookedValues) = std::numeric_limits<UserType>::max();
203 }
204 }
205
206 private:
207 FixedPointConverter* _fpc;
208 };
209
211 template<class S>
212 struct Round {
213 static S nearbyint(S s) { return round(s); }
214
215 using round_style = boost::mpl::integral_c<std::float_round_style, std::round_to_nearest>;
216 };
217
220 template<typename UserType, typename std::enable_if<std::is_signed<UserType>{}, int>::type = 0>
221 bool isNegativeUserType(UserType value) const;
222 template<typename UserType, typename std::enable_if<!std::is_signed<UserType>{}, int>::type = 0>
223 bool isNegativeUserType(UserType value) const;
224
225 // helper function: force unused leading bits to 0 for positive or 1 for negative numbers
226 // NOLINTBEGIN(hicpp-signed-bitwise)
227 // NOLINTBEGIN(bugprone-narrowing-conversions)
228 // Turn off the linter warning. Yes, we are fiddling with the bit interpretation here, that's the whole point.
229 void padUnusedBits(RawType& rawValue) const {
230 if(!(rawValue & _signBitMask)) {
231 rawValue &= _usedBitsMask;
232 }
233 else {
234 rawValue |= _unusedBitsMask;
235 }
236 }
237 // NOLINTEND(bugprone-narrowing-conversions)
238 // NOLINTEND(hicpp-signed-bitwise)
239 };
240
241 /********************************************************************************************************************/
242 template<typename RawType>
243 template<typename UserType, typename RAW_ITERATOR, typename COOKED_ITERATOR>
245 const FixedPointConverter& fpc, const RAW_ITERATOR& raw_begin, const RAW_ITERATOR& raw_end,
246 COOKED_ITERATOR cooked_begin) {
247 // Handle integer and floating-point types differently.
248 switch(boost::fusion::at_key<UserType>(fpc.conversionBranch_toCooked.table)) {
249 case 1: { // std::numeric_limits<UserType>::is_integer && _fpc->_fractionalBits == 0 && !_fpc->_isSigned
250 std::transform(raw_begin, raw_end, cooked_begin, [&fpc](RawType rawValue) {
251 fpc.padUnusedBits(rawValue);
252 if constexpr(sizeof(RawType) == 4) {
253 return numericToUserType<UserType>(*(std::bit_cast<uint32_t*>(&rawValue)));
254 }
255 else if constexpr(sizeof(RawType) == 8) {
256 return numericToUserType<UserType>(*(std::bit_cast<uint64_t*>(&rawValue)));
257 }
258 });
259 break;
260 }
261 case 2: { // std::numeric_limits<UserType>::is_integer && _fpc->_fractionalBits == 0 && _fpc->_isSigned
262 std::transform(raw_begin, raw_end, cooked_begin, [&fpc](RawType rawValue) {
263 fpc.padUnusedBits(rawValue);
264 return numericToUserType<UserType>(rawValue);
265 });
266 break;
267 }
268 case 9: { // _fpc->_nBits == 16 && _fpc->_fractionalBits == 0 && !_fpc->_isSigned
269 std::transform(raw_begin, raw_end, cooked_begin, [](const auto& rawValue) {
270 return numericToUserType<UserType>(*(std::bit_cast<const uint16_t*>(&rawValue)));
271 });
272 break;
273 }
274 case 10: { // _fpc->_nBits == 16 && _fpc->_fractionalBits == 0 && _fpc->_isSigned
275 std::transform(raw_begin, raw_end, cooked_begin, [](const auto& rawValue) {
276 return numericToUserType<UserType>(*(std::bit_cast<const int16_t*>(&rawValue)));
277 });
278 break;
279 }
280 case 7: { // _fpc->_nBits == 16 && _fpc->_fractionalBits < 0 && _fpc->_fractionalBits > -16 && !_fpc->_isSigned
281 const auto f = static_cast<uint32_t>(fpc._fractionalBitsCoefficient);
282 std::transform(raw_begin, raw_end, cooked_begin, [f](const auto& rawValue) {
283 return numericToUserType<UserType>(f * *(std::bit_cast<const uint16_t*>(&rawValue)));
284 });
285 break;
286 }
287 case 8: { // _fpc->_nBits == 16 && _fpc->_fractionalBits < 0 && _fpc->_fractionalBits > -16 && _fpc->_isSigned
288 const auto f = static_cast<int32_t>(fpc._fractionalBitsCoefficient);
289 std::transform(raw_begin, raw_end, cooked_begin, [f](const auto& rawValue) {
290 return numericToUserType<UserType>(f * *(std::bit_cast<const int16_t*>(&rawValue)));
291 });
292 break;
293 }
294 case 5: { // _fpc->_nBits == 16 && !_fpc->_isSigned
295 const auto f = fpc._fractionalBitsCoefficient;
296 std::transform(raw_begin, raw_end, cooked_begin, [f](const auto& rawValue) {
297 return numericToUserType<UserType>(f * *(std::bit_cast<const uint16_t*>(&rawValue)));
298 });
299 break;
300 }
301 case 6: { // _fpc->_nBits == 16 && _fpc->_isSigned
302 const auto f = fpc._fractionalBitsCoefficient;
303 std::transform(raw_begin, raw_end, cooked_begin, [f](const auto& rawValue) {
304 return numericToUserType<UserType>(f * *(std::bit_cast<const int16_t*>(&rawValue)));
305 });
306 break;
307 }
308 case 3: { // !_fpc->_isSigned
309 const auto f = fpc._fractionalBitsCoefficient;
310 std::transform(raw_begin, raw_end, cooked_begin, [&fpc, f](RawType rawValue) {
311 fpc.padUnusedBits(rawValue);
312 if constexpr(sizeof(RawType) == 4) {
313 return numericToUserType<UserType>(f * *(std::bit_cast<uint32_t*>(&rawValue)));
314 }
315 else if constexpr(sizeof(RawType) == 8) {
316 return numericToUserType<UserType>(f * *(std::bit_cast<uint64_t*>(&rawValue)));
317 }
318 });
319 break;
320 }
321 case 4: { // _fpc->_isSigned
322 const auto f = fpc._fractionalBitsCoefficient;
323 std::transform(raw_begin, raw_end, cooked_begin, [&fpc, f](RawType rawValue) {
324 fpc.padUnusedBits(rawValue);
325 auto ttt = numericToUserType<UserType>(f * rawValue);
326 return ttt;
327 });
328 break;
329 }
330 default: {
331 std::cerr << "Fixed point converter configuration is corrupt." << std::endl;
332 std::terminate();
333 }
334 }
335 }
336 // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
337
338 /********************************************************************************************************************/
339 template<typename RawType>
340 template<typename UserType>
341 RawType FixedPointConverter<RawType>::toRaw(UserType cookedValue) const {
342 if constexpr(std::is_same<UserType, std::string>::value) {
343 if(_fractionalBits == 0) { // use integer conversion
344 if(_isSigned) {
345 return toRaw(std::stoi(cookedValue));
346 }
347 return toRaw(std::stoul(cookedValue));
348 }
349
350 return toRaw(std::stod(cookedValue));
351 }
352 else if constexpr(std::is_same<UserType, Boolean>::value) {
353 if((bool)cookedValue) { // use integer conversion
354 return 1;
355 }
356 return 0;
357 }
358 else if constexpr(std::is_same<UserType, Void>::value) {
359 return 0;
360 }
361 else {
362 // Do a range check first. The later overflow check in the conversion is not
363 // sufficient, since we can have non-standard word sizes like 12 bits.
364 if(cookedValue < boost::fusion::at_key<UserType>(_minCookedValues)) {
365 return _minRawValue;
366 }
367 if(cookedValue > boost::fusion::at_key<UserType>(_maxCookedValues)) {
368 return _maxRawValue;
369 }
370
371 // handle integer and floating-point types differently
372 if constexpr(std::numeric_limits<UserType>::is_integer) {
373 if(_fractionalBits == 0) {
374 // extract the sign and leave the positive number
375 bool isNegative = isNegativeUserType(cookedValue);
376 if(isNegative && !_isSigned) {
377 return _minRawValue;
378 }
379 if(isNegative) {
380 cookedValue = -(cookedValue + 1); // bit inversion, ~ operator cannot be used as UserType might be double
381 }
382 // cast into raw type
383 auto rawValue = static_cast<RawType>(cookedValue);
384
385 // handle sign
386 if(_isSigned && isNegative) {
387 rawValue = ~rawValue;
388 }
389
390 // return with bit mask applied
391 return rawValue & _usedBitsMask;
392 }
393 }
394 // convert into double and scale by fractional bit coefficient
395 double d_cooked = _inverseFractionalBitsCoefficient * static_cast<double>(cookedValue);
396
397 // Convert into either signed or unsigned int32_t or int64t, depending on _isSigned,
398 // so the conversion handles the sign correctly and size of Raw type.
399 // Store always in RawType. The conversion will properly round, when
400 // needed. Negative and positive overflow exceptions need to be caught for some corner
401 // cases (e.g. number of fractional bits >= number of bits in total).
402 RawType raw;
403 try {
404 if(_isSigned) {
405 if constexpr(sizeof(RawType) == 4) {
406 using converter_signed =
407 boost::numeric::converter<int32_t, double, boost::numeric::conversion_traits<int32_t, double>,
408 boost::numeric::def_overflow_handler, Round<double>>;
409 raw = static_cast<RawType>(converter_signed::convert(d_cooked));
410 }
411 else if constexpr(sizeof(RawType) == 8) {
412 using converter_signed =
413 boost::numeric::converter<int64_t, double, boost::numeric::conversion_traits<int64_t, double>,
414 boost::numeric::def_overflow_handler, Round<double>>;
415 raw = static_cast<RawType>(converter_signed::convert(d_cooked));
416 }
417 }
418 else {
419 if constexpr(sizeof(RawType) == 4) {
420 using converter_unsigned =
421 boost::numeric::converter<uint32_t, double, boost::numeric::conversion_traits<uint32_t, double>,
422 boost::numeric::def_overflow_handler, Round<double>>;
423 raw = static_cast<RawType>(converter_unsigned::convert(d_cooked));
424 }
425 else if constexpr(sizeof(RawType) == 8) {
426 using converter_unsigned =
427 boost::numeric::converter<uint64_t, double, boost::numeric::conversion_traits<uint64_t, double>,
428 boost::numeric::def_overflow_handler, Round<double>>;
429 raw = static_cast<RawType>(converter_unsigned::convert(d_cooked));
430 }
431 }
432 }
433 catch(boost::numeric::negative_overflow& e) {
434 raw = _minRawValue;
435 }
436 catch(boost::numeric::positive_overflow& e) {
437 raw = _maxRawValue;
438 }
439
440 // apply bit mask
441 // NOLINTNEXTLINE(hicpp-signed-bitwise)
442 return raw & _usedBitsMask;
443 }
444 }
445
446 /********************************************************************************************************************/
447 template<typename RawType>
448 template<typename UserType, typename std::enable_if<std::is_signed<UserType>{}, int>::type>
449 bool FixedPointConverter<RawType>::isNegativeUserType(UserType value) const {
450 return static_cast<bool>(value < 0);
451 }
452
453 template<typename RawType>
454 template<typename UserType, typename std::enable_if<!std::is_signed<UserType>{}, int>::type>
455 bool FixedPointConverter<RawType>::isNegativeUserType(UserType /*value*/) const {
456 return false;
457 }
458
459 /********************************************************************************************************************/
460 /* specialization for a std::string as UserType*/
461 template<typename RawType>
462 template<typename RAW_ITERATOR, typename COOKED_ITERATOR>
463 struct FixedPointConverter<RawType>::vectorToCooked_impl<std::string, RAW_ITERATOR, COOKED_ITERATOR> {
464 static void impl(const FixedPointConverter& fpc, const RAW_ITERATOR& raw_begin, const RAW_ITERATOR& raw_end,
465 COOKED_ITERATOR cooked_begin) {
466 if(fpc._fractionalBits == 0) { // use integer conversion
467 if(fpc._isSigned) {
468 std::vector<int32_t> intValues(raw_end - raw_begin);
469 fpc.vectorToCooked<int32_t>(raw_begin, raw_end, intValues.begin());
470 for(auto it : intValues) {
471 *cooked_begin = std::to_string(it);
472 ++cooked_begin;
473 }
474 }
475 else {
476 std::vector<uint32_t> uintValues(raw_end - raw_begin);
477 fpc.vectorToCooked<uint32_t>(raw_begin, raw_end, uintValues.begin());
478 for(auto it : uintValues) {
479 *cooked_begin = std::to_string(it);
480 ++cooked_begin;
481 }
482 }
483 }
484 else {
485 std::vector<double> doubleValues(raw_end - raw_begin);
486 fpc.vectorToCooked<double>(raw_begin, raw_end, doubleValues.begin());
487 for(auto it : doubleValues) {
488 *cooked_begin = std::to_string(it);
489 ++cooked_begin;
490 }
491 }
492 }
493 };
494
495 /********************************************************************************************************************/
496 template<typename RawType>
498 std::string variableName, unsigned int nBits, int fractionalBits, bool isSignedFlag)
499 : _variableName(std::move(variableName)), _nBits(nBits), _fractionalBits(fractionalBits), _isSigned(isSignedFlag),
500 _fractionalBitsCoefficient(pow(2., -fractionalBits)), _inverseFractionalBitsCoefficient(pow(2., fractionalBits)) {
501 _fractionalBitsCoefficient = pow(2., -_fractionalBits);
502 _inverseFractionalBitsCoefficient = pow(2., _fractionalBits);
503
504 const auto maxBits = (sizeof(RawType) * 8);
505 if(nBits > maxBits) {
506 std::stringstream errorMessage;
507 errorMessage << "The number of bits must be <= " << maxBits << ", but is " << nBits;
508 throw ChimeraTK::logic_error(errorMessage.str());
509 }
510
511 // For floating-point types: check if number of fractional bits are complying
512 // with the dynamic range Note: positive fractional bits give us smaller
513 // numbers and thus correspond to negative exponents!
514 if((fractionalBits > -std::numeric_limits<double>::min_exponent - static_cast<int>(nBits)) ||
515 (fractionalBits < -std::numeric_limits<double>::max_exponent + static_cast<int>(nBits))) {
516 std::stringstream errorMessage;
517 errorMessage << "The number of fractional bits exceeds the dynamic"
518 << " range of a double.";
519 throw ChimeraTK::logic_error(errorMessage.str());
520 }
521
522 // compute mask for the signed bit
523 // keep the mask at 0 if unsigned to simplify further calculations
524 _signBitMask = 0;
525 if(_isSigned && nBits > 0) {
526 // NOLINTNEXTLINE(hicpp-signed-bitwise)
527 _signBitMask = RawType(1) << (nBits - 1); // the highest valid bit is the sign
528 }
529
530 // compute masks of used and unused bits
531 // NOLINTNEXTLINE(hicpp-signed-bitwise)
532 _usedBitsMask = ~RawType(0);
533 if(nBits < sizeof(RawType) * 8) {
534 _usedBitsMask = static_cast<RawType>((RawType(1) << nBits) - RawType(1));
535 }
536 // NOLINTNEXTLINE(hicpp-signed-bitwise)
537 _unusedBitsMask = ~_usedBitsMask;
538
539 // compute minimum and maximum value in raw representation
540 // NOLINTNEXTLINE(hicpp-signed-bitwise)
541 _maxRawValue = _usedBitsMask ^ _signBitMask; // bitwise xor: first bit is 0 if signed
542 // NOLINTNEXTLINE(hicpp-signed-bitwise)
543 _minRawValue = _signBitMask; // if only the sign bit is on, it is the smallest
544 // possible value
545 // (0 if unsigned)
546
547 // fill all user type depending values: min and max cooked values and
548 // fractional bit coefficients note: we loop over one of the maps only, but
549 // initCoefficients() will fill all maps!
550 boost::fusion::for_each(_minCookedValues, initCoefficients(this));
551 }
552
553 /********************************************************************************************************************/
555 /********************************************************************************************************************/
556} // namespace ChimeraTK
The fixed point converter provides conversion functions between a user type and up to 32 bit fixed po...
bool operator==(const FixedPointConverter &other) const
Compare two fixed point converters.
FixedPointConverter(std::string variableName, unsigned int nBits=32, int fractionalBits=0, bool isSignedFlag=true)
The constructor defines the conversion factor.
int getFractionalBits() const
Read back the fractional bits the converter is using.
bool operator!=(const FixedPointConverter &other) const
UserType scalarToCooked(RawType const &raw) const
Inefficient convenience function for converting a single value to cooked.
bool isSigned() const
Read back wether the conversion is using signed values.
unsigned int getNBits() const
Read back the number of bits the converter is using.
void vectorToCooked(const RAW_ITERATOR &raw_begin, const RAW_ITERATOR &raw_end, const COOKED_ITERATOR &cooked_begin) const
Conversion function from fixed-point values to type T.
RawType toRaw(UserType cookedValue) const
Conversion function from type T to fixed point.
boost::fusion::map< boost::fusion::pair< int8_t, TargetType >, boost::fusion::pair< uint8_t, TargetType >, boost::fusion::pair< int16_t, TargetType >, boost::fusion::pair< uint16_t, TargetType >, boost::fusion::pair< int32_t, TargetType >, boost::fusion::pair< uint32_t, TargetType >, boost::fusion::pair< int64_t, TargetType >, boost::fusion::pair< uint64_t, TargetType >, boost::fusion::pair< float, TargetType >, boost::fusion::pair< double, TargetType >, boost::fusion::pair< std::string, TargetType >, boost::fusion::pair< Boolean, TargetType >, boost::fusion::pair< Void, TargetType > > table
Exception thrown when a logic error has occured.
Definition Exception.h:51
boost::fusion::map< boost::fusion::pair< int8_t, int8_t >, boost::fusion::pair< uint8_t, uint8_t >, boost::fusion::pair< int16_t, int16_t >, boost::fusion::pair< uint16_t, uint16_t >, boost::fusion::pair< int32_t, int32_t >, boost::fusion::pair< uint32_t, uint32_t >, boost::fusion::pair< int64_t, int64_t >, boost::fusion::pair< uint64_t, uint64_t >, boost::fusion::pair< float, float >, boost::fusion::pair< double, double >, boost::fusion::pair< std::string, std::string >, boost::fusion::pair< Boolean, Boolean >, boost::fusion::pair< Void, Void > > userTypeMap
Map of UserType to value of the UserType.
int32_t DEPRECATED_FIXEDPOINT_DEFAULT
@ raw
Raw access: disable any possible conversion from the original hardware data type into the given UserT...
STL namespace.
std::string to_string(const std::string &v)
static void impl(const FixedPointConverter &fpc, const RAW_ITERATOR &raw_begin, const RAW_ITERATOR &raw_end, COOKED_ITERATOR cooked_begin)
static void impl(const FixedPointConverter &fpc, const RAW_ITERATOR &raw_begin, const RAW_ITERATOR &raw_end, COOKED_ITERATOR cooked_begin)