highest_for<T>() (+22 bytes!!)

This commit is contained in:
Benoit Blanchon
2022-04-06 14:45:28 +02:00
parent e7afef895e
commit 42976551f8
2 changed files with 55 additions and 23 deletions

View File

@@ -12,6 +12,7 @@
#include <ArduinoJson/Polyfills/math.hpp>
#include <ArduinoJson/Polyfills/preprocessor.hpp>
#include <ArduinoJson/Polyfills/static_array.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
namespace ARDUINOJSON_NAMESPACE {
@@ -116,11 +117,28 @@ struct FloatTraits<T, 8 /*64bits*/> {
return forge(0x7FEFFFFF, 0xFFFFFFFF);
}
static T highest_for(int64_t) {
template <typename TOut>
static
typename enable_if<is_integral<TOut>::value && sizeof(TOut) < sizeof(T),
T>::type
highest_for() {
// This conversion is safe because the destination type is smaller
return highest();
}
template <typename TOut>
static typename enable_if<is_integral<TOut>::value &&
is_signed<TOut>::value && sizeof(TOut) == 8,
T>::type // TOut == int64_t
highest_for() {
return forge(0x43DFFFFF, 0xFFFFFFFF); // 9.2233720368547748e+18
}
static T highest_for(uint64_t) {
template <typename TOut>
static typename enable_if<is_integral<TOut>::value &&
is_unsigned<TOut>::value && sizeof(TOut) == 8,
T>::type // TOut == uint64_t
highest_for() {
return forge(0x43EFFFFF, 0xFFFFFFFF); // 1.8446744073709549568e+19
}
@@ -220,19 +238,44 @@ struct FloatTraits<T, 4 /*32bits*/> {
return forge(0x7f7fffff);
}
static T highest_for(int32_t) {
template <typename TOut>
static
typename enable_if<is_integral<TOut>::value && sizeof(TOut) < sizeof(T),
T>::type
highest_for() {
// This conversion is safe because the destination type is smaller
return highest();
}
template <typename TOut>
static typename enable_if<is_integral<TOut>::value &&
is_signed<TOut>::value && sizeof(TOut) == 4,
T>::type // TOut == int32_t
highest_for() {
return forge(0x4EFFFFFF); // 2.14748352E9
}
static T highest_for(uint32_t) {
template <typename TOut>
static typename enable_if<is_integral<TOut>::value &&
is_unsigned<TOut>::value && sizeof(TOut) == 4,
T>::type // TOut == uint32_t
highest_for() {
return forge(0x4F7FFFFF); // 4.29496704E9
}
static T highest_for(int64_t) {
template <typename TOut>
static typename enable_if<is_integral<TOut>::value &&
is_signed<TOut>::value && sizeof(TOut) == 8,
T>::type // TOut == int64_t
highest_for() {
return forge(0x5EFFFFFF); // 9.22337148709896192E18
}
static T highest_for(uint64_t) {
template <typename TOut>
static typename enable_if<is_integral<TOut>::value &&
is_unsigned<TOut>::value && sizeof(TOut) == 8,
T>::type // TOut == uint64_t
highest_for() {
return forge(0x5F7FFFFF); // 1.844674297419792384E19
}

View File

@@ -96,33 +96,22 @@ canConvertNumber(TIn value) {
return value <= TIn(numeric_limits<TOut>::highest());
}
// float32 -> int8
// float32 -> int16
// float64 -> int32
template <typename TOut, typename TIn>
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value &&
sizeof(TOut) < sizeof(TIn),
bool>::type
canConvertNumber(TIn value) {
return value >= numeric_limits<TOut>::lowest() &&
value <= numeric_limits<TOut>::highest();
}
// float32 -> int32
// float32 -> uint32
// float32 -> int64
// float32 -> int8
// float32 -> uint32
// float32 -> uint64
// float64 -> int32
// float64 -> int64
// float64 -> uint64
template <typename TOut, typename TIn>
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value &&
sizeof(TOut) >= sizeof(TIn),
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value,
bool>::type
canConvertNumber(TIn value) {
// Avoid error "9.22337e+18 is outside the range of representable values of
// type 'long'"
return value >= numeric_limits<TOut>::lowest() &&
value <= FloatTraits<TIn>::highest_for(TOut());
value <= numeric_limits<TOut>::highest() &&
value <= FloatTraits<TIn>::template highest_for<TOut>();
}
template <typename TOut, typename TIn>