Coverage Report

Created: 2023-01-13 06:07

/src/arduinojson/src/ArduinoJson/Numbers/convertNumber.hpp
Line
Count
Source (jump to first uncovered line)
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2022, Benoit BLANCHON
3
// MIT License
4
5
#pragma once
6
7
#if defined(__clang__)
8
#  pragma clang diagnostic push
9
#  pragma clang diagnostic ignored "-Wconversion"
10
#elif defined(__GNUC__)
11
#  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
12
#    pragma GCC diagnostic push
13
#  endif
14
#  pragma GCC diagnostic ignored "-Wconversion"
15
#endif
16
17
#include <ArduinoJson/Numbers/FloatTraits.hpp>
18
#include <ArduinoJson/Numbers/JsonFloat.hpp>
19
#include <ArduinoJson/Polyfills/limits.hpp>
20
#include <ArduinoJson/Polyfills/type_traits.hpp>
21
22
namespace ARDUINOJSON_NAMESPACE {
23
24
// uint32 -> int32
25
// uint64 -> int32
26
template <typename TOut, typename TIn>
27
typename enable_if<is_integral<TIn>::value && is_unsigned<TIn>::value &&
28
                       is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
29
                   bool>::type
30
canConvertNumber(TIn value) {
31
  return value <= TIn(numeric_limits<TOut>::highest());
32
}
33
34
// uint32 -> int64
35
template <typename TOut, typename TIn>
36
typename enable_if<is_integral<TIn>::value && is_unsigned<TIn>::value &&
37
                       is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
38
                   bool>::type
39
canConvertNumber(TIn) {
40
  return true;
41
}
42
43
// uint32 -> float
44
// int32 -> float
45
template <typename TOut, typename TIn>
46
typename enable_if<is_integral<TIn>::value && is_floating_point<TOut>::value,
47
                   bool>::type
48
canConvertNumber(TIn) {
49
  return true;
50
}
51
52
// int64 -> int32
53
template <typename TOut, typename TIn>
54
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
55
                       is_integral<TOut>::value && is_signed<TOut>::value &&
56
                       sizeof(TOut) < sizeof(TIn),
57
                   bool>::type
58
canConvertNumber(TIn value) {
59
  return value >= TIn(numeric_limits<TOut>::lowest()) &&
60
         value <= TIn(numeric_limits<TOut>::highest());
61
}
62
63
// int32 -> int32
64
// int32 -> int64
65
template <typename TOut, typename TIn>
66
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
67
                       is_integral<TOut>::value && is_signed<TOut>::value &&
68
                       sizeof(TIn) <= sizeof(TOut),
69
                   bool>::type
70
canConvertNumber(TIn) {
71
  return true;
72
}
73
74
// int32 -> uint32
75
// int32 -> uint64
76
template <typename TOut, typename TIn>
77
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
78
                       is_integral<TOut>::value && is_unsigned<TOut>::value &&
79
                       sizeof(TOut) >= sizeof(TIn),
80
                   bool>::type
81
canConvertNumber(TIn value) {
82
  if (value < 0)
83
    return false;
84
  return TOut(value) <= numeric_limits<TOut>::highest();
85
}
86
87
// int32 -> uint16
88
template <typename TOut, typename TIn>
89
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
90
                       is_integral<TOut>::value && is_unsigned<TOut>::value &&
91
                       sizeof(TOut) < sizeof(TIn),
92
                   bool>::type
93
canConvertNumber(TIn value) {
94
  if (value < 0)
95
    return false;
96
  return value <= TIn(numeric_limits<TOut>::highest());
97
}
98
99
// float32 -> int16
100
// float64 -> int32
101
template <typename TOut, typename TIn>
102
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value &&
103
                       sizeof(TOut) < sizeof(TIn),
104
                   bool>::type
105
canConvertNumber(TIn value) {
106
  return value >= numeric_limits<TOut>::lowest() &&
107
         value <= numeric_limits<TOut>::highest();
108
}
109
110
// float32 -> int32
111
// float32 -> uint32
112
// float32 -> int64
113
// float32 -> uint64
114
// float64 -> int64
115
// float64 -> uint64
116
template <typename TOut, typename TIn>
117
typename enable_if<is_floating_point<TIn>::value && is_integral<TOut>::value &&
118
                       sizeof(TOut) >= sizeof(TIn),
119
                   bool>::type
120
0
canConvertNumber(TIn value) {
121
0
  // Avoid error "9.22337e+18 is outside the range of representable values of
122
0
  // type 'long'"
123
0
  return value >= numeric_limits<TOut>::lowest() &&
124
0
         value <= FloatTraits<TIn>::template highest_for<TOut>();
125
0
}
126
127
template <typename TOut, typename TIn>
128
TOut convertNumber(TIn value) {
129
  return canConvertNumber<TOut>(value) ? TOut(value) : 0;
130
}
131
}  // namespace ARDUINOJSON_NAMESPACE
132
133
#if defined(__clang__)
134
#  pragma clang diagnostic pop
135
#elif defined(__GNUC__)
136
#  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
137
#    pragma GCC diagnostic pop
138
#  endif
139
#endif