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