Line data Source code
1 : #ifndef FASTFLOAT_FLOAT_COMMON_H
2 : #define FASTFLOAT_FLOAT_COMMON_H
3 :
4 : #include <cfloat>
5 : #include <cstdint>
6 : #include <cassert>
7 : #include <cstring>
8 : #include <type_traits>
9 : #include <system_error>
10 :
11 : #include "constexpr_feature_detect.h"
12 :
13 : namespace fast_float {
14 :
15 : #define FASTFLOAT_JSONFMT (1 << 5)
16 : #define FASTFLOAT_FORTRANFMT (1 << 6)
17 :
18 : enum chars_format {
19 : scientific = 1 << 0,
20 : fixed = 1 << 2,
21 : hex = 1 << 3,
22 : no_infnan = 1 << 4,
23 : // RFC 8259: https://datatracker.ietf.org/doc/html/rfc8259#section-6
24 : json = FASTFLOAT_JSONFMT | fixed | scientific | no_infnan,
25 : // Extension of RFC 8259 where, e.g., "inf" and "nan" are allowed.
26 : json_or_infnan = FASTFLOAT_JSONFMT | fixed | scientific,
27 : fortran = FASTFLOAT_FORTRANFMT | fixed | scientific,
28 : general = fixed | scientific
29 : };
30 :
31 : template <typename UC>
32 : struct from_chars_result_t {
33 : UC const* ptr;
34 : std::errc ec;
35 : };
36 : using from_chars_result = from_chars_result_t<char>;
37 :
38 : template <typename UC>
39 : struct parse_options_t {
40 7463760 : constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
41 : UC dot = UC('.'))
42 7463760 : : format(fmt), decimal_point(dot) {}
43 :
44 : /** Which number formats are accepted */
45 : chars_format format;
46 : /** The character used as decimal point */
47 : UC decimal_point;
48 : };
49 : using parse_options = parse_options_t<char>;
50 :
51 : }
52 :
53 : #if FASTFLOAT_HAS_BIT_CAST
54 : #include <bit>
55 : #endif
56 :
57 : #if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
58 : || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
59 : || defined(__MINGW64__) \
60 : || defined(__s390x__) \
61 : || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) \
62 : || defined(__loongarch64) )
63 : #define FASTFLOAT_64BIT 1
64 : #elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) \
65 : || defined(__arm__) || defined(_M_ARM) || defined(__ppc__) \
66 : || defined(__MINGW32__) || defined(__EMSCRIPTEN__))
67 : #define FASTFLOAT_32BIT 1
68 : #else
69 : // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow.
70 : // We can never tell the register width, but the SIZE_MAX is a good approximation.
71 : // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability.
72 : #if SIZE_MAX == 0xffff
73 : #error Unknown platform (16-bit, unsupported)
74 : #elif SIZE_MAX == 0xffffffff
75 : #define FASTFLOAT_32BIT 1
76 : #elif SIZE_MAX == 0xffffffffffffffff
77 : #define FASTFLOAT_64BIT 1
78 : #else
79 : #error Unknown platform (not 32-bit, not 64-bit?)
80 : #endif
81 : #endif
82 :
83 : #if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__))
84 : #include <intrin.h>
85 : #endif
86 :
87 : #if defined(_MSC_VER) && !defined(__clang__)
88 : #define FASTFLOAT_VISUAL_STUDIO 1
89 : #endif
90 :
91 : #if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
92 : #define FASTFLOAT_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
93 : #elif defined _WIN32
94 : #define FASTFLOAT_IS_BIG_ENDIAN 0
95 : #else
96 : #if defined(__APPLE__) || defined(__FreeBSD__)
97 : #include <machine/endian.h>
98 : #elif defined(sun) || defined(__sun)
99 : #include <sys/byteorder.h>
100 : #elif defined(__MVS__)
101 : #include <sys/endian.h>
102 : #else
103 : #ifdef __has_include
104 : #if __has_include(<endian.h>)
105 : #include <endian.h>
106 : #endif //__has_include(<endian.h>)
107 : #endif //__has_include
108 : #endif
109 : #
110 : #ifndef __BYTE_ORDER__
111 : // safe choice
112 : #define FASTFLOAT_IS_BIG_ENDIAN 0
113 : #endif
114 : #
115 : #ifndef __ORDER_LITTLE_ENDIAN__
116 : // safe choice
117 : #define FASTFLOAT_IS_BIG_ENDIAN 0
118 : #endif
119 : #
120 : #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
121 : #define FASTFLOAT_IS_BIG_ENDIAN 0
122 : #else
123 : #define FASTFLOAT_IS_BIG_ENDIAN 1
124 : #endif
125 : #endif
126 :
127 : #if defined(__SSE2__) || \
128 : (defined(FASTFLOAT_VISUAL_STUDIO) && \
129 : (defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP == 2)))
130 : #define FASTFLOAT_SSE2 1
131 : #endif
132 :
133 : #if defined(__aarch64__) || defined(_M_ARM64)
134 : #define FASTFLOAT_NEON 1
135 : #endif
136 :
137 : #if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_ARM64)
138 : #define FASTFLOAT_HAS_SIMD 1
139 : #endif
140 :
141 : #if defined(__GNUC__)
142 : // disable -Wcast-align=strict (GCC only)
143 : #define FASTFLOAT_SIMD_DISABLE_WARNINGS \
144 : _Pragma("GCC diagnostic push") \
145 : _Pragma("GCC diagnostic ignored \"-Wcast-align\"")
146 : #else
147 : #define FASTFLOAT_SIMD_DISABLE_WARNINGS
148 : #endif
149 :
150 : #if defined(__GNUC__)
151 : #define FASTFLOAT_SIMD_RESTORE_WARNINGS \
152 : _Pragma("GCC diagnostic pop")
153 : #else
154 : #define FASTFLOAT_SIMD_RESTORE_WARNINGS
155 : #endif
156 :
157 :
158 :
159 : #ifdef FASTFLOAT_VISUAL_STUDIO
160 : #define fastfloat_really_inline __forceinline
161 : #else
162 : #define fastfloat_really_inline inline __attribute__((always_inline))
163 : #endif
164 :
165 : #ifndef FASTFLOAT_ASSERT
166 : #define FASTFLOAT_ASSERT(x) { ((void)(x)); }
167 : #endif
168 :
169 : #ifndef FASTFLOAT_DEBUG_ASSERT
170 : #define FASTFLOAT_DEBUG_ASSERT(x) { ((void)(x)); }
171 : #endif
172 :
173 : // rust style `try!()` macro, or `?` operator
174 : #define FASTFLOAT_TRY(x) { if (!(x)) return false; }
175 :
176 : #define FASTFLOAT_ENABLE_IF(...) typename std::enable_if<(__VA_ARGS__), int>::type = 0
177 :
178 :
179 : namespace fast_float {
180 :
181 : fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() {
182 : #if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED
183 : return std::is_constant_evaluated();
184 : #else
185 9187190 : return false;
186 : #endif
187 : }
188 :
189 : // Compares two ASCII strings in a case insensitive manner.
190 : template <typename UC>
191 : inline FASTFLOAT_CONSTEXPR14 bool
192 10 : fastfloat_strncasecmp(UC const * input1, UC const * input2, size_t length) {
193 10 : char running_diff{0};
194 40 : for (size_t i = 0; i < length; ++i) {
195 30 : running_diff |= (char(input1[i]) ^ char(input2[i]));
196 : }
197 10 : return (running_diff == 0) || (running_diff == 32);
198 : }
199 :
200 : #ifndef FLT_EVAL_METHOD
201 : #error "FLT_EVAL_METHOD should be defined, please include cfloat."
202 : #endif
203 :
204 : // a pointer and a length to a contiguous block of memory
205 : template <typename T>
206 : struct span {
207 : const T* ptr;
208 : size_t length;
209 13738100 : constexpr span(const T* _ptr, size_t _length) : ptr(_ptr), length(_length) {}
210 : constexpr span() : ptr(nullptr), length(0) {}
211 :
212 125032 : constexpr size_t len() const noexcept {
213 125032 : return length;
214 : }
215 :
216 0 : FASTFLOAT_CONSTEXPR14 const T& operator[](size_t index) const noexcept {
217 : FASTFLOAT_DEBUG_ASSERT(index < length);
218 0 : return ptr[index];
219 : }
220 : };
221 :
222 : struct value128 {
223 : uint64_t low;
224 : uint64_t high;
225 : constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {}
226 : constexpr value128() : low(0), high(0) {}
227 : };
228 :
229 : /* Helper C++14 constexpr generic implementation of leading_zeroes */
230 : fastfloat_really_inline FASTFLOAT_CONSTEXPR14
231 : int leading_zeroes_generic(uint64_t input_num, int last_bit = 0) {
232 0 : if(input_num & uint64_t(0xffffffff00000000)) { input_num >>= 32; last_bit |= 32; }
233 0 : if(input_num & uint64_t( 0xffff0000)) { input_num >>= 16; last_bit |= 16; }
234 0 : if(input_num & uint64_t( 0xff00)) { input_num >>= 8; last_bit |= 8; }
235 0 : if(input_num & uint64_t( 0xf0)) { input_num >>= 4; last_bit |= 4; }
236 0 : if(input_num & uint64_t( 0xc)) { input_num >>= 2; last_bit |= 2; }
237 0 : if(input_num & uint64_t( 0x2)) { input_num >>= 1; last_bit |= 1; }
238 0 : return 63 - last_bit;
239 : }
240 :
241 : /* result might be undefined when input_num is zero */
242 : fastfloat_really_inline FASTFLOAT_CONSTEXPR20
243 : int leading_zeroes(uint64_t input_num) {
244 329159 : assert(input_num > 0);
245 329159 : if (cpp20_and_in_constexpr()) {
246 0 : return leading_zeroes_generic(input_num);
247 : }
248 : #ifdef FASTFLOAT_VISUAL_STUDIO
249 : #if defined(_M_X64) || defined(_M_ARM64)
250 : unsigned long leading_zero = 0;
251 : // Search the mask data from most significant bit (MSB)
252 : // to least significant bit (LSB) for a set bit (1).
253 : _BitScanReverse64(&leading_zero, input_num);
254 : return (int)(63 - leading_zero);
255 : #else
256 : return leading_zeroes_generic(input_num);
257 : #endif
258 : #else
259 329159 : return __builtin_clzll(input_num);
260 : #endif
261 : }
262 :
263 : // slow emulation routine for 32-bit
264 : fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) {
265 0 : return x * (uint64_t)y;
266 : }
267 :
268 : fastfloat_really_inline FASTFLOAT_CONSTEXPR14
269 : uint64_t umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) {
270 0 : uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd);
271 0 : uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd);
272 0 : uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32));
273 0 : uint64_t adbc_carry = !!(adbc < ad);
274 0 : uint64_t lo = bd + (adbc << 32);
275 0 : *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) +
276 0 : (adbc_carry << 32) + !!(lo < bd);
277 0 : return lo;
278 : }
279 :
280 : #ifdef FASTFLOAT_32BIT
281 :
282 : // slow emulation routine for 32-bit
283 : #if !defined(__MINGW64__)
284 : fastfloat_really_inline FASTFLOAT_CONSTEXPR14
285 : uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
286 : return umul128_generic(ab, cd, hi);
287 : }
288 : #endif // !__MINGW64__
289 :
290 : #endif // FASTFLOAT_32BIT
291 :
292 :
293 : // compute 64-bit a*b
294 : fastfloat_really_inline FASTFLOAT_CONSTEXPR20
295 : value128 full_multiplication(uint64_t a, uint64_t b) {
296 370803 : if (cpp20_and_in_constexpr()) {
297 0 : value128 answer;
298 0 : answer.low = umul128_generic(a, b, &answer.high);
299 0 : return answer;
300 : }
301 370803 : value128 answer;
302 : #if defined(_M_ARM64) && !defined(__MINGW32__)
303 : // ARM64 has native support for 64-bit multiplications, no need to emulate
304 : // But MinGW on ARM64 doesn't have native support for 64-bit multiplications
305 : answer.high = __umulh(a, b);
306 : answer.low = a * b;
307 : #elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__))
308 : answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
309 : #elif defined(FASTFLOAT_64BIT)
310 370803 : __uint128_t r = ((__uint128_t)a) * b;
311 370803 : answer.low = uint64_t(r);
312 370803 : answer.high = uint64_t(r >> 64);
313 : #else
314 : answer.low = umul128_generic(a, b, &answer.high);
315 : #endif
316 370803 : return answer;
317 : }
318 :
319 : struct adjusted_mantissa {
320 : uint64_t mantissa{0};
321 : int32_t power2{0}; // a negative value indicates an invalid result
322 : adjusted_mantissa() = default;
323 : constexpr bool operator==(const adjusted_mantissa &o) const {
324 : return mantissa == o.mantissa && power2 == o.power2;
325 : }
326 62516 : constexpr bool operator!=(const adjusted_mantissa &o) const {
327 62516 : return mantissa != o.mantissa || power2 != o.power2;
328 : }
329 : };
330 :
331 : // Bias so we can get the real exponent with an invalid adjusted_mantissa.
332 : constexpr static int32_t invalid_am_bias = -0x8000;
333 :
334 : // used for binary_format_lookup_tables<T>::max_mantissa
335 : constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
336 :
337 : template <typename T, typename U = void>
338 : struct binary_format_lookup_tables;
339 :
340 : template <typename T> struct binary_format : binary_format_lookup_tables<T> {
341 : using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
342 :
343 : static inline constexpr int mantissa_explicit_bits();
344 : static inline constexpr int minimum_exponent();
345 : static inline constexpr int infinite_power();
346 : static inline constexpr int sign_index();
347 : static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
348 : static inline constexpr int max_exponent_fast_path();
349 : static inline constexpr int max_exponent_round_to_even();
350 : static inline constexpr int min_exponent_round_to_even();
351 : static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
352 : static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
353 : static inline constexpr int largest_power_of_ten();
354 : static inline constexpr int smallest_power_of_ten();
355 : static inline constexpr T exact_power_of_ten(int64_t power);
356 : static inline constexpr size_t max_digits();
357 : static inline constexpr equiv_uint exponent_mask();
358 : static inline constexpr equiv_uint mantissa_mask();
359 : static inline constexpr equiv_uint hidden_bit_mask();
360 : };
361 :
362 : template <typename U>
363 : struct binary_format_lookup_tables<double, U> {
364 : static constexpr double powers_of_ten[] = {
365 : 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
366 : 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
367 :
368 : // Largest integer value v so that (5**index * v) <= 1<<53.
369 : // 0x10000000000000 == 1 << 53
370 : static constexpr uint64_t max_mantissa[] = {
371 : 0x10000000000000,
372 : 0x10000000000000 / 5,
373 : 0x10000000000000 / (5 * 5),
374 : 0x10000000000000 / (5 * 5 * 5),
375 : 0x10000000000000 / (5 * 5 * 5 * 5),
376 : 0x10000000000000 / (constant_55555),
377 : 0x10000000000000 / (constant_55555 * 5),
378 : 0x10000000000000 / (constant_55555 * 5 * 5),
379 : 0x10000000000000 / (constant_55555 * 5 * 5 * 5),
380 : 0x10000000000000 / (constant_55555 * 5 * 5 * 5 * 5),
381 : 0x10000000000000 / (constant_55555 * constant_55555),
382 : 0x10000000000000 / (constant_55555 * constant_55555 * 5),
383 : 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5),
384 : 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5),
385 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555),
386 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5),
387 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5),
388 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5),
389 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5),
390 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555),
391 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5),
392 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5),
393 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5),
394 : 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)};
395 : };
396 :
397 : template <typename U>
398 : constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
399 :
400 : template <typename U>
401 : constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
402 :
403 : template <typename U>
404 : struct binary_format_lookup_tables<float, U> {
405 : static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
406 : 1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
407 :
408 : // Largest integer value v so that (5**index * v) <= 1<<24.
409 : // 0x1000000 == 1<<24
410 : static constexpr uint64_t max_mantissa[] = {
411 : 0x1000000,
412 : 0x1000000 / 5,
413 : 0x1000000 / (5 * 5),
414 : 0x1000000 / (5 * 5 * 5),
415 : 0x1000000 / (5 * 5 * 5 * 5),
416 : 0x1000000 / (constant_55555),
417 : 0x1000000 / (constant_55555 * 5),
418 : 0x1000000 / (constant_55555 * 5 * 5),
419 : 0x1000000 / (constant_55555 * 5 * 5 * 5),
420 : 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5),
421 : 0x1000000 / (constant_55555 * constant_55555),
422 : 0x1000000 / (constant_55555 * constant_55555 * 5)};
423 : };
424 :
425 : template <typename U>
426 : constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
427 :
428 : template <typename U>
429 : constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
430 :
431 7422650 : template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
432 : #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
433 : return 0;
434 : #else
435 7422650 : return -22;
436 : #endif
437 : }
438 :
439 : template <> inline constexpr int binary_format<float>::min_exponent_fast_path() {
440 : #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
441 : return 0;
442 : #else
443 : return -10;
444 : #endif
445 : }
446 :
447 8613050 : template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
448 8613050 : return 52;
449 : }
450 : template <> inline constexpr int binary_format<float>::mantissa_explicit_bits() {
451 : return 23;
452 : }
453 :
454 88 : template <> inline constexpr int binary_format<double>::max_exponent_round_to_even() {
455 88 : return 23;
456 : }
457 :
458 : template <> inline constexpr int binary_format<float>::max_exponent_round_to_even() {
459 : return 10;
460 : }
461 :
462 15118 : template <> inline constexpr int binary_format<double>::min_exponent_round_to_even() {
463 15118 : return -4;
464 : }
465 :
466 : template <> inline constexpr int binary_format<float>::min_exponent_round_to_even() {
467 : return -17;
468 : }
469 :
470 329159 : template <> inline constexpr int binary_format<double>::minimum_exponent() {
471 329159 : return -1023;
472 : }
473 : template <> inline constexpr int binary_format<float>::minimum_exponent() {
474 : return -127;
475 : }
476 :
477 595797 : template <> inline constexpr int binary_format<double>::infinite_power() {
478 595797 : return 0x7FF;
479 : }
480 : template <> inline constexpr int binary_format<float>::infinite_power() {
481 : return 0xFF;
482 : }
483 :
484 266645 : template <> inline constexpr int binary_format<double>::sign_index() { return 63; }
485 : template <> inline constexpr int binary_format<float>::sign_index() { return 31; }
486 :
487 7421600 : template <> inline constexpr int binary_format<double>::max_exponent_fast_path() {
488 7421600 : return 22;
489 : }
490 : template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
491 : return 10;
492 : }
493 :
494 7358940 : template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
495 7358940 : return uint64_t(2) << mantissa_explicit_bits();
496 : }
497 0 : template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
498 : // caller is responsible to ensure that
499 : // power >= 0 && power <= 22
500 : //
501 : // Work around clang bug https://godbolt.org/z/zedh7rrhc
502 0 : return (void)max_mantissa[0], max_mantissa[power];
503 : }
504 : template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
505 : return uint64_t(2) << mantissa_explicit_bits();
506 : }
507 : template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
508 : // caller is responsible to ensure that
509 : // power >= 0 && power <= 10
510 : //
511 : // Work around clang bug https://godbolt.org/z/zedh7rrhc
512 : return (void)max_mantissa[0], max_mantissa[power];
513 : }
514 :
515 : template <>
516 7156000 : inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
517 : // Work around clang bug https://godbolt.org/z/zedh7rrhc
518 7156000 : return (void)powers_of_ten[0], powers_of_ten[power];
519 : }
520 : template <>
521 : inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
522 : // Work around clang bug https://godbolt.org/z/zedh7rrhc
523 : return (void)powers_of_ten[0], powers_of_ten[power];
524 : }
525 :
526 :
527 : template <>
528 329161 : inline constexpr int binary_format<double>::largest_power_of_ten() {
529 329161 : return 308;
530 : }
531 : template <>
532 : inline constexpr int binary_format<float>::largest_power_of_ten() {
533 : return 38;
534 : }
535 :
536 : template <>
537 329161 : inline constexpr int binary_format<double>::smallest_power_of_ten() {
538 329161 : return -342;
539 : }
540 : template <>
541 : inline constexpr int binary_format<float>::smallest_power_of_ten() {
542 : return -65;
543 : }
544 :
545 : template <> inline constexpr size_t binary_format<double>::max_digits() {
546 : return 769;
547 : }
548 : template <> inline constexpr size_t binary_format<float>::max_digits() {
549 : return 114;
550 : }
551 :
552 : template <> inline constexpr binary_format<float>::equiv_uint
553 : binary_format<float>::exponent_mask() {
554 : return 0x7F800000;
555 : }
556 : template <> inline constexpr binary_format<double>::equiv_uint
557 : binary_format<double>::exponent_mask() {
558 : return 0x7FF0000000000000;
559 : }
560 :
561 : template <> inline constexpr binary_format<float>::equiv_uint
562 : binary_format<float>::mantissa_mask() {
563 : return 0x007FFFFF;
564 : }
565 : template <> inline constexpr binary_format<double>::equiv_uint
566 : binary_format<double>::mantissa_mask() {
567 : return 0x000FFFFFFFFFFFFF;
568 : }
569 :
570 : template <> inline constexpr binary_format<float>::equiv_uint
571 : binary_format<float>::hidden_bit_mask() {
572 : return 0x00800000;
573 : }
574 : template <> inline constexpr binary_format<double>::equiv_uint
575 : binary_format<double>::hidden_bit_mask() {
576 : return 0x0010000000000000;
577 : }
578 :
579 : template<typename T>
580 : fastfloat_really_inline FASTFLOAT_CONSTEXPR20
581 : void to_float(bool negative, adjusted_mantissa am, T &value) {
582 : using fastfloat_uint = typename binary_format<T>::equiv_uint;
583 266645 : fastfloat_uint word = (fastfloat_uint)am.mantissa;
584 266645 : word |= fastfloat_uint(am.power2) << binary_format<T>::mantissa_explicit_bits();
585 266645 : word |= fastfloat_uint(negative) << binary_format<T>::sign_index();
586 : #if FASTFLOAT_HAS_BIT_CAST
587 : value = std::bit_cast<T>(word);
588 : #else
589 266645 : ::memcpy(&value, &word, sizeof(T));
590 : #endif
591 266645 : }
592 :
593 : #ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
594 : template <typename = void>
595 : struct space_lut {
596 : static constexpr bool value[] = {
597 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
598 : 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
599 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
600 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
601 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
602 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
603 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
606 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
607 : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
608 : };
609 :
610 : template <typename T>
611 : constexpr bool space_lut<T>::value[];
612 :
613 : inline constexpr bool is_space(uint8_t c) { return space_lut<>::value[c]; }
614 : #endif
615 :
616 : template<typename UC>
617 0 : static constexpr uint64_t int_cmp_zeros()
618 : {
619 : static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), "Unsupported character size");
620 0 : return (sizeof(UC) == 1) ? 0x3030303030303030 : (sizeof(UC) == 2) ? (uint64_t(UC('0')) << 48 | uint64_t(UC('0')) << 32 | uint64_t(UC('0')) << 16 | UC('0')) : (uint64_t(UC('0')) << 32 | UC('0'));
621 : }
622 : template<typename UC>
623 0 : static constexpr int int_cmp_len()
624 : {
625 0 : return sizeof(uint64_t) / sizeof(UC);
626 : }
627 : template<typename UC>
628 : static constexpr UC const * str_const_nan()
629 : {
630 : return nullptr;
631 : }
632 : template<>
633 5 : constexpr char const * str_const_nan<char>()
634 : {
635 5 : return "nan";
636 : }
637 : template<>
638 : constexpr wchar_t const * str_const_nan<wchar_t>()
639 : {
640 : return L"nan";
641 : }
642 : template<>
643 : constexpr char16_t const * str_const_nan<char16_t>()
644 : {
645 : return u"nan";
646 : }
647 : template<>
648 : constexpr char32_t const * str_const_nan<char32_t>()
649 : {
650 : return U"nan";
651 : }
652 : template<typename UC>
653 : static constexpr UC const * str_const_inf()
654 : {
655 : return nullptr;
656 : }
657 : template<>
658 5 : constexpr char const * str_const_inf<char>()
659 : {
660 5 : return "infinity";
661 : }
662 : template<>
663 : constexpr wchar_t const * str_const_inf<wchar_t>()
664 : {
665 : return L"infinity";
666 : }
667 : template<>
668 : constexpr char16_t const * str_const_inf<char16_t>()
669 : {
670 : return u"infinity";
671 : }
672 : template<>
673 : constexpr char32_t const * str_const_inf<char32_t>()
674 : {
675 : return U"infinity";
676 : }
677 : } // namespace fast_float
678 :
679 : #endif
|