• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bblanchon / ArduinoJson / 4206071096

pending completion
4206071096

push

github

Benoit Blanchon
Use `delete` instead of hiding copy constructors and assignments (#1820)

3348 of 3363 relevant lines covered (99.55%)

6103.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.48
/src/ArduinoJson/Numbers/FloatTraits.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2023, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <stddef.h>  // for size_t
8
#include <stdint.h>
9

10
#include <ArduinoJson/Configuration.hpp>
11
#include <ArduinoJson/Polyfills/alias_cast.hpp>
12
#include <ArduinoJson/Polyfills/math.hpp>
13
#include <ArduinoJson/Polyfills/pgmspace_generic.hpp>
14
#include <ArduinoJson/Polyfills/preprocessor.hpp>
15
#include <ArduinoJson/Polyfills/type_traits.hpp>
16

17
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
18

19
template <typename T, size_t = sizeof(T)>
20
struct FloatTraits {};
21

22
template <typename T>
23
struct FloatTraits<T, 8 /*64bits*/> {
24
  typedef uint64_t mantissa_type;
25
  static const short mantissa_bits = 52;
26
  static const mantissa_type mantissa_max =
27
      (mantissa_type(1) << mantissa_bits) - 1;
28

29
  typedef int16_t exponent_type;
30
  static const exponent_type exponent_max = 308;
31

32
  template <typename TExponent>
33
  static T make_float(T m, TExponent e) {
104✔
34
    if (e > 0) {
104✔
35
      for (uint8_t index = 0; e != 0; index++) {
125✔
36
        if (e & 1)
107✔
37
          m *= positiveBinaryPowerOfTen(index);
48✔
38
        e >>= 1;
107✔
39
      }
40
    } else {
41
      e = TExponent(-e);
86✔
42
      for (uint8_t index = 0; e != 0; index++) {
319✔
43
        if (e & 1)
233✔
44
          m *= negativeBinaryPowerOfTen(index);
114✔
45
        e >>= 1;
233✔
46
      }
47
    }
48
    return m;
104✔
49
  }
50

51
  static T positiveBinaryPowerOfTen(int index) {
136✔
52
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(  //
1✔
53
        uint32_t, factors,
54
        ARDUINOJSON_EXPAND18({
55
            0x40240000, 0x00000000,  // 1e1
56
            0x40590000, 0x00000000,  // 1e2
57
            0x40C38800, 0x00000000,  // 1e4
58
            0x4197D784, 0x00000000,  // 1e8
59
            0x4341C379, 0x37E08000,  // 1e16
60
            0x4693B8B5, 0xB5056E17,  // 1e32
61
            0x4D384F03, 0xE93FF9F5,  // 1e64
62
            0x5A827748, 0xF9301D32,  // 1e128
63
            0x75154FDD, 0x7F73BF3C   // 1e256
64
        }));
65
    return forge(pgm_read(factors + 2 * index),
136✔
66
                 pgm_read(factors + 2 * index + 1));
272✔
67
  }
68

69
  static T negativeBinaryPowerOfTen(int index) {
142✔
70
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(  //
1✔
71
        uint32_t, factors,
72
        ARDUINOJSON_EXPAND18({
73
            0x3FB99999, 0x9999999A,  // 1e-1
74
            0x3F847AE1, 0x47AE147B,  // 1e-2
75
            0x3F1A36E2, 0xEB1C432D,  // 1e-4
76
            0x3E45798E, 0xE2308C3A,  // 1e-8
77
            0x3C9CD2B2, 0x97D889BC,  // 1e-16
78
            0x3949F623, 0xD5A8A733,  // 1e-32
79
            0x32A50FFD, 0x44F4A73D,  // 1e-64
80
            0x255BBA08, 0xCF8C979D,  // 1e-128
81
            0x0AC80628, 0x64AC6F43   // 1e-256
82
        }));
83
    return forge(pgm_read(factors + 2 * index),
142✔
84
                 pgm_read(factors + 2 * index + 1));
284✔
85
  }
86

87
  static T negativeBinaryPowerOfTenPlusOne(int index) {
63✔
88
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(  //
×
89
        uint32_t, factors,
90
        ARDUINOJSON_EXPAND18({
91
            0x3FF00000, 0x00000000,  // 1e0
92
            0x3FB99999, 0x9999999A,  // 1e-1
93
            0x3F50624D, 0xD2F1A9FC,  // 1e-3
94
            0x3E7AD7F2, 0x9ABCAF48,  // 1e-7
95
            0x3CD203AF, 0x9EE75616,  // 1e-15
96
            0x398039D6, 0x65896880,  // 1e-31
97
            0x32DA53FC, 0x9631D10D,  // 1e-63
98
            0x25915445, 0x81B7DEC2,  // 1e-127
99
            0x0AFE07B2, 0x7DD78B14   // 1e-255
100
        }));
101
    return forge(pgm_read(factors + 2 * index),
63✔
102
                 pgm_read(factors + 2 * index + 1));
126✔
103
  }
104

105
  static T nan() {
4✔
106
    return forge(0x7ff80000, 0x00000000);
4✔
107
  }
108

109
  static T inf() {
9✔
110
    return forge(0x7ff00000, 0x00000000);
9✔
111
  }
112

113
  static T highest() {
114
    return forge(0x7FEFFFFF, 0xFFFFFFFF);
115
  }
116

117
  template <typename TOut>  // int64_t
118
  static T highest_for(
7✔
119
      typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
120
                             sizeof(TOut) == 8,
121
                         signed>::type* = 0) {
122
    return forge(0x43DFFFFF, 0xFFFFFFFF);  //  9.2233720368547748e+18
7✔
123
  }
124

125
  template <typename TOut>  // uint64_t
126
  static T highest_for(
3✔
127
      typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
128
                             sizeof(TOut) == 8,
129
                         unsigned>::type* = 0) {
130
    return forge(0x43EFFFFF, 0xFFFFFFFF);  //  1.8446744073709549568e+19
3✔
131
  }
132

133
  static T lowest() {
134
    return forge(0xFFEFFFFF, 0xFFFFFFFF);
135
  }
136

137
  // constructs a double floating point values from its binary representation
138
  // we use this function to workaround platforms with single precision literals
139
  // (for example, when -fsingle-precision-constant is passed to GCC)
140
  static T forge(uint32_t msb, uint32_t lsb) {
364✔
141
    return alias_cast<T>((uint64_t(msb) << 32) | lsb);
364✔
142
  }
143
};
144

145
template <typename T>
146
struct FloatTraits<T, 4 /*32bits*/> {
147
  typedef uint32_t mantissa_type;
148
  static const short mantissa_bits = 23;
149
  static const mantissa_type mantissa_max =
150
      (mantissa_type(1) << mantissa_bits) - 1;
151

152
  typedef int8_t exponent_type;
153
  static const exponent_type exponent_max = 38;
154

155
  template <typename TExponent>
156
  static T make_float(T m, TExponent e) {
23✔
157
    if (e > 0) {
23✔
158
      for (uint8_t index = 0; e != 0; index++) {
89✔
159
        if (e & 1)
74✔
160
          m *= positiveBinaryPowerOfTen(index);
27✔
161
        e >>= 1;
74✔
162
      }
163
    } else {
164
      e = -e;
8✔
165
      for (uint8_t index = 0; e != 0; index++) {
38✔
166
        if (e & 1)
30✔
167
          m *= negativeBinaryPowerOfTen(index);
16✔
168
        e >>= 1;
30✔
169
      }
170
    }
171
    return m;
23✔
172
  }
173

174
  static T positiveBinaryPowerOfTen(int index) {
36✔
175
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
176
                                     ARDUINOJSON_EXPAND6({
177
                                         0x41200000,  // 1e1f
178
                                         0x42c80000,  // 1e2f
179
                                         0x461c4000,  // 1e4f
180
                                         0x4cbebc20,  // 1e8f
181
                                         0x5a0e1bca,  // 1e16f
182
                                         0x749dc5ae   // 1e32f
183
                                     }));
184
    return forge(pgm_read(factors + index));
36✔
185
  }
186

187
  static T negativeBinaryPowerOfTen(int index) {
19✔
188
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
189
                                     ARDUINOJSON_EXPAND6({
190
                                         0x3dcccccd,  // 1e-1f
191
                                         0x3c23d70a,  // 1e-2f
192
                                         0x38d1b717,  // 1e-4f
193
                                         0x322bcc77,  // 1e-8f
194
                                         0x24e69595,  // 1e-16f
195
                                         0x0a4fb11f   // 1e-32f
196
                                     }));
197
    return forge(pgm_read(factors + index));
19✔
198
  }
199

200
  static T negativeBinaryPowerOfTenPlusOne(int index) {
6✔
201
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
202
                                     ARDUINOJSON_EXPAND6({
203
                                         0x3f800000,  // 1e0f
204
                                         0x3dcccccd,  // 1e-1f
205
                                         0x3a83126f,  // 1e-3f
206
                                         0x33d6bf95,  // 1e-7f
207
                                         0x26901d7d,  // 1e-15f
208
                                         0x0c01ceb3   // 1e-31f
209
                                     }));
210
    return forge(pgm_read(factors + index));
6✔
211
  }
212

213
  static T forge(uint32_t bits) {
101✔
214
    return alias_cast<T>(bits);
101✔
215
  }
216

217
  static T nan() {
2✔
218
    return forge(0x7fc00000);
2✔
219
  }
220

221
  static T inf() {
11✔
222
    return forge(0x7f800000);
11✔
223
  }
224

225
  static T highest() {
226
    return forge(0x7f7fffff);
227
  }
228

229
  template <typename TOut>  // int32_t
230
  static T highest_for(
4✔
231
      typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
232
                             sizeof(TOut) == 4,
233
                         signed>::type* = 0) {
234
    return forge(0x4EFFFFFF);  // 2.14748352E9
4✔
235
  }
236

237
  template <typename TOut>  // uint32_t
238
  static T highest_for(
3✔
239
      typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
240
                             sizeof(TOut) == 4,
241
                         unsigned>::type* = 0) {
242
    return forge(0x4F7FFFFF);  // 4.29496704E9
3✔
243
  }
244

245
  template <typename TOut>  // int64_t
246
  static T highest_for(
17✔
247
      typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
248
                             sizeof(TOut) == 8,
249
                         signed>::type* = 0) {
250
    return forge(0x5EFFFFFF);  // 9.22337148709896192E18
17✔
251
  }
252

253
  template <typename TOut>  // uint64_t
254
  static T highest_for(
3✔
255
      typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value &&
256
                             sizeof(TOut) == 8,
257
                         unsigned>::type* = 0) {
258
    return forge(0x5F7FFFFF);  // 1.844674297419792384E19
3✔
259
  }
260

261
  static T lowest() {
262
    return forge(0xFf7fffff);
263
  }
264
};
265

266
ARDUINOJSON_END_PRIVATE_NAMESPACE
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc