simdjson 5.0.2
Ridiculously Fast JSON
Loading...
Searching...
No Matches
fast_float.h
1// Vendored from fast_float v8.2.10, generated by tools/vendor_fast_float.sh.
2// Do not edit by hand; re-run the script to update.
3//
4// https://github.com/fastfloat/fast_float
5// Licensed under Apache-2.0 OR MIT OR BSL-1.0, at your option.
6//
7// simdjson uses this for two things that its own number parser cannot do:
8// * the slow path for numbers with more than 19 significant digits, where
9// fast_float's bigint comparison is several times quicker than the
10// Wuffs-derived decimal shifting it replaced (see src/from_chars.cpp), and
11// * correctly rounded parsing inside a constant expression, which the runtime
12// path cannot offer because it relies on memcpy and __uint128_t (see
13// compile_time_json-inl.h).
14//
15// Two edits are applied by the script. Every fast_float name is rewritten so
16// that this copy cannot collide with a copy of fast_float that the surrounding
17// program includes for itself: namespace fast_float -> simdjson_fast_float,
18// FASTFLOAT_* -> SIMDJSON_FASTFLOAT_*, fastfloat_* -> simdjson_fastfloat_*. And
19// the accented letters in the attribution comments below are folded to ASCII,
20// to keep the tree ASCII-only; no disrespect to the people named is intended.
21// simdjson_fast_float by Daniel Lemire
22// simdjson_fast_float by Joao Paulo Magalhaes
23//
24//
25// with contributions from Eugene Golushkov
26// with contributions from Maksim Kita
27// with contributions from Marcin Wojdyr
28// with contributions from Neal Richardson
29// with contributions from Tim Paine
30// with contributions from Fabio Pellacini
31// with contributions from Lenard Szolnoki
32// with contributions from Jan Pharago
33// with contributions from Maya Warrier
34// with contributions from Taha Khokhar
35// with contributions from Anders Dalvander
36//
37//
38// Licensed under the Apache License, Version 2.0, or the
39// MIT License or the Boost License. This file may not be copied,
40// modified, or distributed except according to those terms.
41//
42// MIT License Notice
43//
44// MIT License
45//
46// Copyright (c) 2021 The simdjson_fast_float authors
47//
48// Permission is hereby granted, free of charge, to any
49// person obtaining a copy of this software and associated
50// documentation files (the "Software"), to deal in the
51// Software without restriction, including without
52// limitation the rights to use, copy, modify, merge,
53// publish, distribute, sublicense, and/or sell copies of
54// the Software, and to permit persons to whom the Software
55// is furnished to do so, subject to the following
56// conditions:
57//
58// The above copyright notice and this permission notice
59// shall be included in all copies or substantial portions
60// of the Software.
61//
62// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
63// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
64// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
65// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
66// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
67// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
68// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
69// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
70// DEALINGS IN THE SOFTWARE.
71//
72// Apache License (Version 2.0) Notice
73//
74// Copyright 2021 The simdjson_fast_float authors
75// Licensed under the Apache License, Version 2.0 (the "License");
76// you may not use this file except in compliance with the License.
77// You may obtain a copy of the License at
78//
79// http://www.apache.org/licenses/LICENSE-2.0
80//
81// Unless required by applicable law or agreed to in writing, software
82// distributed under the License is distributed on an "AS IS" BASIS,
83// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84// See the License for the specific language governing permissions and
85//
86// BOOST License Notice
87//
88// Boost Software License - Version 1.0 - August 17th, 2003
89//
90// Permission is hereby granted, free of charge, to any person or organization
91// obtaining a copy of the software and accompanying documentation covered by
92// this license (the "Software") to use, reproduce, display, distribute,
93// execute, and transmit the Software, and to prepare derivative works of the
94// Software, and to permit third-parties to whom the Software is furnished to
95// do so, all subject to the following:
96//
97// The copyright notices in the Software and this entire statement, including
98// the above license grant, this restriction and the following disclaimer,
99// must be included in all copies of the Software, in whole or in part, and
100// all derivative works of the Software, unless such copies or derivative
101// works are solely in the form of machine-executable object code generated by
102// a source language processor.
103//
104// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
106// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
107// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
108// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
109// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
110// DEALINGS IN THE SOFTWARE.
111//
112
113#ifndef SIMDJSON_FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H
114#define SIMDJSON_FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H
115
116#ifdef __has_include
117#if __has_include(<version>)
118#include <version>
119#endif
120#endif
121
122// Testing for https://wg21.link/N3652, adopted in C++14
123#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
124#define SIMDJSON_FASTFLOAT_CONSTEXPR14 constexpr
125#else
126#define SIMDJSON_FASTFLOAT_CONSTEXPR14
127#endif
128
129#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
130#define SIMDJSON_FASTFLOAT_HAS_BIT_CAST 1
131#else
132#define SIMDJSON_FASTFLOAT_HAS_BIT_CAST 0
133#endif
134
135#if defined(__cpp_lib_is_constant_evaluated) && \
136 __cpp_lib_is_constant_evaluated >= 201811L
137#define SIMDJSON_FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 1
138#else
139#define SIMDJSON_FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0
140#endif
141
142#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
143#define SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(x) if constexpr (x)
144#else
145#define SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(x) if (x)
146#endif
147
148// Testing for relevant C++20 constexpr library features
149#if SIMDJSON_FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && SIMDJSON_FASTFLOAT_HAS_BIT_CAST && \
150 defined(__cpp_lib_constexpr_algorithms) && \
151 __cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/
152#define SIMDJSON_FASTFLOAT_CONSTEXPR20 constexpr
153#define SIMDJSON_FASTFLOAT_IS_CONSTEXPR 1
154#else
155#define SIMDJSON_FASTFLOAT_CONSTEXPR20
156#define SIMDJSON_FASTFLOAT_IS_CONSTEXPR 0
157#endif
158
159#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
160#define SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 0
161#else
162#define SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 1
163#endif
164
165#endif // SIMDJSON_FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H
166
167#ifndef SIMDJSON_FASTFLOAT_FLOAT_COMMON_H
168#define SIMDJSON_FASTFLOAT_FLOAT_COMMON_H
169
170#include <cfloat>
171#include <cstddef>
172#include <cstdint>
173#include <cassert>
174#include <cstring>
175#include <limits>
176#include <type_traits>
177#include <system_error>
178#ifdef __has_include
179#if __has_include(<stdfloat>) && (__cplusplus > 202002L || (defined(_MSVC_LANG) && (_MSVC_LANG > 202002L)))
180#include <stdfloat>
181#endif
182#endif
183
184#define SIMDJSON_FASTFLOAT_VERSION_MAJOR 8
185#define SIMDJSON_FASTFLOAT_VERSION_MINOR 2
186#define SIMDJSON_FASTFLOAT_VERSION_PATCH 10
187
188#define SIMDJSON_FASTFLOAT_STRINGIZE_IMPL(x) #x
189#define SIMDJSON_FASTFLOAT_STRINGIZE(x) SIMDJSON_FASTFLOAT_STRINGIZE_IMPL(x)
190
191#define SIMDJSON_FASTFLOAT_VERSION_STR \
192 SIMDJSON_FASTFLOAT_STRINGIZE(SIMDJSON_FASTFLOAT_VERSION_MAJOR) \
193 "." SIMDJSON_FASTFLOAT_STRINGIZE(SIMDJSON_FASTFLOAT_VERSION_MINOR) "." SIMDJSON_FASTFLOAT_STRINGIZE( \
194 SIMDJSON_FASTFLOAT_VERSION_PATCH)
195
196#define SIMDJSON_FASTFLOAT_VERSION \
197 (SIMDJSON_FASTFLOAT_VERSION_MAJOR * 10000 + SIMDJSON_FASTFLOAT_VERSION_MINOR * 100 + \
198 SIMDJSON_FASTFLOAT_VERSION_PATCH)
199
200namespace simdjson_fast_float {
201
202enum class chars_format : uint64_t;
203
204namespace detail {
205constexpr chars_format basic_json_fmt = chars_format(1 << 5);
206constexpr chars_format basic_fortran_fmt = chars_format(1 << 6);
207} // namespace detail
208
209enum class chars_format : uint64_t {
210 scientific = 1 << 0,
211 fixed = 1 << 2,
212 hex = 1 << 3,
213 no_infnan = 1 << 4,
214 // RFC 8259: https://datatracker.ietf.org/doc/html/rfc8259#section-6
215 json = uint64_t(detail::basic_json_fmt) | fixed | scientific | no_infnan,
216 // Extension of RFC 8259 where, e.g., "inf" and "nan" are allowed.
217 json_or_infnan = uint64_t(detail::basic_json_fmt) | fixed | scientific,
218 fortran = uint64_t(detail::basic_fortran_fmt) | fixed | scientific,
219 general = fixed | scientific,
220 allow_leading_plus = 1 << 7,
221 skip_white_space = 1 << 8,
222};
223
224template <typename UC> struct from_chars_result_t {
225 UC const *ptr;
226 std::errc ec;
227
228 // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2497r0.html
229 constexpr explicit operator bool() const noexcept {
230 return ec == std::errc();
231 }
232};
233
235
236template <typename UC> struct parse_options_t {
237 constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
238 UC dot = UC('.'), int b = 10)
239 : format(fmt), decimal_point(dot), base(b) {}
240
242 chars_format format;
246 int base;
247};
248
250
251} // namespace simdjson_fast_float
252
253#if SIMDJSON_FASTFLOAT_HAS_BIT_CAST
254#include <bit>
255#endif
256
257#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
258 defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) || \
259 defined(__MINGW64__) || defined(__s390x__) || \
260 (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || \
261 defined(__PPC64LE__)) || \
262 defined(__loongarch64) || (defined(__riscv) && __riscv_xlen == 64))
263#define SIMDJSON_FASTFLOAT_64BIT 1
264#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
265 defined(__arm__) || defined(_M_ARM) || defined(__ppc__) || \
266 defined(__MINGW32__) || defined(__EMSCRIPTEN__) || \
267 (defined(__riscv) && __riscv_xlen == 32))
268#define SIMDJSON_FASTFLOAT_32BIT 1
269#else
270 // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow.
271// We can never tell the register width, but the SIZE_MAX is a good
272// approximation. UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max
273// portability.
274#if SIZE_MAX == 0xffff
275#error Unknown platform (16-bit, unsupported)
276#elif SIZE_MAX == 0xffffffff
277#define SIMDJSON_FASTFLOAT_32BIT 1
278#elif SIZE_MAX == 0xffffffffffffffff
279#define SIMDJSON_FASTFLOAT_64BIT 1
280#else
281#error Unknown platform (not 32-bit, not 64-bit?)
282#endif
283#endif
284
285#if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__)) || \
286 (defined(_M_ARM64) && !defined(__MINGW32__))
287#include <intrin.h>
288#endif
289
290#if defined(_MSC_VER) && !defined(__clang__)
291#define SIMDJSON_FASTFLOAT_VISUAL_STUDIO 1
292#endif
293
294#if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
295#define SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
296#elif defined _WIN32
297#define SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN 0
298#else
299#if defined(__APPLE__) || defined(__FreeBSD__)
300#include <machine/endian.h>
301#elif defined(sun) || defined(__sun)
302#include <sys/byteorder.h>
303#elif defined(__MVS__)
304#include <sys/endian.h>
305#else
306#ifdef __has_include
307#if __has_include(<endian.h>)
308#include <endian.h>
309#endif //__has_include(<endian.h>)
310#endif //__has_include
311#endif
312#
313#ifndef __BYTE_ORDER__
314// safe choice
315#define SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN 0
316#endif
317#
318#ifndef __ORDER_LITTLE_ENDIAN__
319// safe choice
320#define SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN 0
321#endif
322#
323#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
324#define SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN 0
325#else
326#define SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN 1
327#endif
328#endif
329
330#if defined(__SSE2__) || (defined(SIMDJSON_FASTFLOAT_VISUAL_STUDIO) && \
331 (defined(_M_AMD64) || defined(_M_X64) || \
332 (defined(_M_IX86_FP) && _M_IX86_FP == 2)))
333#define SIMDJSON_FASTFLOAT_SSE2 1
334#endif
335
336#if defined(__aarch64__) || defined(_M_ARM64)
337#define SIMDJSON_FASTFLOAT_NEON 1
338#endif
339
340#if defined(SIMDJSON_FASTFLOAT_SSE2) || defined(SIMDJSON_FASTFLOAT_NEON)
341#define SIMDJSON_FASTFLOAT_HAS_SIMD 1
342#endif
343
344#if defined(__GNUC__)
345// disable -Wcast-align=strict (GCC only)
346#define SIMDJSON_FASTFLOAT_SIMD_DISABLE_WARNINGS \
347 _Pragma("GCC diagnostic push") \
348 _Pragma("GCC diagnostic ignored \"-Wcast-align\"")
349#else
350#define SIMDJSON_FASTFLOAT_SIMD_DISABLE_WARNINGS
351#endif
352
353#if defined(__GNUC__)
354#define SIMDJSON_FASTFLOAT_SIMD_RESTORE_WARNINGS _Pragma("GCC diagnostic pop")
355#else
356#define SIMDJSON_FASTFLOAT_SIMD_RESTORE_WARNINGS
357#endif
358
359#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
360#define simdjson_fastfloat_really_inline __forceinline
361#else
362#define simdjson_fastfloat_really_inline inline __attribute__((always_inline))
363#endif
364
365// Branch-probability hint marking the rare slow-path branches as cold, so the
366// optimizer keeps the out-of-line slow-path re-parse off the hot path (and does
367// not duplicate the force-inlined hot scanner into the caller, which bloated
368// the hot frame and hurt ILP on some targets). Used at the call site as
369// if simdjson_fastfloat_unlikely(cond) { ... }
370// (the macro supplies the parentheses). It expands to the standard [[unlikely]]
371// attribute when supported, otherwise to __builtin_expect on GCC/Clang, or
372// to a no-op elsewhere (e.g. pre-C++20 MSVC, which has no equivalent hint).
373#ifdef __has_cpp_attribute
374#if __has_cpp_attribute(unlikely) >= 201803L
375// g++-9 hits hits this branch, but then fails to compile
376// [[unlikely]]. This happens only with g++-9.
377#if !defined(__GNUC__) || (__GNUC__ != 9)
378#define SIMDJSON_FASTFLOAT_USE_UNLIKELY_ATTR
379#endif
380#endif
381#endif
382
383#ifdef SIMDJSON_FASTFLOAT_USE_UNLIKELY_ATTR
384#define simdjson_fastfloat_unlikely(x) (x) [[unlikely]]
385#elif defined(__GNUC__) || defined(__clang__)
386#define simdjson_fastfloat_unlikely(x) (__builtin_expect(!!(x), 0))
387#else
388#define simdjson_fastfloat_unlikely(x) (x)
389#endif
390
391#ifndef SIMDJSON_FASTFLOAT_ASSERT
392#define SIMDJSON_FASTFLOAT_ASSERT(x) \
393 { \
394 static_cast<void>(x); \
395 }
396#endif
397
398#ifndef SIMDJSON_FASTFLOAT_DEBUG_ASSERT
399#define SIMDJSON_FASTFLOAT_DEBUG_ASSERT(x) \
400 { \
401 static_cast<void>(x); \
402 }
403#endif
404
405// rust style `try!()` macro, or `?` operator
406#define SIMDJSON_FASTFLOAT_TRY(x) \
407 { \
408 if (!(x)) \
409 return false; \
410 }
411
412#define SIMDJSON_FASTFLOAT_ENABLE_IF(...) \
413 typename std::enable_if<(__VA_ARGS__), int>::type
414
415namespace simdjson_fast_float {
416
417simdjson_fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() {
418#if SIMDJSON_FASTFLOAT_HAS_IS_CONSTANT_EVALUATED
419 return std::is_constant_evaluated();
420#else
421 return false;
422#endif
423}
424
425template <typename T>
427 : std::integral_constant<
428 bool, std::is_same<T, double>::value || std::is_same<T, float>::value
429#ifdef __STDCPP_FLOAT64_T__
430 || std::is_same<T, std::float64_t>::value
431#endif
432#ifdef __STDCPP_FLOAT32_T__
433 || std::is_same<T, std::float32_t>::value
434#endif
435#ifdef __STDCPP_FLOAT16_T__
436 || std::is_same<T, std::float16_t>::value
437#endif
438#ifdef __STDCPP_BFLOAT16_T__
439 || std::is_same<T, std::bfloat16_t>::value
440#endif
441 > {
442};
443
444template <typename T>
445using equiv_uint_t = typename std::conditional<
446 sizeof(T) == 1, uint8_t,
447 typename std::conditional<
448 sizeof(T) == 2, uint16_t,
449 typename std::conditional<sizeof(T) == 4, uint32_t,
450 uint64_t>::type>::type>::type;
451
452template <typename T> struct is_supported_integer_type : std::is_integral<T> {};
453
454template <typename UC>
456 : std::integral_constant<bool, std::is_same<UC, char>::value ||
457 std::is_same<UC, wchar_t>::value ||
458 std::is_same<UC, char16_t>::value ||
459 std::is_same<UC, char32_t>::value
460#ifdef __cpp_char8_t
461 || std::is_same<UC, char8_t>::value
462#endif
463 > {
464};
465
466template <typename UC>
467inline SIMDJSON_FASTFLOAT_CONSTEXPR14 bool
468simdjson_fastfloat_strncasecmp3(UC const *actual_mixedcase,
469 UC const *expected_lowercase) {
470 uint64_t mask{0};
471 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 1) { mask = 0x2020202020202020; }
472 else SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 2) {
473 mask = 0x0020002000200020;
474 }
475 else SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 4) {
476 mask = 0x0000002000000020;
477 }
478 else {
479 return false;
480 }
481
482 uint64_t val1{0}, val2{0};
483 if (cpp20_and_in_constexpr()) {
484 for (size_t i = 0; i < 3; i++) {
485 if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
486 return false;
487 }
488 }
489 return true;
490 } else {
491 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 1 || sizeof(UC) == 2) {
492 ::memcpy(&val1, actual_mixedcase, 3 * sizeof(UC));
493 ::memcpy(&val2, expected_lowercase, 3 * sizeof(UC));
494 val1 |= mask;
495 val2 |= mask;
496 return val1 == val2;
497 }
498 else SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 4) {
499 ::memcpy(&val1, actual_mixedcase, 2 * sizeof(UC));
500 ::memcpy(&val2, expected_lowercase, 2 * sizeof(UC));
501 val1 |= mask;
502 if (val1 != val2) {
503 return false;
504 }
505 return (actual_mixedcase[2] | 32) == (expected_lowercase[2]);
506 }
507 else {
508 return false;
509 }
510 }
511}
512
513template <typename UC>
514inline SIMDJSON_FASTFLOAT_CONSTEXPR14 bool
515simdjson_fastfloat_strncasecmp5(UC const *actual_mixedcase,
516 UC const *expected_lowercase) {
517 uint64_t mask{0};
518 uint64_t val1{0}, val2{0};
519 if (cpp20_and_in_constexpr()) {
520 for (size_t i = 0; i < 5; i++) {
521 if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
522 return false;
523 }
524 }
525 return true;
526 } else {
527 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 1) {
528 mask = 0x2020202020202020;
529 ::memcpy(&val1, actual_mixedcase, 5 * sizeof(UC));
530 ::memcpy(&val2, expected_lowercase, 5 * sizeof(UC));
531 val1 |= mask;
532 val2 |= mask;
533 return val1 == val2;
534 }
535 else SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 2) {
536 mask = 0x0020002000200020;
537 ::memcpy(&val1, actual_mixedcase, 4 * sizeof(UC));
538 ::memcpy(&val2, expected_lowercase, 4 * sizeof(UC));
539 val1 |= mask;
540 if (val1 != val2) {
541 return false;
542 }
543 return (actual_mixedcase[4] | 32) == (expected_lowercase[4]);
544 }
545 else SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 4) {
546 mask = 0x0000002000000020;
547 ::memcpy(&val1, actual_mixedcase, 2 * sizeof(UC));
548 ::memcpy(&val2, expected_lowercase, 2 * sizeof(UC));
549 val1 |= mask;
550 if (val1 != val2) {
551 return false;
552 }
553 ::memcpy(&val1, actual_mixedcase + 2, 2 * sizeof(UC));
554 ::memcpy(&val2, expected_lowercase + 2, 2 * sizeof(UC));
555 val1 |= mask;
556 if (val1 != val2) {
557 return false;
558 }
559 return (actual_mixedcase[4] | 32) == (expected_lowercase[4]);
560 }
561 else {
562 return false;
563 }
564 }
565}
566
567// Compares two ASCII strings in a case insensitive manner.
568template <typename UC>
569inline SIMDJSON_FASTFLOAT_CONSTEXPR14 bool
570simdjson_fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase,
571 size_t length) {
572 uint64_t mask{0};
573 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 1) { mask = 0x2020202020202020; }
574 else SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 2) {
575 mask = 0x0020002000200020;
576 }
577 else SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 4) {
578 mask = 0x0000002000000020;
579 }
580 else {
581 return false;
582 }
583
584 if (cpp20_and_in_constexpr()) {
585 for (size_t i = 0; i < length; i++) {
586 if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
587 return false;
588 }
589 }
590 return true;
591 } else {
592 uint64_t val1{0}, val2{0};
593 size_t sz{8 / (sizeof(UC))};
594 for (size_t i = 0; i < length; i += sz) {
595 val1 = val2 = 0;
596 sz = sz < (length - i) ? sz : length - i;
597 ::memcpy(&val1, actual_mixedcase + i, sz * sizeof(UC));
598 ::memcpy(&val2, expected_lowercase + i, sz * sizeof(UC));
599 val1 |= mask;
600 val2 |= mask;
601 if (val1 != val2) {
602 return false;
603 }
604 }
605 return true;
606 }
607}
608
609#ifndef FLT_EVAL_METHOD
610#error "FLT_EVAL_METHOD should be defined, please include cfloat."
611#endif
612
613// a pointer and a length to a contiguous block of memory
614template <typename T> struct span {
615 T const *ptr;
616 size_t length;
617
618 constexpr span(T const *_ptr, size_t _length) : ptr(_ptr), length(_length) {}
619
620 constexpr span() : ptr(nullptr), length(0) {}
621
622 constexpr size_t len() const noexcept { return length; }
623
624 SIMDJSON_FASTFLOAT_CONSTEXPR14 const T &operator[](size_t index) const noexcept {
625 SIMDJSON_FASTFLOAT_DEBUG_ASSERT(index < length);
626 return ptr[index];
627 }
628};
629
630struct value128 {
631 uint64_t low;
632 uint64_t high;
633
634 constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {}
635
636 constexpr value128() : low(0), high(0) {}
637};
638
639/* Helper C++14 constexpr generic implementation of leading_zeroes */
640simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 int
641leading_zeroes_generic(uint64_t input_num, int last_bit = 0) {
642 if (input_num & uint64_t(0xffffffff00000000)) {
643 input_num >>= 32;
644 last_bit |= 32;
645 }
646 if (input_num & uint64_t(0xffff0000)) {
647 input_num >>= 16;
648 last_bit |= 16;
649 }
650 if (input_num & uint64_t(0xff00)) {
651 input_num >>= 8;
652 last_bit |= 8;
653 }
654 if (input_num & uint64_t(0xf0)) {
655 input_num >>= 4;
656 last_bit |= 4;
657 }
658 if (input_num & uint64_t(0xc)) {
659 input_num >>= 2;
660 last_bit |= 2;
661 }
662 if (input_num & uint64_t(0x2)) { /* input_num >>= 1; */
663 last_bit |= 1;
664 }
665 return 63 - last_bit;
666}
667
668/* result might be undefined when input_num is zero */
669simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 int
670leading_zeroes(uint64_t input_num) {
671 assert(input_num > 0);
672 if (cpp20_and_in_constexpr()) {
673 return leading_zeroes_generic(input_num);
674 }
675#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
676#if defined(_M_X64) || defined(_M_ARM64)
677 unsigned long leading_zero = 0;
678 // Search the mask data from most significant bit (MSB)
679 // to least significant bit (LSB) for a set bit (1).
680 _BitScanReverse64(&leading_zero, input_num);
681 return static_cast<int>(63 - leading_zero);
682#else
683 return leading_zeroes_generic(input_num);
684#endif
685#else
686 return __builtin_clzll(input_num);
687#endif
688}
689
690/* Helper C++14 constexpr generic implementation of countr_zero for 32-bit */
691simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 int
692countr_zero_generic_32(uint32_t input_num) {
693 if (input_num == 0) {
694 return 32;
695 }
696 int last_bit = 0;
697 if (!(input_num & 0x0000FFFF)) {
698 input_num >>= 16;
699 last_bit |= 16;
700 }
701 if (!(input_num & 0x00FF)) {
702 input_num >>= 8;
703 last_bit |= 8;
704 }
705 if (!(input_num & 0x0F)) {
706 input_num >>= 4;
707 last_bit |= 4;
708 }
709 if (!(input_num & 0x3)) {
710 input_num >>= 2;
711 last_bit |= 2;
712 }
713 if (!(input_num & 0x1)) {
714 last_bit |= 1;
715 }
716 return last_bit;
717}
718
719/* count trailing zeroes for 32-bit integers */
720simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 int
721countr_zero_32(uint32_t input_num) {
722 if (cpp20_and_in_constexpr()) {
723 return countr_zero_generic_32(input_num);
724 }
725#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
726 unsigned long trailing_zero = 0;
727 if (_BitScanForward(&trailing_zero, input_num)) {
728 return static_cast<int>(trailing_zero);
729 }
730 return 32;
731#else
732 return input_num == 0 ? 32 : __builtin_ctz(input_num);
733#endif
734}
735
736// slow emulation routine for 32-bit
737simdjson_fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) {
738 return x * static_cast<uint64_t>(y);
739}
740
741simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 uint64_t
742umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) {
743 uint64_t ad =
744 emulu(static_cast<uint32_t>(ab >> 32), static_cast<uint32_t>(cd));
745 uint64_t bd = emulu(static_cast<uint32_t>(ab), static_cast<uint32_t>(cd));
746 uint64_t adbc =
747 ad + emulu(static_cast<uint32_t>(ab), static_cast<uint32_t>(cd >> 32));
748 uint64_t adbc_carry = static_cast<uint64_t>(adbc < ad);
749 uint64_t lo = bd + (adbc << 32);
750 *hi =
751 emulu(static_cast<uint32_t>(ab >> 32), static_cast<uint32_t>(cd >> 32)) +
752 (adbc >> 32) + (adbc_carry << 32) + static_cast<uint64_t>(lo < bd);
753 return lo;
754}
755
756#ifdef SIMDJSON_FASTFLOAT_32BIT
757
758// slow emulation routine for 32-bit
759#if !defined(__MINGW64__)
760simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 uint64_t _umul128(uint64_t ab,
761 uint64_t cd,
762 uint64_t *hi) {
763 return umul128_generic(ab, cd, hi);
764}
765#endif // !__MINGW64__
766
767#endif // SIMDJSON_FASTFLOAT_32BIT
768
769// compute 64-bit a*b
770simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 value128
771full_multiplication(uint64_t a, uint64_t b) {
772 if (cpp20_and_in_constexpr()) {
773 value128 answer;
774 answer.low = umul128_generic(a, b, &answer.high);
775 return answer;
776 }
777 value128 answer;
778#if defined(_M_ARM64) && !defined(__MINGW32__)
779 // ARM64 has native support for 64-bit multiplications, no need to emulate
780 // But MinGW on ARM64 doesn't have native support for 64-bit multiplications
781 answer.high = __umulh(a, b);
782 answer.low = a * b;
783#elif defined(SIMDJSON_FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__) && \
784 !defined(_M_ARM64) && !defined(__GNUC__))
785 answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
786#elif defined(SIMDJSON_FASTFLOAT_64BIT) && defined(__SIZEOF_INT128__)
787 __uint128_t r = static_cast<__uint128_t>(a) * b;
788 answer.low = uint64_t(r);
789 answer.high = uint64_t(r >> 64);
790#else
791 answer.low = umul128_generic(a, b, &answer.high);
792#endif
793 return answer;
794}
795
797 uint64_t mantissa{0};
798 int32_t power2{0}; // a negative value indicates an invalid result
799 adjusted_mantissa() = default;
800
801 constexpr bool operator==(adjusted_mantissa const &o) const {
802 return mantissa == o.mantissa && power2 == o.power2;
803 }
804
805 constexpr bool operator!=(adjusted_mantissa const &o) const {
806 return mantissa != o.mantissa || power2 != o.power2;
807 }
808};
809
810// Bias so we can get the real exponent with an invalid adjusted_mantissa.
811constexpr static int32_t invalid_am_bias = -0x8000;
812
813// used for binary_format_lookup_tables<T>::max_mantissa
814constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
815
816template <typename T, typename U = void> struct binary_format_lookup_tables;
817
818template <typename T> struct binary_format : binary_format_lookup_tables<T> {
819 using equiv_uint = equiv_uint_t<T>;
820
821 static constexpr int mantissa_explicit_bits();
822 static constexpr int minimum_exponent();
823 static constexpr int infinite_power();
824 static constexpr int sign_index();
825 static constexpr int
826 min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
827 static constexpr int max_exponent_fast_path();
828 static constexpr int max_exponent_round_to_even();
829 static constexpr int min_exponent_round_to_even();
830 static constexpr uint64_t max_mantissa_fast_path(int64_t power);
831 static constexpr uint64_t
832 max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
833 static constexpr int largest_power_of_ten();
834 static constexpr int smallest_power_of_ten();
835 static constexpr T exact_power_of_ten(int64_t power);
836 static constexpr size_t max_digits();
837 static constexpr equiv_uint exponent_mask();
838 static constexpr equiv_uint mantissa_mask();
839 static constexpr equiv_uint hidden_bit_mask();
840};
841
842template <typename U> struct binary_format_lookup_tables<double, U> {
843 static constexpr double powers_of_ten[] = {
844 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
845 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
846
847 // Largest integer value v so that (5**index * v) <= 1<<53.
848 // 0x20000000000000 == 1 << 53
849 static constexpr uint64_t max_mantissa[] = {
850 0x20000000000000,
851 0x20000000000000 / 5,
852 0x20000000000000 / (5 * 5),
853 0x20000000000000 / (5 * 5 * 5),
854 0x20000000000000 / (5 * 5 * 5 * 5),
855 0x20000000000000 / (constant_55555),
856 0x20000000000000 / (constant_55555 * 5),
857 0x20000000000000 / (constant_55555 * 5 * 5),
858 0x20000000000000 / (constant_55555 * 5 * 5 * 5),
859 0x20000000000000 / (constant_55555 * 5 * 5 * 5 * 5),
860 0x20000000000000 / (constant_55555 * constant_55555),
861 0x20000000000000 / (constant_55555 * constant_55555 * 5),
862 0x20000000000000 / (constant_55555 * constant_55555 * 5 * 5),
863 0x20000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5),
864 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555),
865 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5),
866 0x20000000000000 /
867 (constant_55555 * constant_55555 * constant_55555 * 5 * 5),
868 0x20000000000000 /
869 (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5),
870 0x20000000000000 /
871 (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5),
872 0x20000000000000 /
873 (constant_55555 * constant_55555 * constant_55555 * constant_55555),
874 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 *
875 constant_55555 * 5),
876 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 *
877 constant_55555 * 5 * 5),
878 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 *
879 constant_55555 * 5 * 5 * 5),
880 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 *
881 constant_55555 * 5 * 5 * 5 * 5)};
882};
883
884#if SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
885
886template <typename U>
888
889template <typename U>
891
892#endif
893
894template <typename U> struct binary_format_lookup_tables<float, U> {
895 static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
896 1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
897
898 // Largest integer value v so that (5**index * v) <= 1<<24.
899 // 0x1000000 == 1<<24
900 static constexpr uint64_t max_mantissa[] = {
901 0x1000000,
902 0x1000000 / 5,
903 0x1000000 / (5 * 5),
904 0x1000000 / (5 * 5 * 5),
905 0x1000000 / (5 * 5 * 5 * 5),
906 0x1000000 / (constant_55555),
907 0x1000000 / (constant_55555 * 5),
908 0x1000000 / (constant_55555 * 5 * 5),
909 0x1000000 / (constant_55555 * 5 * 5 * 5),
910 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5),
911 0x1000000 / (constant_55555 * constant_55555),
912 0x1000000 / (constant_55555 * constant_55555 * 5)};
913};
914
915#if SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
916
917template <typename U>
919
920template <typename U>
922
923#endif
924
925template <>
927#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
928 return 0;
929#else
930 return -22;
931#endif
932}
933
934template <>
935inline constexpr int binary_format<float>::min_exponent_fast_path() {
936#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
937 return 0;
938#else
939 return -10;
940#endif
941}
942
943template <>
944inline constexpr int binary_format<double>::mantissa_explicit_bits() {
945 return 52;
946}
947
948template <>
949inline constexpr int binary_format<float>::mantissa_explicit_bits() {
950 return 23;
951}
952
953template <>
954inline constexpr int binary_format<double>::max_exponent_round_to_even() {
955 return 23;
956}
957
958template <>
959inline constexpr int binary_format<float>::max_exponent_round_to_even() {
960 return 10;
961}
962
963template <>
964inline constexpr int binary_format<double>::min_exponent_round_to_even() {
965 return -4;
966}
967
968template <>
969inline constexpr int binary_format<float>::min_exponent_round_to_even() {
970 return -17;
971}
972
973template <> inline constexpr int binary_format<double>::minimum_exponent() {
974 return -1023;
975}
976
977template <> inline constexpr int binary_format<float>::minimum_exponent() {
978 return -127;
979}
980
981template <> inline constexpr int binary_format<double>::infinite_power() {
982 return 0x7FF;
983}
984
985template <> inline constexpr int binary_format<float>::infinite_power() {
986 return 0xFF;
987}
988
989template <> inline constexpr int binary_format<double>::sign_index() {
990 return 63;
991}
992
993template <> inline constexpr int binary_format<float>::sign_index() {
994 return 31;
995}
996
997template <>
998inline constexpr int binary_format<double>::max_exponent_fast_path() {
999 return 22;
1000}
1001
1002template <>
1003inline constexpr int binary_format<float>::max_exponent_fast_path() {
1004 return 10;
1005}
1006
1007template <>
1008inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
1009 return uint64_t(2) << mantissa_explicit_bits();
1010}
1011
1012template <>
1013inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
1014 return uint64_t(2) << mantissa_explicit_bits();
1015}
1016
1017// credit: Jakub Jelinek
1018#ifdef __STDCPP_FLOAT16_T__
1019template <typename U> struct binary_format_lookup_tables<std::float16_t, U> {
1020 static constexpr std::float16_t powers_of_ten[] = {1e0f16, 1e1f16, 1e2f16,
1021 1e3f16, 1e4f16};
1022
1023 // Largest integer value v so that (5**index * v) <= 1<<11.
1024 // 0x800 == 1<<11
1025 static constexpr uint64_t max_mantissa[] = {0x800,
1026 0x800 / 5,
1027 0x800 / (5 * 5),
1028 0x800 / (5 * 5 * 5),
1029 0x800 / (5 * 5 * 5 * 5),
1030 0x800 / (constant_55555)};
1031};
1032
1033#if SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
1034
1035template <typename U>
1036constexpr std::float16_t
1037 binary_format_lookup_tables<std::float16_t, U>::powers_of_ten[];
1038
1039template <typename U>
1040constexpr uint64_t
1041 binary_format_lookup_tables<std::float16_t, U>::max_mantissa[];
1042
1043#endif
1044
1045template <>
1046inline constexpr std::float16_t
1047binary_format<std::float16_t>::exact_power_of_ten(int64_t power) {
1048 // Work around clang bug https://godbolt.org/z/zedh7rrhc
1049 return static_cast<void>(powers_of_ten[0]), powers_of_ten[power];
1050}
1051
1052template <>
1053inline constexpr binary_format<std::float16_t>::equiv_uint
1054binary_format<std::float16_t>::exponent_mask() {
1055 return 0x7C00;
1056}
1057
1058template <>
1059inline constexpr binary_format<std::float16_t>::equiv_uint
1060binary_format<std::float16_t>::mantissa_mask() {
1061 return 0x03FF;
1062}
1063
1064template <>
1065inline constexpr binary_format<std::float16_t>::equiv_uint
1066binary_format<std::float16_t>::hidden_bit_mask() {
1067 return 0x0400;
1068}
1069
1070template <>
1071inline constexpr int binary_format<std::float16_t>::max_exponent_fast_path() {
1072 return 4;
1073}
1074
1075template <>
1076inline constexpr int binary_format<std::float16_t>::mantissa_explicit_bits() {
1077 return 10;
1078}
1079
1080template <>
1081inline constexpr uint64_t
1082binary_format<std::float16_t>::max_mantissa_fast_path() {
1083 return uint64_t(2) << mantissa_explicit_bits();
1084}
1085
1086template <>
1087inline constexpr uint64_t
1088binary_format<std::float16_t>::max_mantissa_fast_path(int64_t power) {
1089 // caller is responsible to ensure that
1090 // power >= 0 && power <= 4
1091 //
1092 // Work around clang bug https://godbolt.org/z/zedh7rrhc
1093 return static_cast<void>(max_mantissa[0]), max_mantissa[power];
1094}
1095
1096template <>
1097inline constexpr int binary_format<std::float16_t>::min_exponent_fast_path() {
1098 return 0;
1099}
1100
1101template <>
1102inline constexpr int
1103binary_format<std::float16_t>::max_exponent_round_to_even() {
1104 return 5;
1105}
1106
1107template <>
1108inline constexpr int
1109binary_format<std::float16_t>::min_exponent_round_to_even() {
1110 return -22;
1111}
1112
1113template <>
1114inline constexpr int binary_format<std::float16_t>::minimum_exponent() {
1115 return -15;
1116}
1117
1118template <>
1119inline constexpr int binary_format<std::float16_t>::infinite_power() {
1120 return 0x1F;
1121}
1122
1123template <> inline constexpr int binary_format<std::float16_t>::sign_index() {
1124 return 15;
1125}
1126
1127template <>
1128inline constexpr int binary_format<std::float16_t>::largest_power_of_ten() {
1129 return 4;
1130}
1131
1132template <>
1133inline constexpr int binary_format<std::float16_t>::smallest_power_of_ten() {
1134 return -27;
1135}
1136
1137template <>
1138inline constexpr size_t binary_format<std::float16_t>::max_digits() {
1139 return 22;
1140}
1141#endif // __STDCPP_FLOAT16_T__
1142
1143// credit: Jakub Jelinek
1144#ifdef __STDCPP_BFLOAT16_T__
1145template <typename U> struct binary_format_lookup_tables<std::bfloat16_t, U> {
1146 static constexpr std::bfloat16_t powers_of_ten[] = {1e0bf16, 1e1bf16, 1e2bf16,
1147 1e3bf16};
1148
1149 // Largest integer value v so that (5**index * v) <= 1<<8.
1150 // 0x100 == 1<<8
1151 static constexpr uint64_t max_mantissa[] = {0x100, 0x100 / 5, 0x100 / (5 * 5),
1152 0x100 / (5 * 5 * 5),
1153 0x100 / (5 * 5 * 5 * 5)};
1154};
1155
1156#if SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
1157
1158template <typename U>
1159constexpr std::bfloat16_t
1160 binary_format_lookup_tables<std::bfloat16_t, U>::powers_of_ten[];
1161
1162template <typename U>
1163constexpr uint64_t
1164 binary_format_lookup_tables<std::bfloat16_t, U>::max_mantissa[];
1165
1166#endif
1167
1168template <>
1169inline constexpr std::bfloat16_t
1170binary_format<std::bfloat16_t>::exact_power_of_ten(int64_t power) {
1171 // Work around clang bug https://godbolt.org/z/zedh7rrhc
1172 return static_cast<void>(powers_of_ten[0]), powers_of_ten[power];
1173}
1174
1175template <>
1176inline constexpr int binary_format<std::bfloat16_t>::max_exponent_fast_path() {
1177 return 3;
1178}
1179
1180template <>
1181inline constexpr binary_format<std::bfloat16_t>::equiv_uint
1182binary_format<std::bfloat16_t>::exponent_mask() {
1183 return 0x7F80;
1184}
1185
1186template <>
1187inline constexpr binary_format<std::bfloat16_t>::equiv_uint
1188binary_format<std::bfloat16_t>::mantissa_mask() {
1189 return 0x007F;
1190}
1191
1192template <>
1193inline constexpr binary_format<std::bfloat16_t>::equiv_uint
1194binary_format<std::bfloat16_t>::hidden_bit_mask() {
1195 return 0x0080;
1196}
1197
1198template <>
1199inline constexpr int binary_format<std::bfloat16_t>::mantissa_explicit_bits() {
1200 return 7;
1201}
1202
1203template <>
1204inline constexpr uint64_t
1205binary_format<std::bfloat16_t>::max_mantissa_fast_path() {
1206 return uint64_t(2) << mantissa_explicit_bits();
1207}
1208
1209template <>
1210inline constexpr uint64_t
1211binary_format<std::bfloat16_t>::max_mantissa_fast_path(int64_t power) {
1212 // caller is responsible to ensure that
1213 // power >= 0 && power <= 3
1214 //
1215 // Work around clang bug https://godbolt.org/z/zedh7rrhc
1216 return static_cast<void>(max_mantissa[0]), max_mantissa[power];
1217}
1218
1219template <>
1220inline constexpr int binary_format<std::bfloat16_t>::min_exponent_fast_path() {
1221 return 0;
1222}
1223
1224template <>
1225inline constexpr int
1226binary_format<std::bfloat16_t>::max_exponent_round_to_even() {
1227 return 3;
1228}
1229
1230template <>
1231inline constexpr int
1232binary_format<std::bfloat16_t>::min_exponent_round_to_even() {
1233 return -24;
1234}
1235
1236template <>
1237inline constexpr int binary_format<std::bfloat16_t>::minimum_exponent() {
1238 return -127;
1239}
1240
1241template <>
1242inline constexpr int binary_format<std::bfloat16_t>::infinite_power() {
1243 return 0xFF;
1244}
1245
1246template <> inline constexpr int binary_format<std::bfloat16_t>::sign_index() {
1247 return 15;
1248}
1249
1250template <>
1251inline constexpr int binary_format<std::bfloat16_t>::largest_power_of_ten() {
1252 return 38;
1253}
1254
1255template <>
1256inline constexpr int binary_format<std::bfloat16_t>::smallest_power_of_ten() {
1257 return -60;
1258}
1259
1260template <>
1261inline constexpr size_t binary_format<std::bfloat16_t>::max_digits() {
1262 return 98;
1263}
1264#endif // __STDCPP_BFLOAT16_T__
1265
1266template <>
1267inline constexpr uint64_t
1268binary_format<double>::max_mantissa_fast_path(int64_t power) {
1269 // caller is responsible to ensure that
1270 // power >= 0 && power <= 22
1271 //
1272 // Work around clang bug https://godbolt.org/z/zedh7rrhc
1273 return static_cast<void>(max_mantissa[0]), max_mantissa[power];
1274}
1275
1276template <>
1277inline constexpr uint64_t
1278binary_format<float>::max_mantissa_fast_path(int64_t power) {
1279 // caller is responsible to ensure that
1280 // power >= 0 && power <= 10
1281 //
1282 // Work around clang bug https://godbolt.org/z/zedh7rrhc
1283 return static_cast<void>(max_mantissa[0]), max_mantissa[power];
1284}
1285
1286template <>
1287inline constexpr double
1288binary_format<double>::exact_power_of_ten(int64_t power) {
1289 // Work around clang bug https://godbolt.org/z/zedh7rrhc
1290 return static_cast<void>(powers_of_ten[0]), powers_of_ten[power];
1291}
1292
1293template <>
1294inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
1295 // Work around clang bug https://godbolt.org/z/zedh7rrhc
1296 return static_cast<void>(powers_of_ten[0]), powers_of_ten[power];
1297}
1298
1299template <> inline constexpr int binary_format<double>::largest_power_of_ten() {
1300 return 308;
1301}
1302
1303template <> inline constexpr int binary_format<float>::largest_power_of_ten() {
1304 return 38;
1305}
1306
1307template <>
1308inline constexpr int binary_format<double>::smallest_power_of_ten() {
1309 return -342;
1310}
1311
1312template <> inline constexpr int binary_format<float>::smallest_power_of_ten() {
1313 return -64;
1314}
1315
1316template <> inline constexpr size_t binary_format<double>::max_digits() {
1317 return 769;
1318}
1319
1320template <> inline constexpr size_t binary_format<float>::max_digits() {
1321 return 114;
1322}
1323
1324template <>
1325inline constexpr binary_format<float>::equiv_uint
1326binary_format<float>::exponent_mask() {
1327 return 0x7F800000;
1328}
1329
1330template <>
1331inline constexpr binary_format<double>::equiv_uint
1332binary_format<double>::exponent_mask() {
1333 return 0x7FF0000000000000;
1334}
1335
1336template <>
1337inline constexpr binary_format<float>::equiv_uint
1338binary_format<float>::mantissa_mask() {
1339 return 0x007FFFFF;
1340}
1341
1342template <>
1343inline constexpr binary_format<double>::equiv_uint
1344binary_format<double>::mantissa_mask() {
1345 return 0x000FFFFFFFFFFFFF;
1346}
1347
1348template <>
1349inline constexpr binary_format<float>::equiv_uint
1350binary_format<float>::hidden_bit_mask() {
1351 return 0x00800000;
1352}
1353
1354template <>
1355inline constexpr binary_format<double>::equiv_uint
1356binary_format<double>::hidden_bit_mask() {
1357 return 0x0010000000000000;
1358}
1359
1360template <typename T>
1361simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 void
1362to_float(bool negative, adjusted_mantissa am, T &value) {
1363 using equiv_uint = equiv_uint_t<T>;
1364 equiv_uint word = equiv_uint(am.mantissa);
1365 word = equiv_uint(word | equiv_uint(am.power2)
1366 << binary_format<T>::mantissa_explicit_bits());
1367 word =
1368 equiv_uint(word | equiv_uint(negative) << binary_format<T>::sign_index());
1369#if SIMDJSON_FASTFLOAT_HAS_BIT_CAST
1370 value = std::bit_cast<T>(word);
1371#else
1372 ::memcpy(&value, &word, sizeof(T));
1373#endif
1374}
1375
1376template <typename = void> struct space_lut {
1377 static constexpr bool value[] = {
1378 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1379 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1380 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1381 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1382 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1383 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1384 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1389};
1390
1391#if SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
1392
1393template <typename T> constexpr bool space_lut<T>::value[];
1394
1395#endif
1396
1397template <typename UC> constexpr bool is_space(UC c) {
1398 // wchar_t and char can be signed, so a negative code unit slips past a plain
1399 // `c < 256` and then indexes the table by its truncated low byte. Compare as
1400 // unsigned, matching the care taken in ch_to_digit.
1401 using UnsignedUC = typename std::make_unsigned<UC>::type;
1402 return static_cast<UnsignedUC>(c) < 256 && space_lut<>::value[uint8_t(c)];
1403}
1404
1405template <typename UC> static constexpr uint64_t int_cmp_zeros() {
1406 static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4),
1407 "Unsupported character size");
1408 return (sizeof(UC) == 1) ? 0x3030303030303030
1409 : (sizeof(UC) == 2)
1410 ? (uint64_t(UC('0')) << 48 | uint64_t(UC('0')) << 32 |
1411 uint64_t(UC('0')) << 16 | UC('0'))
1412 : (uint64_t(UC('0')) << 32 | UC('0'));
1413}
1414
1415template <typename UC> static constexpr int int_cmp_len() {
1416 return sizeof(uint64_t) / sizeof(UC);
1417}
1418
1419template <typename UC> constexpr UC const *str_const_nan();
1420
1421template <> constexpr char const *str_const_nan<char>() { return "nan"; }
1422
1423template <> constexpr wchar_t const *str_const_nan<wchar_t>() { return L"nan"; }
1424
1425template <> constexpr char16_t const *str_const_nan<char16_t>() {
1426 return u"nan";
1427}
1428
1429template <> constexpr char32_t const *str_const_nan<char32_t>() {
1430 return U"nan";
1431}
1432
1433#ifdef __cpp_char8_t
1434template <> constexpr char8_t const *str_const_nan<char8_t>() {
1435 return u8"nan";
1436}
1437#endif
1438
1439template <typename UC> constexpr UC const *str_const_inf();
1440
1441template <> constexpr char const *str_const_inf<char>() { return "infinity"; }
1442
1443template <> constexpr wchar_t const *str_const_inf<wchar_t>() {
1444 return L"infinity";
1445}
1446
1447template <> constexpr char16_t const *str_const_inf<char16_t>() {
1448 return u"infinity";
1449}
1450
1451template <> constexpr char32_t const *str_const_inf<char32_t>() {
1452 return U"infinity";
1453}
1454
1455#ifdef __cpp_char8_t
1456template <> constexpr char8_t const *str_const_inf<char8_t>() {
1457 return u8"infinity";
1458}
1459#endif
1460
1461template <typename = void> struct int_luts {
1462 static constexpr uint8_t chdigit[] = {
1463 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1464 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1465 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1466 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255,
1467 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1468 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
1469 35, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17,
1470 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
1471 33, 34, 35, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1472 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1473 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1474 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1475 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1476 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1477 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1478 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1479 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1480 255};
1481
1482 static constexpr size_t maxdigits_u64[] = {
1483 64, 41, 32, 28, 25, 23, 22, 21, 20, 19, 18, 18, 17, 17, 16, 16, 16, 16,
1484 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13};
1485
1486 static constexpr uint64_t min_safe_u64[] = {
1487 9223372036854775808ull, 12157665459056928801ull, 4611686018427387904,
1488 7450580596923828125, 4738381338321616896, 3909821048582988049,
1489 9223372036854775808ull, 12157665459056928801ull, 10000000000000000000ull,
1490 5559917313492231481, 2218611106740436992, 8650415919381337933,
1491 2177953337809371136, 6568408355712890625, 1152921504606846976,
1492 2862423051509815793, 6746640616477458432, 15181127029874798299ull,
1493 1638400000000000000, 3243919932521508681, 6221821273427820544,
1494 11592836324538749809ull, 876488338465357824, 1490116119384765625,
1495 2481152873203736576, 4052555153018976267, 6502111422497947648,
1496 10260628712958602189ull, 15943230000000000000ull, 787662783788549761,
1497 1152921504606846976, 1667889514952984961, 2386420683693101056,
1498 3379220508056640625, 4738381338321616896};
1499};
1500
1501#if SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
1502
1503template <typename T> constexpr uint8_t int_luts<T>::chdigit[];
1504
1505template <typename T> constexpr size_t int_luts<T>::maxdigits_u64[];
1506
1507template <typename T> constexpr uint64_t int_luts<T>::min_safe_u64[];
1508
1509#endif
1510
1511template <typename UC>
1512simdjson_fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) {
1513 // wchar_t and char can be signed, so we need to be careful.
1514 using UnsignedUC = typename std::make_unsigned<UC>::type;
1515 return int_luts<>::chdigit[static_cast<unsigned char>(
1516 static_cast<UnsignedUC>(c) &
1517 static_cast<UnsignedUC>(
1518 -((static_cast<UnsignedUC>(c) & ~0xFFull) == 0)))];
1519}
1520
1521simdjson_fastfloat_really_inline constexpr size_t max_digits_u64(int base) {
1522 return int_luts<>::maxdigits_u64[base - 2];
1523}
1524
1525// If a u64 is exactly max_digits_u64() in length, this is
1526// the value below which it has definitely overflowed.
1527simdjson_fastfloat_really_inline constexpr uint64_t min_safe_u64(int base) {
1528 return int_luts<>::min_safe_u64[base - 2];
1529}
1530
1531static_assert(std::is_same<equiv_uint_t<double>, uint64_t>::value,
1532 "equiv_uint should be uint64_t for double");
1533static_assert(std::numeric_limits<double>::is_iec559,
1534 "double must fulfill the requirements of IEC 559 (IEEE 754)");
1535
1536static_assert(std::is_same<equiv_uint_t<float>, uint32_t>::value,
1537 "equiv_uint should be uint32_t for float");
1538static_assert(std::numeric_limits<float>::is_iec559,
1539 "float must fulfill the requirements of IEC 559 (IEEE 754)");
1540
1541#ifdef __STDCPP_FLOAT64_T__
1542static_assert(std::is_same<equiv_uint_t<std::float64_t>, uint64_t>::value,
1543 "equiv_uint should be uint64_t for std::float64_t");
1544static_assert(
1545 std::numeric_limits<std::float64_t>::is_iec559,
1546 "std::float64_t must fulfill the requirements of IEC 559 (IEEE 754)");
1547
1548template <>
1549struct binary_format<std::float64_t> : public binary_format<double> {};
1550#endif // __STDCPP_FLOAT64_T__
1551
1552#ifdef __STDCPP_FLOAT32_T__
1553static_assert(std::is_same<equiv_uint_t<std::float32_t>, uint32_t>::value,
1554 "equiv_uint should be uint32_t for std::float32_t");
1555static_assert(
1556 std::numeric_limits<std::float32_t>::is_iec559,
1557 "std::float32_t must fulfill the requirements of IEC 559 (IEEE 754)");
1558
1559template <>
1560struct binary_format<std::float32_t> : public binary_format<float> {};
1561#endif // __STDCPP_FLOAT32_T__
1562
1563#ifdef __STDCPP_FLOAT16_T__
1564static_assert(
1565 std::is_same<binary_format<std::float16_t>::equiv_uint, uint16_t>::value,
1566 "equiv_uint should be uint16_t for std::float16_t");
1567static_assert(
1568 std::numeric_limits<std::float16_t>::is_iec559,
1569 "std::float16_t must fulfill the requirements of IEC 559 (IEEE 754)");
1570#endif // __STDCPP_FLOAT16_T__
1571
1572#ifdef __STDCPP_BFLOAT16_T__
1573static_assert(
1574 std::is_same<binary_format<std::bfloat16_t>::equiv_uint, uint16_t>::value,
1575 "equiv_uint should be uint16_t for std::bfloat16_t");
1576static_assert(
1577 std::numeric_limits<std::bfloat16_t>::is_iec559,
1578 "std::bfloat16_t must fulfill the requirements of IEC 559 (IEEE 754)");
1579#endif // __STDCPP_BFLOAT16_T__
1580
1581constexpr chars_format operator~(chars_format rhs) noexcept {
1582 using int_type = std::underlying_type<chars_format>::type;
1583 return static_cast<chars_format>(~static_cast<int_type>(rhs));
1584}
1585
1586constexpr chars_format operator&(chars_format lhs, chars_format rhs) noexcept {
1587 using int_type = std::underlying_type<chars_format>::type;
1588 return static_cast<chars_format>(static_cast<int_type>(lhs) &
1589 static_cast<int_type>(rhs));
1590}
1591
1592constexpr chars_format operator|(chars_format lhs, chars_format rhs) noexcept {
1593 using int_type = std::underlying_type<chars_format>::type;
1594 return static_cast<chars_format>(static_cast<int_type>(lhs) |
1595 static_cast<int_type>(rhs));
1596}
1597
1598constexpr chars_format operator^(chars_format lhs, chars_format rhs) noexcept {
1599 using int_type = std::underlying_type<chars_format>::type;
1600 return static_cast<chars_format>(static_cast<int_type>(lhs) ^
1601 static_cast<int_type>(rhs));
1602}
1603
1604simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 chars_format &
1605operator&=(chars_format &lhs, chars_format rhs) noexcept {
1606 return lhs = (lhs & rhs);
1607}
1608
1609simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 chars_format &
1610operator|=(chars_format &lhs, chars_format rhs) noexcept {
1611 return lhs = (lhs | rhs);
1612}
1613
1614simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 chars_format &
1615operator^=(chars_format &lhs, chars_format rhs) noexcept {
1616 return lhs = (lhs ^ rhs);
1617}
1618
1619namespace detail {
1620// adjust for deprecated feature macros
1621constexpr chars_format adjust_for_feature_macros(chars_format fmt) {
1622 return fmt
1623#ifdef SIMDJSON_FASTFLOAT_ALLOWS_LEADING_PLUS
1624 | chars_format::allow_leading_plus
1625#endif
1626#ifdef SIMDJSON_FASTFLOAT_SKIP_WHITE_SPACE
1627 | chars_format::skip_white_space
1628#endif
1629 ;
1630}
1631} // namespace detail
1632} // namespace simdjson_fast_float
1633
1634#endif
1635
1636
1637#ifndef SIMDJSON_FASTFLOAT_FAST_FLOAT_H
1638#define SIMDJSON_FASTFLOAT_FAST_FLOAT_H
1639
1640
1641namespace simdjson_fast_float {
1667template <typename T, typename UC = char,
1668 typename = SIMDJSON_FASTFLOAT_ENABLE_IF(is_supported_float_type<T>::value)>
1669SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
1670from_chars(UC const *first, UC const *last, T &value,
1671 chars_format fmt = chars_format::general) noexcept;
1672
1677template <typename T, typename UC = char>
1678SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
1679from_chars_advanced(UC const *first, UC const *last, T &value,
1680 parse_options_t<UC> options) noexcept;
1681
1695SIMDJSON_FASTFLOAT_CONSTEXPR20 inline double
1696integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept;
1697SIMDJSON_FASTFLOAT_CONSTEXPR20 inline double
1698integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept;
1699
1705template <typename T>
1706SIMDJSON_FASTFLOAT_CONSTEXPR20
1707 typename std::enable_if<is_supported_float_type<T>::value, T>::type
1708 integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept;
1709template <typename T>
1710SIMDJSON_FASTFLOAT_CONSTEXPR20
1711 typename std::enable_if<is_supported_float_type<T>::value, T>::type
1712 integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept;
1713
1717template <typename T, typename UC = char,
1718 typename = SIMDJSON_FASTFLOAT_ENABLE_IF(is_supported_integer_type<T>::value)>
1719SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
1720from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept;
1721
1722} // namespace simdjson_fast_float
1723
1724#endif // SIMDJSON_FASTFLOAT_FAST_FLOAT_H
1725
1726#ifndef SIMDJSON_FASTFLOAT_ASCII_NUMBER_H
1727#define SIMDJSON_FASTFLOAT_ASCII_NUMBER_H
1728
1729#include <cctype>
1730#include <cstdint>
1731#include <cstring>
1732#include <iterator>
1733#include <limits>
1734#include <type_traits>
1735
1736
1737#ifdef SIMDJSON_FASTFLOAT_SSE2
1738#include <emmintrin.h>
1739#endif
1740
1741#ifdef SIMDJSON_FASTFLOAT_NEON
1742#include <arm_neon.h>
1743#endif
1744
1745namespace simdjson_fast_float {
1746
1747template <typename UC> simdjson_fastfloat_really_inline constexpr bool has_simd_opt() {
1748#ifdef SIMDJSON_FASTFLOAT_HAS_SIMD
1749 return std::is_same<UC, char16_t>::value;
1750#else
1751 return false;
1752#endif
1753}
1754
1755// Next function can be micro-optimized, but compilers are entirely
1756// able to optimize it well.
1757template <typename UC>
1758simdjson_fastfloat_really_inline constexpr bool is_integer(UC c) noexcept {
1759 return static_cast<unsigned>(c - UC('0')) <= 9u;
1760}
1761
1762simdjson_fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) {
1763 return (val & 0xFF00000000000000) >> 56 | (val & 0x00FF000000000000) >> 40 |
1764 (val & 0x0000FF0000000000) >> 24 | (val & 0x000000FF00000000) >> 8 |
1765 (val & 0x00000000FF000000) << 8 | (val & 0x0000000000FF0000) << 24 |
1766 (val & 0x000000000000FF00) << 40 | (val & 0x00000000000000FF) << 56;
1767}
1768
1769simdjson_fastfloat_really_inline constexpr uint32_t byteswap_32(uint32_t val) {
1770 return (val >> 24) | ((val >> 8) & 0x0000FF00u) | ((val << 8) & 0x00FF0000u) |
1771 (val << 24);
1772}
1773
1774// Read 8 UC into a u64. Truncates UC if not char.
1775template <typename UC>
1776simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 uint64_t
1777read8_to_u64(UC const *chars) {
1778 if (cpp20_and_in_constexpr() || !std::is_same<UC, char>::value) {
1779 uint64_t val = 0;
1780 for (int i = 0; i < 8; ++i) {
1781 val |= uint64_t(uint8_t(*chars)) << (i * 8);
1782 ++chars;
1783 }
1784 return val;
1785 }
1786 uint64_t val;
1787 ::memcpy(&val, chars, sizeof(uint64_t));
1788#if SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN == 1
1789 // Need to read as-if the number was in little-endian order.
1790 val = byteswap(val);
1791#endif
1792 return val;
1793}
1794
1795// Read 4 UC into a u32. Truncates UC if not char.
1796template <typename UC>
1797simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 uint32_t
1798read4_to_u32(UC const *chars) {
1799 if (cpp20_and_in_constexpr() || !std::is_same<UC, char>::value) {
1800 uint32_t val = 0;
1801 for (int i = 0; i < 4; ++i) {
1802 val |= uint32_t(uint8_t(*chars)) << (i * 8);
1803 ++chars;
1804 }
1805 return val;
1806 }
1807 uint32_t val;
1808 ::memcpy(&val, chars, sizeof(uint32_t));
1809#if SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN == 1
1810 val = byteswap_32(val);
1811#endif
1812 return val;
1813}
1814#ifdef SIMDJSON_FASTFLOAT_SSE2
1815
1816simdjson_fastfloat_really_inline uint64_t simd_read8_to_u64(__m128i const data) {
1817 SIMDJSON_FASTFLOAT_SIMD_DISABLE_WARNINGS
1818 __m128i const packed = _mm_packus_epi16(data, data);
1819#ifdef SIMDJSON_FASTFLOAT_64BIT
1820 return uint64_t(_mm_cvtsi128_si64(packed));
1821#else
1822 uint64_t value;
1823 // Visual Studio + older versions of GCC don't support _mm_storeu_si64
1824 _mm_storel_epi64(reinterpret_cast<__m128i *>(&value), packed);
1825 return value;
1826#endif
1827 SIMDJSON_FASTFLOAT_SIMD_RESTORE_WARNINGS
1828}
1829
1830simdjson_fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
1831 SIMDJSON_FASTFLOAT_SIMD_DISABLE_WARNINGS
1832 return simd_read8_to_u64(
1833 _mm_loadu_si128(reinterpret_cast<__m128i const *>(chars)));
1834 SIMDJSON_FASTFLOAT_SIMD_RESTORE_WARNINGS
1835}
1836
1837#elif defined(SIMDJSON_FASTFLOAT_NEON)
1838
1839simdjson_fastfloat_really_inline uint64_t simd_read8_to_u64(uint16x8_t const data) {
1840 SIMDJSON_FASTFLOAT_SIMD_DISABLE_WARNINGS
1841 uint8x8_t utf8_packed = vmovn_u16(data);
1842 return vget_lane_u64(vreinterpret_u64_u8(utf8_packed), 0);
1843 SIMDJSON_FASTFLOAT_SIMD_RESTORE_WARNINGS
1844}
1845
1846simdjson_fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
1847 SIMDJSON_FASTFLOAT_SIMD_DISABLE_WARNINGS
1848 return simd_read8_to_u64(
1849 vld1q_u16(reinterpret_cast<uint16_t const *>(chars)));
1850 SIMDJSON_FASTFLOAT_SIMD_RESTORE_WARNINGS
1851}
1852
1853#endif // SIMDJSON_FASTFLOAT_SSE2
1854
1855// MSVC SFINAE is broken pre-VS2017
1856#if defined(_MSC_VER) && _MSC_VER <= 1900
1857template <typename UC>
1858#else
1859template <typename UC, SIMDJSON_FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>()) = 0>
1860#endif
1861// dummy for compile
1862uint64_t simd_read8_to_u64(UC const *) {
1863 return 0;
1864}
1865
1866// credit @aqrit
1867simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 uint32_t
1868parse_eight_digits_unrolled(uint64_t val) {
1869 uint64_t const mask = 0x000000FF000000FF;
1870 uint64_t const mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
1871 uint64_t const mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
1872 val -= 0x3030303030303030;
1873 val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8;
1874 val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32;
1875 return uint32_t(val);
1876}
1877
1878// Call this if chars are definitely 8 digits.
1879template <typename UC>
1880simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 uint32_t
1881parse_eight_digits_unrolled(UC const *chars) noexcept {
1882 if (cpp20_and_in_constexpr() || !has_simd_opt<UC>()) {
1883 return parse_eight_digits_unrolled(read8_to_u64(chars)); // truncation okay
1884 }
1885 return parse_eight_digits_unrolled(simd_read8_to_u64(chars));
1886}
1887
1888// credit @aqrit
1889simdjson_fastfloat_really_inline constexpr bool
1890is_made_of_eight_digits_fast(uint64_t val) noexcept {
1891 return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) &
1892 0x8080808080808080));
1893}
1894
1895simdjson_fastfloat_really_inline constexpr bool
1896is_made_of_four_digits_fast(uint32_t val) noexcept {
1897 return !((((val + 0x46464646) | (val - 0x30303030)) & 0x80808080));
1898}
1899
1900simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 uint32_t
1901parse_four_digits_unrolled(uint32_t val) noexcept {
1902 val -= 0x30303030;
1903 val = (val * 10) + (val >> 8);
1904 return (((val & 0x00FF00FF) * 0x00640001) >> 16) & 0xFFFF;
1905}
1906
1907#ifdef SIMDJSON_FASTFLOAT_HAS_SIMD
1908
1909// Call this if chars might not be 8 digits.
1910// Using this style (instead of is_made_of_eight_digits_fast() then
1911// parse_eight_digits_unrolled()) ensures we don't load SIMD registers twice.
1912simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 bool
1913simd_parse_if_eight_digits_unrolled(char16_t const *chars,
1914 uint64_t &i) noexcept {
1915 if (cpp20_and_in_constexpr()) {
1916 return false;
1917 }
1918#ifdef SIMDJSON_FASTFLOAT_SSE2
1919 SIMDJSON_FASTFLOAT_SIMD_DISABLE_WARNINGS
1920 __m128i const data =
1921 _mm_loadu_si128(reinterpret_cast<__m128i const *>(chars));
1922
1923 // (x - '0') <= 9
1924 // http://0x80.pl/articles/simd-parsing-int-sequences.html
1925 __m128i const t0 = _mm_add_epi16(data, _mm_set1_epi16(32720));
1926 __m128i const t1 = _mm_cmpgt_epi16(t0, _mm_set1_epi16(-32759));
1927
1928 if (_mm_movemask_epi8(t1) == 0) {
1929 i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data));
1930 return true;
1931 } else
1932 return false;
1933 SIMDJSON_FASTFLOAT_SIMD_RESTORE_WARNINGS
1934#elif defined(SIMDJSON_FASTFLOAT_NEON)
1935 SIMDJSON_FASTFLOAT_SIMD_DISABLE_WARNINGS
1936 uint16x8_t const data = vld1q_u16(reinterpret_cast<uint16_t const *>(chars));
1937
1938 // (x - '0') <= 9
1939 // http://0x80.pl/articles/simd-parsing-int-sequences.html
1940 uint16x8_t const t0 = vsubq_u16(data, vmovq_n_u16('0'));
1941 uint16x8_t const mask = vcltq_u16(t0, vmovq_n_u16('9' - '0' + 1));
1942
1943 if (vminvq_u16(mask) == 0xFFFF) {
1944 i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data));
1945 return true;
1946 } else
1947 return false;
1948 SIMDJSON_FASTFLOAT_SIMD_RESTORE_WARNINGS
1949#else
1950 static_cast<void>(chars);
1951 static_cast<void>(i);
1952 return false;
1953#endif // SIMDJSON_FASTFLOAT_SSE2
1954}
1955
1956#endif // SIMDJSON_FASTFLOAT_HAS_SIMD
1957
1958// MSVC SFINAE is broken pre-VS2017
1959#if defined(_MSC_VER) && _MSC_VER <= 1900
1960template <typename UC>
1961#else
1962template <typename UC, SIMDJSON_FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>()) = 0>
1963#endif
1964// dummy for compile
1965bool simd_parse_if_eight_digits_unrolled(UC const *, uint64_t &) {
1966 return 0;
1967}
1968
1969template <typename UC, SIMDJSON_FASTFLOAT_ENABLE_IF(!std::is_same<UC, char>::value) = 0>
1970simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 void
1971loop_parse_if_eight_digits(UC const *&p, UC const *const pend, uint64_t &i) {
1972 if (!has_simd_opt<UC>()) {
1973 return;
1974 }
1975 while ((std::distance(p, pend) >= 8) &&
1976 simd_parse_if_eight_digits_unrolled(
1977 p, i)) { // in rare cases, this will overflow, but that's ok
1978 p += 8;
1979 }
1980}
1981
1982simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 void
1983loop_parse_if_eight_digits(char const *&p, char const *const pend,
1984 uint64_t &i) {
1985 // optimizes better than parse_if_eight_digits_unrolled() for UC = char.
1986 while ((std::distance(p, pend) >= 8) &&
1987 is_made_of_eight_digits_fast(read8_to_u64(p))) {
1988 i = i * 100000000 +
1989 parse_eight_digits_unrolled(read8_to_u64(
1990 p)); // in rare cases, this will overflow, but that's ok
1991 p += 8;
1992 }
1993 // Consume a remaining 4-7 digit run in a single SWAR step instead of
1994 // byte-by-byte (reuses the existing 4-digit helpers). The parsed result is
1995 // identical either way. Historically gated to clang because gcc regressed on
1996 // short remainders, but that verdict predates the span-elision restructure;
1997 // with the leaner hot path the 4-digit step now wins on gcc as well.
1998 if ((pend - p) >= 4) {
1999 uint32_t const val4 = read4_to_u32(p);
2000 if (is_made_of_four_digits_fast(val4)) {
2001 i = i * 10000 +
2002 parse_four_digits_unrolled(val4); // may overflow, that's ok
2003 p += 4;
2004 }
2005 }
2006}
2007
2008enum class parse_error {
2009 no_error,
2010 // [JSON-only] The minus sign must be followed by an integer.
2011 missing_integer_after_sign,
2012 // A sign must be followed by an integer or dot.
2013 missing_integer_or_dot_after_sign,
2014 // [JSON-only] The integer part must not have leading zeros.
2015 leading_zeros_in_integer_part,
2016 // [JSON-only] The integer part must have at least one digit.
2017 no_digits_in_integer_part,
2018 // [JSON-only] If there is a decimal point, there must be digits in the
2019 // fractional part.
2020 no_digits_in_fractional_part,
2021 // The mantissa must have at least one digit.
2022 no_digits_in_mantissa,
2023 // Scientific notation requires an exponential part.
2024 missing_exponential_part,
2025};
2026
2027template <typename UC> struct parsed_number_string_t {
2028 int64_t exponent{0};
2029 uint64_t mantissa{0};
2030 UC const *lastmatch{nullptr};
2031 bool negative{false};
2032 bool valid{false};
2033 bool too_many_digits{false};
2034 // contains the range of the significant digits
2035 span<UC const> integer{}; // non-nullable
2036 span<UC const> fraction{}; // nullable
2037 parse_error error{parse_error::no_error};
2038};
2039
2042
2043template <typename UC>
2044simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
2045report_parse_error(UC const *p, parse_error error) {
2047 answer.valid = false;
2048 answer.lastmatch = p;
2049 answer.error = error;
2050 return answer;
2051}
2052
2053// Assuming that you use no more than 19 digits, this will
2054// parse an ASCII string.
2055//
2056// store_spans is a *runtime* flag (not a template parameter, deliberately: a
2057// template would create a second instantiation of this whole function and the
2058// extra icache pressure wipes out the gain). When false, the integer/fraction
2059// spans (read only by the rare digit_comp slow path) are not materialized,
2060// which keeps the fat parsed_number_string_t off the hot path. The caller
2061// re-parses with store_spans=true if the slow path is actually reached.
2062template <bool basic_json_fmt, typename UC>
2063simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
2064parse_number_string(UC const *p, UC const *pend, parse_options_t<UC> options,
2065 bool store_spans = true) noexcept {
2066 chars_format const fmt = detail::adjust_for_feature_macros(options.format);
2067 UC const decimal_point = options.decimal_point;
2068
2069 parsed_number_string_t<UC> answer;
2070 answer.valid = false;
2071 answer.too_many_digits = false;
2072 // assume p < pend, so dereference without checks;
2073 answer.negative = (*p == UC('-'));
2074 // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
2075 if ((*p == UC('-')) || (uint64_t(fmt & chars_format::allow_leading_plus) &&
2076 !basic_json_fmt && *p == UC('+'))) {
2077 ++p;
2078 if (p == pend) {
2079 return report_parse_error<UC>(
2080 p, parse_error::missing_integer_or_dot_after_sign);
2081 }
2082 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
2083 if (!is_integer(*p)) { // a sign must be followed by an integer
2084 return report_parse_error<UC>(p,
2085 parse_error::missing_integer_after_sign);
2086 }
2087 }
2088 else {
2089 if (!is_integer(*p) &&
2090 (*p !=
2091 decimal_point)) { // a sign must be followed by an integer or the dot
2092 return report_parse_error<UC>(
2093 p, parse_error::missing_integer_or_dot_after_sign);
2094 }
2095 }
2096 }
2097 UC const *const start_digits = p;
2098
2099 uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad)
2100
2101 // Straight-line unroll of the integer-part scan: most integer parts are
2102 // 1-5 digits, so peeling the first iterations eliminates the loop back-edge
2103 // for the common case. Semantics are identical to the original `while` loop:
2104 // i = 10*i + digit, advancing p.
2105 if ((p != pend) && is_integer(*p)) {
2106 i = uint64_t(*p - UC('0'));
2107 ++p;
2108 if ((p != pend) && is_integer(*p)) {
2109 i = 10 * i + uint64_t(*p - UC('0'));
2110 ++p;
2111 if ((p != pend) && is_integer(*p)) {
2112 i = 10 * i + uint64_t(*p - UC('0'));
2113 ++p;
2114 if ((p != pend) && is_integer(*p)) {
2115 i = 10 * i + uint64_t(*p - UC('0'));
2116 ++p;
2117 if ((p != pend) && is_integer(*p)) {
2118 i = 10 * i + uint64_t(*p - UC('0'));
2119 ++p;
2120 while ((p != pend) && is_integer(*p)) {
2121 // a multiplication by 10 is cheaper than an arbitrary integer
2122 // multiplication
2123 i = 10 * i +
2124 uint64_t(*p - UC('0')); // might overflow, handled later
2125 ++p;
2126 }
2127 }
2128 }
2129 }
2130 }
2131 }
2132 UC const *const end_of_integer_part = p;
2133 int64_t digit_count = int64_t(end_of_integer_part - start_digits);
2134 if (store_spans) {
2135 answer.integer = span<UC const>(start_digits, size_t(digit_count));
2136 }
2137 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
2138 // at least 1 digit in integer part, without leading zeros
2139 if (digit_count == 0) {
2140 return report_parse_error<UC>(p, parse_error::no_digits_in_integer_part);
2141 }
2142 if ((start_digits[0] == UC('0') && digit_count > 1)) {
2143 return report_parse_error<UC>(start_digits,
2144 parse_error::leading_zeros_in_integer_part);
2145 }
2146 }
2147
2148 int64_t exponent = 0;
2149 bool const has_decimal_point = (p != pend) && (*p == decimal_point);
2150 if (has_decimal_point) {
2151 ++p;
2152 UC const *before = p;
2153 // can occur at most twice without overflowing, but let it occur more, since
2154 // for integers with many digits, digit parsing is the primary bottleneck.
2155 loop_parse_if_eight_digits(p, pend, i);
2156
2157 while ((p != pend) && is_integer(*p)) {
2158 uint8_t digit = uint8_t(*p - UC('0'));
2159 ++p;
2160 i = i * 10 + digit; // in rare cases, this will overflow, but that's ok
2161 }
2162 exponent = before - p;
2163 if (store_spans) {
2164 answer.fraction = span<UC const>(before, size_t(p - before));
2165 }
2166 digit_count -= exponent;
2167 }
2168 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
2169 // at least 1 digit in fractional part
2170 if (has_decimal_point && exponent == 0) {
2171 return report_parse_error<UC>(p,
2172 parse_error::no_digits_in_fractional_part);
2173 }
2174 }
2175 else if (digit_count == 0) { // we must have encountered at least one integer!
2176 return report_parse_error<UC>(p, parse_error::no_digits_in_mantissa);
2177 }
2178 int64_t exp_number = 0; // explicit exponential part
2179 if ((uint64_t(fmt & chars_format::scientific) && (p != pend) &&
2180 ((UC('e') == *p) || (UC('E') == *p))) ||
2181 (uint64_t(fmt & detail::basic_fortran_fmt) && (p != pend) &&
2182 ((UC('+') == *p) || (UC('-') == *p) || (UC('d') == *p) ||
2183 (UC('D') == *p)))) {
2184 UC const *location_of_e = p;
2185 if ((UC('e') == *p) || (UC('E') == *p) || (UC('d') == *p) ||
2186 (UC('D') == *p)) {
2187 ++p;
2188 }
2189 bool neg_exp = false;
2190 if ((p != pend) && (UC('-') == *p)) {
2191 neg_exp = true;
2192 ++p;
2193 } else if ((p != pend) &&
2194 (UC('+') ==
2195 *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
2196 ++p;
2197 }
2198 if ((p == pend) || !is_integer(*p)) {
2199 if (!uint64_t(fmt & chars_format::fixed)) {
2200 // The exponential part is invalid for scientific notation, so it must
2201 // be a trailing token for fixed notation. However, fixed notation is
2202 // disabled, so report a scientific notation error.
2203 return report_parse_error<UC>(p, parse_error::missing_exponential_part);
2204 }
2205 // Otherwise, we will be ignoring the 'e'.
2206 p = location_of_e;
2207 } else {
2208 while ((p != pend) && is_integer(*p)) {
2209 uint8_t digit = uint8_t(*p - UC('0'));
2210 if (exp_number < 0x10000000) {
2211 exp_number = 10 * exp_number + digit;
2212 }
2213 ++p;
2214 }
2215 if (neg_exp) {
2216 exp_number = -exp_number;
2217 }
2218 exponent += exp_number;
2219 }
2220 } else {
2221 // If it scientific and not fixed, we have to bail out.
2222 if (uint64_t(fmt & chars_format::scientific) &&
2223 !uint64_t(fmt & chars_format::fixed)) {
2224 return report_parse_error<UC>(p, parse_error::missing_exponential_part);
2225 }
2226 }
2227 answer.lastmatch = p;
2228 answer.valid = true;
2229
2230 // If we frequently had to deal with long strings of digits,
2231 // we could extend our code by using a 128-bit integer instead
2232 // of a 64-bit integer. However, this is uncommon.
2233 //
2234 // We can deal with up to 19 digits.
2235 if (digit_count > 19) { // this is uncommon
2236 // It is possible that the integer had an overflow.
2237 // We have to handle the case where we have 0.0000somenumber.
2238 // We need to be mindful of the case where we only have zeroes...
2239 // E.g., 0.000000000...000.
2240 UC const *start = start_digits;
2241 while ((start != pend) && (*start == UC('0') || *start == decimal_point)) {
2242 if (*start == UC('0')) {
2243 digit_count--;
2244 }
2245 start++;
2246 }
2247
2248 if (digit_count > 19) {
2249 answer.too_many_digits = true;
2250 // The truncation recompute below reads the integer/fraction spans. When
2251 // store_spans is false we didn't materialize them, so just flag
2252 // too_many_digits; the caller re-parses with store_spans=true to obtain
2253 // the corrected mantissa/exponent before taking the slow path.
2254 if (store_spans) {
2255 // Let us start again, this time, avoiding overflows.
2256 // We don't need to call if is_integer, since we use the
2257 // pre-tokenized spans from above.
2258 i = 0;
2259 p = answer.integer.ptr;
2260 UC const *int_end = p + answer.integer.len();
2261 uint64_t const minimal_nineteen_digit_integer{1000000000000000000};
2262 while ((i < minimal_nineteen_digit_integer) && (p != int_end)) {
2263 i = i * 10 + uint64_t(*p - UC('0'));
2264 ++p;
2265 }
2266 if (i >= minimal_nineteen_digit_integer) { // We have a big integer
2267 exponent = end_of_integer_part - p + exp_number;
2268 } else { // We have a value with a fractional component.
2269 p = answer.fraction.ptr;
2270 UC const *frac_end = p + answer.fraction.len();
2271 while ((i < minimal_nineteen_digit_integer) && (p != frac_end)) {
2272 i = i * 10 + uint64_t(*p - UC('0'));
2273 ++p;
2274 }
2275 exponent = answer.fraction.ptr - p + exp_number;
2276 }
2277 // We have now corrected both exponent and i, to a truncated value
2278 }
2279 }
2280 }
2281 answer.exponent = exponent;
2282 answer.mantissa = i;
2283 return answer;
2284}
2285
2286template <typename T, typename UC>
2287simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
2288parse_int_string(UC const *p, UC const *pend, T &value,
2289 parse_options_t<UC> options) {
2290 chars_format const fmt = detail::adjust_for_feature_macros(options.format);
2291 int const base = options.base;
2292
2293 from_chars_result_t<UC> answer;
2294
2295 UC const *const first = p;
2296
2297 bool const negative = (*p == UC('-'));
2298#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
2299#pragma warning(push)
2300#pragma warning(disable : 4127)
2301#endif
2302 if (!std::is_signed<T>::value && negative) {
2303#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
2304#pragma warning(pop)
2305#endif
2306 answer.ec = std::errc::invalid_argument;
2307 answer.ptr = first;
2308 return answer;
2309 }
2310 if ((*p == UC('-')) ||
2311 (uint64_t(fmt & chars_format::allow_leading_plus) && (*p == UC('+')))) {
2312 ++p;
2313 }
2314
2315 UC const *const start_num = p;
2316
2317 while (p != pend && *p == UC('0')) {
2318 ++p;
2319 }
2320
2321 bool const has_leading_zeros = p > start_num;
2322
2323 UC const *const start_digits = p;
2324
2325 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(
2326 (std::is_same<T, std::uint8_t>::value && sizeof(UC) == 1)) {
2327 if (base == 10) {
2328 const size_t len = static_cast<size_t>(pend - p);
2329 if (len == 0) {
2330 if (has_leading_zeros) {
2331 value = 0;
2332 answer.ec = std::errc();
2333 answer.ptr = p;
2334 } else {
2335 answer.ec = std::errc::invalid_argument;
2336 answer.ptr = first;
2337 }
2338 return answer;
2339 }
2340
2341 uint32_t digits;
2342
2343#if SIMDJSON_FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && SIMDJSON_FASTFLOAT_HAS_BIT_CAST
2344 if (std::is_constant_evaluated()) {
2345 uint8_t str[4]{};
2346 for (size_t j = 0; j < 4 && j < len; ++j) {
2347 str[j] = static_cast<uint8_t>(p[j]);
2348 }
2349 digits = std::bit_cast<uint32_t>(str);
2350#if SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN
2351 digits = byteswap_32(digits);
2352#endif
2353 }
2354#else
2355 if (false) {
2356 }
2357#endif
2358 else if (len >= 4) {
2359 ::memcpy(&digits, p, 4);
2360#if SIMDJSON_FASTFLOAT_IS_BIG_ENDIAN
2361 digits = byteswap_32(digits);
2362#endif
2363 } else {
2364 uint32_t b0 = static_cast<uint8_t>(p[0]);
2365 uint32_t b1 = (len > 1) ? static_cast<uint8_t>(p[1]) : 0xFFu;
2366 uint32_t b2 = (len > 2) ? static_cast<uint8_t>(p[2]) : 0xFFu;
2367 uint32_t b3 = 0xFFu;
2368 digits = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
2369 }
2370
2371 uint32_t magic =
2372 ((digits + 0x46464646u) | (digits - 0x30303030u)) & 0x80808080u;
2373 uint32_t tz =
2374 static_cast<uint32_t>(countr_zero_32(magic)); // 7, 15, 23, 31, or 32
2375 uint32_t nd = (tz == 32) ? 4 : (tz >> 3);
2376 nd = static_cast<uint32_t>(nd < len ? nd : len);
2377 if (nd == 0) {
2378 if (has_leading_zeros) {
2379 value = 0;
2380 answer.ec = std::errc();
2381 answer.ptr = p;
2382 return answer;
2383 }
2384 answer.ec = std::errc::invalid_argument;
2385 answer.ptr = first;
2386 return answer;
2387 }
2388 if (nd > 3) {
2389 const UC *q = p + nd;
2390 size_t rem = len - nd;
2391 while (rem) {
2392 if (*q < UC('0') || *q > UC('9'))
2393 break;
2394 ++q;
2395 --rem;
2396 }
2397 answer.ec = std::errc::result_out_of_range;
2398 answer.ptr = q;
2399 return answer;
2400 }
2401
2402 digits ^= 0x30303030u;
2403 digits <<= ((4 - nd) * 8);
2404
2405 uint32_t check = ((digits >> 24) & 0xff) | ((digits >> 8) & 0xff00) |
2406 ((digits << 8) & 0xff0000);
2407 if (check > 0x00020505) {
2408 answer.ec = std::errc::result_out_of_range;
2409 answer.ptr = p + nd;
2410 return answer;
2411 }
2412 value = static_cast<uint8_t>((0x640a01 * digits) >> 24);
2413 answer.ec = std::errc();
2414 answer.ptr = p + nd;
2415 return answer;
2416 }
2417 }
2418
2419 SIMDJSON_FASTFLOAT_IF_CONSTEXPR17(
2420 (std::is_same<T, std::uint16_t>::value && sizeof(UC) == 1)) {
2421 if (base == 10) {
2422 const size_t len = size_t(pend - p);
2423 if (len == 0) {
2424 if (has_leading_zeros) {
2425 value = 0;
2426 answer.ec = std::errc();
2427 answer.ptr = p;
2428 } else {
2429 answer.ec = std::errc::invalid_argument;
2430 answer.ptr = first;
2431 }
2432 return answer;
2433 }
2434
2435 if (len >= 4) {
2436 uint32_t digits = read4_to_u32(p);
2437 if (is_made_of_four_digits_fast(digits)) {
2438 uint32_t v = parse_four_digits_unrolled(digits);
2439 if (len >= 5 && is_integer(p[4])) {
2440 v = v * 10 + uint32_t(p[4] - '0');
2441 if (len >= 6 && is_integer(p[5])) {
2442 answer.ec = std::errc::result_out_of_range;
2443 const UC *q = p + 5;
2444 while (q != pend && is_integer(*q)) {
2445 q++;
2446 }
2447 answer.ptr = q;
2448 return answer;
2449 }
2450 if (v > 65535) {
2451 answer.ec = std::errc::result_out_of_range;
2452 answer.ptr = p + 5;
2453 return answer;
2454 }
2455 value = uint16_t(v);
2456 answer.ec = std::errc();
2457 answer.ptr = p + 5;
2458 return answer;
2459 }
2460 // 4 digits
2461 value = uint16_t(v);
2462 answer.ec = std::errc();
2463 answer.ptr = p + 4;
2464 return answer;
2465 }
2466 }
2467 }
2468 }
2469
2470 uint64_t i = 0;
2471 if (base == 10) {
2472 loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible
2473 }
2474 while (p != pend) {
2475 uint8_t digit = ch_to_digit(*p);
2476 if (digit >= base) {
2477 break;
2478 }
2479 i = uint64_t(base) * i + digit; // might overflow, check this later
2480 p++;
2481 }
2482
2483 size_t digit_count = size_t(p - start_digits);
2484
2485 if (digit_count == 0) {
2486 if (has_leading_zeros) {
2487 value = 0;
2488 answer.ec = std::errc();
2489 answer.ptr = p;
2490 } else {
2491 answer.ec = std::errc::invalid_argument;
2492 answer.ptr = first;
2493 }
2494 return answer;
2495 }
2496
2497 answer.ptr = p;
2498
2499 // check u64 overflow
2500 size_t max_digits = max_digits_u64(base);
2501 if (digit_count > max_digits) {
2502 answer.ec = std::errc::result_out_of_range;
2503 return answer;
2504 }
2505 // this check can be eliminated for all other types, but they will all require
2506 // a max_digits(base) equivalent
2507 if (digit_count == max_digits) {
2508 // At the max_digits boundary the accumulator `i` may have wrapped around
2509 // 2^64. A plain `i < min_safe_u64(base)` test is not sufficient: for any
2510 // base whose max_digits-length range exceeds 2^64 (base 10 reaches
2511 // ~5.4 * 2^64 at 20 digits) the value can wrap a whole multiple of 2^64 and
2512 // land back above min_safe, slipping through. Decide exactly in O(1) using
2513 // the leading digit, following the approach used in simdjson:
2514 // ms == min_safe_u64(base) == base^(max_digits-1), the smallest
2515 // max_digits-length value.
2516 // dmax == the largest leading digit whose number can still fit in u64.
2517 // The leading-digit band [d*ms, (d+1)*ms) has width ms < 2^64, so within
2518 // the single band where d == dmax the value straddles 2^64 at most once,
2519 // and a single threshold separates wrapped from non-wrapped values. A
2520 // leading digit above dmax always overflows; below dmax always fits.
2521 uint64_t const ms = min_safe_u64(base);
2522 uint64_t const dmax = (std::numeric_limits<uint64_t>::max)() / ms;
2523 uint64_t const lead = ch_to_digit(*start_digits);
2524 if (lead > dmax || (lead == dmax && i < dmax * ms)) {
2525 answer.ec = std::errc::result_out_of_range;
2526 return answer;
2527 }
2528 }
2529
2530 // check other types overflow
2531 if (!std::is_same<T, uint64_t>::value) {
2532 if (i > uint64_t((std::numeric_limits<T>::max)()) + uint64_t(negative)) {
2533 answer.ec = std::errc::result_out_of_range;
2534 return answer;
2535 }
2536 }
2537
2538 if (negative) {
2539#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
2540#pragma warning(push)
2541#pragma warning(disable : 4146)
2542#endif
2543 // this weird workaround is required because:
2544 // - converting unsigned to signed when its value is greater than signed max
2545 // is UB pre-C++23.
2546 // - reinterpret_casting (~i + 1) would work, but it is not constexpr
2547 // this is always optimized into a neg instruction (note: T is an integer
2548 // type)
2549 value = T(-(std::numeric_limits<T>::max)() -
2550 T(i - uint64_t((std::numeric_limits<T>::max)())));
2551#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
2552#pragma warning(pop)
2553#endif
2554 } else {
2555 value = T(i);
2556 }
2557
2558 answer.ec = std::errc();
2559 return answer;
2560}
2561
2562} // namespace simdjson_fast_float
2563
2564#endif
2565
2566#ifndef SIMDJSON_FASTFLOAT_FAST_TABLE_H
2567#define SIMDJSON_FASTFLOAT_FAST_TABLE_H
2568
2569#include <cstdint>
2570
2571namespace simdjson_fast_float {
2572
2597template <class unused = void> struct powers_template {
2598
2599 constexpr static int smallest_power_of_five =
2601 constexpr static int largest_power_of_five =
2603 constexpr static int number_of_entries =
2604 2 * (largest_power_of_five - smallest_power_of_five + 1);
2605 // Powers of five from 5^-342 all the way to 5^308 rounded toward one.
2606 constexpr static uint64_t power_of_five_128[number_of_entries] = {
2607 0xeef453d6923bd65a, 0x113faa2906a13b3f,
2608 0x9558b4661b6565f8, 0x4ac7ca59a424c507,
2609 0xbaaee17fa23ebf76, 0x5d79bcf00d2df649,
2610 0xe95a99df8ace6f53, 0xf4d82c2c107973dc,
2611 0x91d8a02bb6c10594, 0x79071b9b8a4be869,
2612 0xb64ec836a47146f9, 0x9748e2826cdee284,
2613 0xe3e27a444d8d98b7, 0xfd1b1b2308169b25,
2614 0x8e6d8c6ab0787f72, 0xfe30f0f5e50e20f7,
2615 0xb208ef855c969f4f, 0xbdbd2d335e51a935,
2616 0xde8b2b66b3bc4723, 0xad2c788035e61382,
2617 0x8b16fb203055ac76, 0x4c3bcb5021afcc31,
2618 0xaddcb9e83c6b1793, 0xdf4abe242a1bbf3d,
2619 0xd953e8624b85dd78, 0xd71d6dad34a2af0d,
2620 0x87d4713d6f33aa6b, 0x8672648c40e5ad68,
2621 0xa9c98d8ccb009506, 0x680efdaf511f18c2,
2622 0xd43bf0effdc0ba48, 0x212bd1b2566def2,
2623 0x84a57695fe98746d, 0x14bb630f7604b57,
2624 0xa5ced43b7e3e9188, 0x419ea3bd35385e2d,
2625 0xcf42894a5dce35ea, 0x52064cac828675b9,
2626 0x818995ce7aa0e1b2, 0x7343efebd1940993,
2627 0xa1ebfb4219491a1f, 0x1014ebe6c5f90bf8,
2628 0xca66fa129f9b60a6, 0xd41a26e077774ef6,
2629 0xfd00b897478238d0, 0x8920b098955522b4,
2630 0x9e20735e8cb16382, 0x55b46e5f5d5535b0,
2631 0xc5a890362fddbc62, 0xeb2189f734aa831d,
2632 0xf712b443bbd52b7b, 0xa5e9ec7501d523e4,
2633 0x9a6bb0aa55653b2d, 0x47b233c92125366e,
2634 0xc1069cd4eabe89f8, 0x999ec0bb696e840a,
2635 0xf148440a256e2c76, 0xc00670ea43ca250d,
2636 0x96cd2a865764dbca, 0x380406926a5e5728,
2637 0xbc807527ed3e12bc, 0xc605083704f5ecf2,
2638 0xeba09271e88d976b, 0xf7864a44c633682e,
2639 0x93445b8731587ea3, 0x7ab3ee6afbe0211d,
2640 0xb8157268fdae9e4c, 0x5960ea05bad82964,
2641 0xe61acf033d1a45df, 0x6fb92487298e33bd,
2642 0x8fd0c16206306bab, 0xa5d3b6d479f8e056,
2643 0xb3c4f1ba87bc8696, 0x8f48a4899877186c,
2644 0xe0b62e2929aba83c, 0x331acdabfe94de87,
2645 0x8c71dcd9ba0b4925, 0x9ff0c08b7f1d0b14,
2646 0xaf8e5410288e1b6f, 0x7ecf0ae5ee44dd9,
2647 0xdb71e91432b1a24a, 0xc9e82cd9f69d6150,
2648 0x892731ac9faf056e, 0xbe311c083a225cd2,
2649 0xab70fe17c79ac6ca, 0x6dbd630a48aaf406,
2650 0xd64d3d9db981787d, 0x92cbbccdad5b108,
2651 0x85f0468293f0eb4e, 0x25bbf56008c58ea5,
2652 0xa76c582338ed2621, 0xaf2af2b80af6f24e,
2653 0xd1476e2c07286faa, 0x1af5af660db4aee1,
2654 0x82cca4db847945ca, 0x50d98d9fc890ed4d,
2655 0xa37fce126597973c, 0xe50ff107bab528a0,
2656 0xcc5fc196fefd7d0c, 0x1e53ed49a96272c8,
2657 0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7a,
2658 0x9faacf3df73609b1, 0x77b191618c54e9ac,
2659 0xc795830d75038c1d, 0xd59df5b9ef6a2417,
2660 0xf97ae3d0d2446f25, 0x4b0573286b44ad1d,
2661 0x9becce62836ac577, 0x4ee367f9430aec32,
2662 0xc2e801fb244576d5, 0x229c41f793cda73f,
2663 0xf3a20279ed56d48a, 0x6b43527578c1110f,
2664 0x9845418c345644d6, 0x830a13896b78aaa9,
2665 0xbe5691ef416bd60c, 0x23cc986bc656d553,
2666 0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa8,
2667 0x94b3a202eb1c3f39, 0x7bf7d71432f3d6a9,
2668 0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc53,
2669 0xe858ad248f5c22c9, 0xd1b3400f8f9cff68,
2670 0x91376c36d99995be, 0x23100809b9c21fa1,
2671 0xb58547448ffffb2d, 0xabd40a0c2832a78a,
2672 0xe2e69915b3fff9f9, 0x16c90c8f323f516c,
2673 0x8dd01fad907ffc3b, 0xae3da7d97f6792e3,
2674 0xb1442798f49ffb4a, 0x99cd11cfdf41779c,
2675 0xdd95317f31c7fa1d, 0x40405643d711d583,
2676 0x8a7d3eef7f1cfc52, 0x482835ea666b2572,
2677 0xad1c8eab5ee43b66, 0xda3243650005eecf,
2678 0xd863b256369d4a40, 0x90bed43e40076a82,
2679 0x873e4f75e2224e68, 0x5a7744a6e804a291,
2680 0xa90de3535aaae202, 0x711515d0a205cb36,
2681 0xd3515c2831559a83, 0xd5a5b44ca873e03,
2682 0x8412d9991ed58091, 0xe858790afe9486c2,
2683 0xa5178fff668ae0b6, 0x626e974dbe39a872,
2684 0xce5d73ff402d98e3, 0xfb0a3d212dc8128f,
2685 0x80fa687f881c7f8e, 0x7ce66634bc9d0b99,
2686 0xa139029f6a239f72, 0x1c1fffc1ebc44e80,
2687 0xc987434744ac874e, 0xa327ffb266b56220,
2688 0xfbe9141915d7a922, 0x4bf1ff9f0062baa8,
2689 0x9d71ac8fada6c9b5, 0x6f773fc3603db4a9,
2690 0xc4ce17b399107c22, 0xcb550fb4384d21d3,
2691 0xf6019da07f549b2b, 0x7e2a53a146606a48,
2692 0x99c102844f94e0fb, 0x2eda7444cbfc426d,
2693 0xc0314325637a1939, 0xfa911155fefb5308,
2694 0xf03d93eebc589f88, 0x793555ab7eba27ca,
2695 0x96267c7535b763b5, 0x4bc1558b2f3458de,
2696 0xbbb01b9283253ca2, 0x9eb1aaedfb016f16,
2697 0xea9c227723ee8bcb, 0x465e15a979c1cadc,
2698 0x92a1958a7675175f, 0xbfacd89ec191ec9,
2699 0xb749faed14125d36, 0xcef980ec671f667b,
2700 0xe51c79a85916f484, 0x82b7e12780e7401a,
2701 0x8f31cc0937ae58d2, 0xd1b2ecb8b0908810,
2702 0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa15,
2703 0xdfbdcece67006ac9, 0x67a791e093e1d49a,
2704 0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e0,
2705 0xaecc49914078536d, 0x58fae9f773886e18,
2706 0xda7f5bf590966848, 0xaf39a475506a899e,
2707 0x888f99797a5e012d, 0x6d8406c952429603,
2708 0xaab37fd7d8f58178, 0xc8e5087ba6d33b83,
2709 0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a64,
2710 0x855c3be0a17fcd26, 0x5cf2eea09a55067f,
2711 0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481e,
2712 0xd0601d8efc57b08b, 0xf13b94daf124da26,
2713 0x823c12795db6ce57, 0x76c53d08d6b70858,
2714 0xa2cb1717b52481ed, 0x54768c4b0c64ca6e,
2715 0xcb7ddcdda26da268, 0xa9942f5dcf7dfd09,
2716 0xfe5d54150b090b02, 0xd3f93b35435d7c4c,
2717 0x9efa548d26e5a6e1, 0xc47bc5014a1a6daf,
2718 0xc6b8e9b0709f109a, 0x359ab6419ca1091b,
2719 0xf867241c8cc6d4c0, 0xc30163d203c94b62,
2720 0x9b407691d7fc44f8, 0x79e0de63425dcf1d,
2721 0xc21094364dfb5636, 0x985915fc12f542e4,
2722 0xf294b943e17a2bc4, 0x3e6f5b7b17b2939d,
2723 0x979cf3ca6cec5b5a, 0xa705992ceecf9c42,
2724 0xbd8430bd08277231, 0x50c6ff782a838353,
2725 0xece53cec4a314ebd, 0xa4f8bf5635246428,
2726 0x940f4613ae5ed136, 0x871b7795e136be99,
2727 0xb913179899f68584, 0x28e2557b59846e3f,
2728 0xe757dd7ec07426e5, 0x331aeada2fe589cf,
2729 0x9096ea6f3848984f, 0x3ff0d2c85def7621,
2730 0xb4bca50b065abe63, 0xfed077a756b53a9,
2731 0xe1ebce4dc7f16dfb, 0xd3e8495912c62894,
2732 0x8d3360f09cf6e4bd, 0x64712dd7abbbd95c,
2733 0xb080392cc4349dec, 0xbd8d794d96aacfb3,
2734 0xdca04777f541c567, 0xecf0d7a0fc5583a0,
2735 0x89e42caaf9491b60, 0xf41686c49db57244,
2736 0xac5d37d5b79b6239, 0x311c2875c522ced5,
2737 0xd77485cb25823ac7, 0x7d633293366b828b,
2738 0x86a8d39ef77164bc, 0xae5dff9c02033197,
2739 0xa8530886b54dbdeb, 0xd9f57f830283fdfc,
2740 0xd267caa862a12d66, 0xd072df63c324fd7b,
2741 0x8380dea93da4bc60, 0x4247cb9e59f71e6d,
2742 0xa46116538d0deb78, 0x52d9be85f074e608,
2743 0xcd795be870516656, 0x67902e276c921f8b,
2744 0x806bd9714632dff6, 0xba1cd8a3db53b6,
2745 0xa086cfcd97bf97f3, 0x80e8a40eccd228a4,
2746 0xc8a883c0fdaf7df0, 0x6122cd128006b2cd,
2747 0xfad2a4b13d1b5d6c, 0x796b805720085f81,
2748 0x9cc3a6eec6311a63, 0xcbe3303674053bb0,
2749 0xc3f490aa77bd60fc, 0xbedbfc4411068a9c,
2750 0xf4f1b4d515acb93b, 0xee92fb5515482d44,
2751 0x991711052d8bf3c5, 0x751bdd152d4d1c4a,
2752 0xbf5cd54678eef0b6, 0xd262d45a78a0635d,
2753 0xef340a98172aace4, 0x86fb897116c87c34,
2754 0x9580869f0e7aac0e, 0xd45d35e6ae3d4da0,
2755 0xbae0a846d2195712, 0x8974836059cca109,
2756 0xe998d258869facd7, 0x2bd1a438703fc94b,
2757 0x91ff83775423cc06, 0x7b6306a34627ddcf,
2758 0xb67f6455292cbf08, 0x1a3bc84c17b1d542,
2759 0xe41f3d6a7377eeca, 0x20caba5f1d9e4a93,
2760 0x8e938662882af53e, 0x547eb47b7282ee9c,
2761 0xb23867fb2a35b28d, 0xe99e619a4f23aa43,
2762 0xdec681f9f4c31f31, 0x6405fa00e2ec94d4,
2763 0x8b3c113c38f9f37e, 0xde83bc408dd3dd04,
2764 0xae0b158b4738705e, 0x9624ab50b148d445,
2765 0xd98ddaee19068c76, 0x3badd624dd9b0957,
2766 0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d6,
2767 0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4c,
2768 0xd47487cc8470652b, 0x7647c3200069671f,
2769 0x84c8d4dfd2c63f3b, 0x29ecd9f40041e073,
2770 0xa5fb0a17c777cf09, 0xf468107100525890,
2771 0xcf79cc9db955c2cc, 0x7182148d4066eeb4,
2772 0x81ac1fe293d599bf, 0xc6f14cd848405530,
2773 0xa21727db38cb002f, 0xb8ada00e5a506a7c,
2774 0xca9cf1d206fdc03b, 0xa6d90811f0e4851c,
2775 0xfd442e4688bd304a, 0x908f4a166d1da663,
2776 0x9e4a9cec15763e2e, 0x9a598e4e043287fe,
2777 0xc5dd44271ad3cdba, 0x40eff1e1853f29fd,
2778 0xf7549530e188c128, 0xd12bee59e68ef47c,
2779 0x9a94dd3e8cf578b9, 0x82bb74f8301958ce,
2780 0xc13a148e3032d6e7, 0xe36a52363c1faf01,
2781 0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac1,
2782 0x96f5600f15a7b7e5, 0x29ab103a5ef8c0b9,
2783 0xbcb2b812db11a5de, 0x7415d448f6b6f0e7,
2784 0xebdf661791d60f56, 0x111b495b3464ad21,
2785 0x936b9fcebb25c995, 0xcab10dd900beec34,
2786 0xb84687c269ef3bfb, 0x3d5d514f40eea742,
2787 0xe65829b3046b0afa, 0xcb4a5a3112a5112,
2788 0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ab,
2789 0xb3f4e093db73a093, 0x59ed216765690f56,
2790 0xe0f218b8d25088b8, 0x306869c13ec3532c,
2791 0x8c974f7383725573, 0x1e414218c73a13fb,
2792 0xafbd2350644eeacf, 0xe5d1929ef90898fa,
2793 0xdbac6c247d62a583, 0xdf45f746b74abf39,
2794 0x894bc396ce5da772, 0x6b8bba8c328eb783,
2795 0xab9eb47c81f5114f, 0x66ea92f3f326564,
2796 0xd686619ba27255a2, 0xc80a537b0efefebd,
2797 0x8613fd0145877585, 0xbd06742ce95f5f36,
2798 0xa798fc4196e952e7, 0x2c48113823b73704,
2799 0xd17f3b51fca3a7a0, 0xf75a15862ca504c5,
2800 0x82ef85133de648c4, 0x9a984d73dbe722fb,
2801 0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebba,
2802 0xcc963fee10b7d1b3, 0x318df905079926a8,
2803 0xffbbcfe994e5c61f, 0xfdf17746497f7052,
2804 0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa633,
2805 0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc0,
2806 0xf9bd690a1b68637b, 0x3dfdce7aa3c673b0,
2807 0x9c1661a651213e2d, 0x6bea10ca65c084e,
2808 0xc31bfa0fe5698db8, 0x486e494fcff30a62,
2809 0xf3e2f893dec3f126, 0x5a89dba3c3efccfa,
2810 0x986ddb5c6b3a76b7, 0xf89629465a75e01c,
2811 0xbe89523386091465, 0xf6bbb397f1135823,
2812 0xee2ba6c0678b597f, 0x746aa07ded582e2c,
2813 0x94db483840b717ef, 0xa8c2a44eb4571cdc,
2814 0xba121a4650e4ddeb, 0x92f34d62616ce413,
2815 0xe896a0d7e51e1566, 0x77b020baf9c81d17,
2816 0x915e2486ef32cd60, 0xace1474dc1d122e,
2817 0xb5b5ada8aaff80b8, 0xd819992132456ba,
2818 0xe3231912d5bf60e6, 0x10e1fff697ed6c69,
2819 0x8df5efabc5979c8f, 0xca8d3ffa1ef463c1,
2820 0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb2,
2821 0xddd0467c64bce4a0, 0xac7cb3f6d05ddbde,
2822 0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96b,
2823 0xad4ab7112eb3929d, 0x86c16c98d2c953c6,
2824 0xd89d64d57a607744, 0xe871c7bf077ba8b7,
2825 0x87625f056c7c4a8b, 0x11471cd764ad4972,
2826 0xa93af6c6c79b5d2d, 0xd598e40d3dd89bcf,
2827 0xd389b47879823479, 0x4aff1d108d4ec2c3,
2828 0x843610cb4bf160cb, 0xcedf722a585139ba,
2829 0xa54394fe1eedb8fe, 0xc2974eb4ee658828,
2830 0xce947a3da6a9273e, 0x733d226229feea32,
2831 0x811ccc668829b887, 0x806357d5a3f525f,
2832 0xa163ff802a3426a8, 0xca07c2dcb0cf26f7,
2833 0xc9bcff6034c13052, 0xfc89b393dd02f0b5,
2834 0xfc2c3f3841f17c67, 0xbbac2078d443ace2,
2835 0x9d9ba7832936edc0, 0xd54b944b84aa4c0d,
2836 0xc5029163f384a931, 0xa9e795e65d4df11,
2837 0xf64335bcf065d37d, 0x4d4617b5ff4a16d5,
2838 0x99ea0196163fa42e, 0x504bced1bf8e4e45,
2839 0xc06481fb9bcf8d39, 0xe45ec2862f71e1d6,
2840 0xf07da27a82c37088, 0x5d767327bb4e5a4c,
2841 0x964e858c91ba2655, 0x3a6a07f8d510f86f,
2842 0xbbe226efb628afea, 0x890489f70a55368b,
2843 0xeadab0aba3b2dbe5, 0x2b45ac74ccea842e,
2844 0x92c8ae6b464fc96f, 0x3b0b8bc90012929d,
2845 0xb77ada0617e3bbcb, 0x9ce6ebb40173744,
2846 0xe55990879ddcaabd, 0xcc420a6a101d0515,
2847 0x8f57fa54c2a9eab6, 0x9fa946824a12232d,
2848 0xb32df8e9f3546564, 0x47939822dc96abf9,
2849 0xdff9772470297ebd, 0x59787e2b93bc56f7,
2850 0x8bfbea76c619ef36, 0x57eb4edb3c55b65a,
2851 0xaefae51477a06b03, 0xede622920b6b23f1,
2852 0xdab99e59958885c4, 0xe95fab368e45eced,
2853 0x88b402f7fd75539b, 0x11dbcb0218ebb414,
2854 0xaae103b5fcd2a881, 0xd652bdc29f26a119,
2855 0xd59944a37c0752a2, 0x4be76d3346f0495f,
2856 0x857fcae62d8493a5, 0x6f70a4400c562ddb,
2857 0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb952,
2858 0xd097ad07a71f26b2, 0x7e2000a41346a7a7,
2859 0x825ecc24c873782f, 0x8ed400668c0c28c8,
2860 0xa2f67f2dfa90563b, 0x728900802f0f32fa,
2861 0xcbb41ef979346bca, 0x4f2b40a03ad2ffb9,
2862 0xfea126b7d78186bc, 0xe2f610c84987bfa8,
2863 0x9f24b832e6b0f436, 0xdd9ca7d2df4d7c9,
2864 0xc6ede63fa05d3143, 0x91503d1c79720dbb,
2865 0xf8a95fcf88747d94, 0x75a44c6397ce912a,
2866 0x9b69dbe1b548ce7c, 0xc986afbe3ee11aba,
2867 0xc24452da229b021b, 0xfbe85badce996168,
2868 0xf2d56790ab41c2a2, 0xfae27299423fb9c3,
2869 0x97c560ba6b0919a5, 0xdccd879fc967d41a,
2870 0xbdb6b8e905cb600f, 0x5400e987bbc1c920,
2871 0xed246723473e3813, 0x290123e9aab23b68,
2872 0x9436c0760c86e30b, 0xf9a0b6720aaf6521,
2873 0xb94470938fa89bce, 0xf808e40e8d5b3e69,
2874 0xe7958cb87392c2c2, 0xb60b1d1230b20e04,
2875 0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c2,
2876 0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af3,
2877 0xe2280b6c20dd5232, 0x25c6da63c38de1b0,
2878 0x8d590723948a535f, 0x579c487e5a38ad0e,
2879 0xb0af48ec79ace837, 0x2d835a9df0c6d851,
2880 0xdcdb1b2798182244, 0xf8e431456cf88e65,
2881 0x8a08f0f8bf0f156b, 0x1b8e9ecb641b58ff,
2882 0xac8b2d36eed2dac5, 0xe272467e3d222f3f,
2883 0xd7adf884aa879177, 0x5b0ed81dcc6abb0f,
2884 0x86ccbb52ea94baea, 0x98e947129fc2b4e9,
2885 0xa87fea27a539e9a5, 0x3f2398d747b36224,
2886 0xd29fe4b18e88640e, 0x8eec7f0d19a03aad,
2887 0x83a3eeeef9153e89, 0x1953cf68300424ac,
2888 0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd7,
2889 0xcdb02555653131b6, 0x3792f412cb06794d,
2890 0x808e17555f3ebf11, 0xe2bbd88bbee40bd0,
2891 0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec4,
2892 0xc8de047564d20a8b, 0xf245825a5a445275,
2893 0xfb158592be068d2e, 0xeed6e2f0f0d56712,
2894 0x9ced737bb6c4183d, 0x55464dd69685606b,
2895 0xc428d05aa4751e4c, 0xaa97e14c3c26b886,
2896 0xf53304714d9265df, 0xd53dd99f4b3066a8,
2897 0x993fe2c6d07b7fab, 0xe546a8038efe4029,
2898 0xbf8fdb78849a5f96, 0xde98520472bdd033,
2899 0xef73d256a5c0f77c, 0x963e66858f6d4440,
2900 0x95a8637627989aad, 0xdde7001379a44aa8,
2901 0xbb127c53b17ec159, 0x5560c018580d5d52,
2902 0xe9d71b689dde71af, 0xaab8f01e6e10b4a6,
2903 0x9226712162ab070d, 0xcab3961304ca70e8,
2904 0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d22,
2905 0xe45c10c42a2b3b05, 0x8cb89a7db77c506a,
2906 0x8eb98a7a9a5b04e3, 0x77f3608e92adb242,
2907 0xb267ed1940f1c61c, 0x55f038b237591ed3,
2908 0xdf01e85f912e37a3, 0x6b6c46dec52f6688,
2909 0x8b61313bbabce2c6, 0x2323ac4b3b3da015,
2910 0xae397d8aa96c1b77, 0xabec975e0a0d081a,
2911 0xd9c7dced53c72255, 0x96e7bd358c904a21,
2912 0x881cea14545c7575, 0x7e50d64177da2e54,
2913 0xaa242499697392d2, 0xdde50bd1d5d0b9e9,
2914 0xd4ad2dbfc3d07787, 0x955e4ec64b44e864,
2915 0x84ec3c97da624ab4, 0xbd5af13bef0b113e,
2916 0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58e,
2917 0xcfb11ead453994ba, 0x67de18eda5814af2,
2918 0x81ceb32c4b43fcf4, 0x80eacf948770ced7,
2919 0xa2425ff75e14fc31, 0xa1258379a94d028d,
2920 0xcad2f7f5359a3b3e, 0x96ee45813a04330,
2921 0xfd87b5f28300ca0d, 0x8bca9d6e188853fc,
2922 0x9e74d1b791e07e48, 0x775ea264cf55347e,
2923 0xc612062576589dda, 0x95364afe032a819e,
2924 0xf79687aed3eec551, 0x3a83ddbd83f52205,
2925 0x9abe14cd44753b52, 0xc4926a9672793543,
2926 0xc16d9a0095928a27, 0x75b7053c0f178294,
2927 0xf1c90080baf72cb1, 0x5324c68b12dd6339,
2928 0x971da05074da7bee, 0xd3f6fc16ebca5e04,
2929 0xbce5086492111aea, 0x88f4bb1ca6bcf585,
2930 0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6,
2931 0x9392ee8e921d5d07, 0x3aff322e62439fd0,
2932 0xb877aa3236a4b449, 0x9befeb9fad487c3,
2933 0xe69594bec44de15b, 0x4c2ebe687989a9b4,
2934 0x901d7cf73ab0acd9, 0xf9d37014bf60a11,
2935 0xb424dc35095cd80f, 0x538484c19ef38c95,
2936 0xe12e13424bb40e13, 0x2865a5f206b06fba,
2937 0x8cbccc096f5088cb, 0xf93f87b7442e45d4,
2938 0xafebff0bcb24aafe, 0xf78f69a51539d749,
2939 0xdbe6fecebdedd5be, 0xb573440e5a884d1c,
2940 0x89705f4136b4a597, 0x31680a88f8953031,
2941 0xabcc77118461cefc, 0xfdc20d2b36ba7c3e,
2942 0xd6bf94d5e57a42bc, 0x3d32907604691b4d,
2943 0x8637bd05af6c69b5, 0xa63f9a49c2c1b110,
2944 0xa7c5ac471b478423, 0xfcf80dc33721d54,
2945 0xd1b71758e219652b, 0xd3c36113404ea4a9,
2946 0x83126e978d4fdf3b, 0x645a1cac083126ea,
2947 0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4,
2948 0xcccccccccccccccc, 0xcccccccccccccccd,
2949 0x8000000000000000, 0x0,
2950 0xa000000000000000, 0x0,
2951 0xc800000000000000, 0x0,
2952 0xfa00000000000000, 0x0,
2953 0x9c40000000000000, 0x0,
2954 0xc350000000000000, 0x0,
2955 0xf424000000000000, 0x0,
2956 0x9896800000000000, 0x0,
2957 0xbebc200000000000, 0x0,
2958 0xee6b280000000000, 0x0,
2959 0x9502f90000000000, 0x0,
2960 0xba43b74000000000, 0x0,
2961 0xe8d4a51000000000, 0x0,
2962 0x9184e72a00000000, 0x0,
2963 0xb5e620f480000000, 0x0,
2964 0xe35fa931a0000000, 0x0,
2965 0x8e1bc9bf04000000, 0x0,
2966 0xb1a2bc2ec5000000, 0x0,
2967 0xde0b6b3a76400000, 0x0,
2968 0x8ac7230489e80000, 0x0,
2969 0xad78ebc5ac620000, 0x0,
2970 0xd8d726b7177a8000, 0x0,
2971 0x878678326eac9000, 0x0,
2972 0xa968163f0a57b400, 0x0,
2973 0xd3c21bcecceda100, 0x0,
2974 0x84595161401484a0, 0x0,
2975 0xa56fa5b99019a5c8, 0x0,
2976 0xcecb8f27f4200f3a, 0x0,
2977 0x813f3978f8940984, 0x4000000000000000,
2978 0xa18f07d736b90be5, 0x5000000000000000,
2979 0xc9f2c9cd04674ede, 0xa400000000000000,
2980 0xfc6f7c4045812296, 0x4d00000000000000,
2981 0x9dc5ada82b70b59d, 0xf020000000000000,
2982 0xc5371912364ce305, 0x6c28000000000000,
2983 0xf684df56c3e01bc6, 0xc732000000000000,
2984 0x9a130b963a6c115c, 0x3c7f400000000000,
2985 0xc097ce7bc90715b3, 0x4b9f100000000000,
2986 0xf0bdc21abb48db20, 0x1e86d40000000000,
2987 0x96769950b50d88f4, 0x1314448000000000,
2988 0xbc143fa4e250eb31, 0x17d955a000000000,
2989 0xeb194f8e1ae525fd, 0x5dcfab0800000000,
2990 0x92efd1b8d0cf37be, 0x5aa1cae500000000,
2991 0xb7abc627050305ad, 0xf14a3d9e40000000,
2992 0xe596b7b0c643c719, 0x6d9ccd05d0000000,
2993 0x8f7e32ce7bea5c6f, 0xe4820023a2000000,
2994 0xb35dbf821ae4f38b, 0xdda2802c8a800000,
2995 0xe0352f62a19e306e, 0xd50b2037ad200000,
2996 0x8c213d9da502de45, 0x4526f422cc340000,
2997 0xaf298d050e4395d6, 0x9670b12b7f410000,
2998 0xdaf3f04651d47b4c, 0x3c0cdd765f114000,
2999 0x88d8762bf324cd0f, 0xa5880a69fb6ac800,
3000 0xab0e93b6efee0053, 0x8eea0d047a457a00,
3001 0xd5d238a4abe98068, 0x72a4904598d6d880,
3002 0x85a36366eb71f041, 0x47a6da2b7f864750,
3003 0xa70c3c40a64e6c51, 0x999090b65f67d924,
3004 0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d,
3005 0x82818f1281ed449f, 0xbff8f10e7a8921a4,
3006 0xa321f2d7226895c7, 0xaff72d52192b6a0d,
3007 0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490,
3008 0xfee50b7025c36a08, 0x2f236d04753d5b4,
3009 0x9f4f2726179a2245, 0x1d762422c946590,
3010 0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5,
3011 0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2,
3012 0x9b934c3b330c8577, 0x63cc55f49f88eb2f,
3013 0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb,
3014 0xf316271c7fc3908a, 0x8bef464e3945ef7a,
3015 0x97edd871cfda3a56, 0x97758bf0e3cbb5ac,
3016 0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317,
3017 0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd,
3018 0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a,
3019 0xb975d6b6ee39e436, 0xb3e2fd538e122b44,
3020 0xe7d34c64a9c85d44, 0x60dbbca87196b616,
3021 0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd,
3022 0xb51d13aea4a488dd, 0x6babab6398bdbe41,
3023 0xe264589a4dcdab14, 0xc696963c7eed2dd1,
3024 0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2,
3025 0xb0de65388cc8ada8, 0x3b25a55f43294bcb,
3026 0xdd15fe86affad912, 0x49ef0eb713f39ebe,
3027 0x8a2dbf142dfcc7ab, 0x6e3569326c784337,
3028 0xacb92ed9397bf996, 0x49c2c37f07965404,
3029 0xd7e77a8f87daf7fb, 0xdc33745ec97be906,
3030 0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3,
3031 0xa8acd7c0222311bc, 0xc40832ea0d68ce0c,
3032 0xd2d80db02aabd62b, 0xf50a3fa490c30190,
3033 0x83c7088e1aab65db, 0x792667c6da79e0fa,
3034 0xa4b8cab1a1563f52, 0x577001b891185938,
3035 0xcde6fd5e09abcf26, 0xed4c0226b55e6f86,
3036 0x80b05e5ac60b6178, 0x544f8158315b05b4,
3037 0xa0dc75f1778e39d6, 0x696361ae3db1c721,
3038 0xc913936dd571c84c, 0x3bc3a19cd1e38e9,
3039 0xfb5878494ace3a5f, 0x4ab48a04065c723,
3040 0x9d174b2dcec0e47b, 0x62eb0d64283f9c76,
3041 0xc45d1df942711d9a, 0x3ba5d0bd324f8394,
3042 0xf5746577930d6500, 0xca8f44ec7ee36479,
3043 0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb,
3044 0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e,
3045 0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e,
3046 0x95d04aee3b80ece5, 0xbba1f1d158724a12,
3047 0xbb445da9ca61281f, 0x2a8a6e45ae8edc97,
3048 0xea1575143cf97226, 0xf52d09d71a3293bd,
3049 0x924d692ca61be758, 0x593c2626705f9c56,
3050 0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c,
3051 0xe498f455c38b997a, 0xb6dfb9c0f956447,
3052 0x8edf98b59a373fec, 0x4724bd4189bd5eac,
3053 0xb2977ee300c50fe7, 0x58edec91ec2cb657,
3054 0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed,
3055 0x8b865b215899f46c, 0xbd79e0d20082ee74,
3056 0xae67f1e9aec07187, 0xecd8590680a3aa11,
3057 0xda01ee641a708de9, 0xe80e6f4820cc9495,
3058 0x884134fe908658b2, 0x3109058d147fdcdd,
3059 0xaa51823e34a7eede, 0xbd4b46f0599fd415,
3060 0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a,
3061 0x850fadc09923329e, 0x3e2cf6bc604ddb0,
3062 0xa6539930bf6bff45, 0x84db8346b786151c,
3063 0xcfe87f7cef46ff16, 0xe612641865679a63,
3064 0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e,
3065 0xa26da3999aef7749, 0xe3be5e330f38f09d,
3066 0xcb090c8001ab551c, 0x5cadf5bfd3072cc5,
3067 0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6,
3068 0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa,
3069 0xc646d63501a1511d, 0xb281e1fd541501b8,
3070 0xf7d88bc24209a565, 0x1f225a7ca91a4226,
3071 0x9ae757596946075f, 0x3375788de9b06958,
3072 0xc1a12d2fc3978937, 0x52d6b1641c83ae,
3073 0xf209787bb47d6b84, 0xc0678c5dbd23a49a,
3074 0x9745eb4d50ce6332, 0xf840b7ba963646e0,
3075 0xbd176620a501fbff, 0xb650e5a93bc3d898,
3076 0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe,
3077 0x93ba47c980e98cdf, 0xc66f336c36b10137,
3078 0xb8a8d9bbe123f017, 0xb80b0047445d4184,
3079 0xe6d3102ad96cec1d, 0xa60dc059157491e5,
3080 0x9043ea1ac7e41392, 0x87c89837ad68db2f,
3081 0xb454e4a179dd1877, 0x29babe4598c311fb,
3082 0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a,
3083 0x8ce2529e2734bb1d, 0x1899e4a65f58660c,
3084 0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f,
3085 0xdc21a1171d42645d, 0x76707543f4fa1f73,
3086 0x899504ae72497eba, 0x6a06494a791c53a8,
3087 0xabfa45da0edbde69, 0x487db9d17636892,
3088 0xd6f8d7509292d603, 0x45a9d2845d3c42b6,
3089 0x865b86925b9bc5c2, 0xb8a2392ba45a9b2,
3090 0xa7f26836f282b732, 0x8e6cac7768d7141e,
3091 0xd1ef0244af2364ff, 0x3207d795430cd926,
3092 0x8335616aed761f1f, 0x7f44e6bd49e807b8,
3093 0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6,
3094 0xcd036837130890a1, 0x36dba887c37a8c0f,
3095 0x802221226be55a64, 0xc2494954da2c9789,
3096 0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c,
3097 0xc83553c5c8965d3d, 0x6f92829494e5acc7,
3098 0xfa42a8b73abbf48c, 0xcb772339ba1f17f9,
3099 0x9c69a97284b578d7, 0xff2a760414536efb,
3100 0xc38413cf25e2d70d, 0xfef5138519684aba,
3101 0xf46518c2ef5b8cd1, 0x7eb258665fc25d69,
3102 0x98bf2f79d5993802, 0xef2f773ffbd97a61,
3103 0xbeeefb584aff8603, 0xaafb550ffacfd8fa,
3104 0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38,
3105 0x952ab45cfa97a0b2, 0xdd945a747bf26183,
3106 0xba756174393d88df, 0x94f971119aeef9e4,
3107 0xe912b9d1478ceb17, 0x7a37cd5601aab85d,
3108 0x91abb422ccb812ee, 0xac62e055c10ab33a,
3109 0xb616a12b7fe617aa, 0x577b986b314d6009,
3110 0xe39c49765fdf9d94, 0xed5a7e85fda0b80b,
3111 0x8e41ade9fbebc27d, 0x14588f13be847307,
3112 0xb1d219647ae6b31c, 0x596eb2d8ae258fc8,
3113 0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb,
3114 0x8aec23d680043bee, 0x25de7bb9480d5854,
3115 0xada72ccc20054ae9, 0xaf561aa79a10ae6a,
3116 0xd910f7ff28069da4, 0x1b2ba1518094da04,
3117 0x87aa9aff79042286, 0x90fb44d2f05d0842,
3118 0xa99541bf57452b28, 0x353a1607ac744a53,
3119 0xd3fa922f2d1675f2, 0x42889b8997915ce8,
3120 0x847c9b5d7c2e09b7, 0x69956135febada11,
3121 0xa59bc234db398c25, 0x43fab9837e699095,
3122 0xcf02b2c21207ef2e, 0x94f967e45e03f4bb,
3123 0x8161afb94b44f57d, 0x1d1be0eebac278f5,
3124 0xa1ba1ba79e1632dc, 0x6462d92a69731732,
3125 0xca28a291859bbf93, 0x7d7b8f7503cfdcfe,
3126 0xfcb2cb35e702af78, 0x5cda735244c3d43e,
3127 0x9defbf01b061adab, 0x3a0888136afa64a7,
3128 0xc56baec21c7a1916, 0x88aaa1845b8fdd0,
3129 0xf6c69a72a3989f5b, 0x8aad549e57273d45,
3130 0x9a3c2087a63f6399, 0x36ac54e2f678864b,
3131 0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd,
3132 0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5,
3133 0x969eb7c47859e743, 0x9f644ae5a4b1b325,
3134 0xbc4665b596706114, 0x873d5d9f0dde1fee,
3135 0xeb57ff22fc0c7959, 0xa90cb506d155a7ea,
3136 0x9316ff75dd87cbd8, 0x9a7f12442d588f2,
3137 0xb7dcbf5354e9bece, 0xc11ed6d538aeb2f,
3138 0xe5d3ef282a242e81, 0x8f1668c8a86da5fa,
3139 0x8fa475791a569d10, 0xf96e017d694487bc,
3140 0xb38d92d760ec4455, 0x37c981dcc395a9ac,
3141 0xe070f78d3927556a, 0x85bbe253f47b1417,
3142 0x8c469ab843b89562, 0x93956d7478ccec8e,
3143 0xaf58416654a6babb, 0x387ac8d1970027b2,
3144 0xdb2e51bfe9d0696a, 0x6997b05fcc0319e,
3145 0x88fcf317f22241e2, 0x441fece3bdf81f03,
3146 0xab3c2fddeeaad25a, 0xd527e81cad7626c3,
3147 0xd60b3bd56a5586f1, 0x8a71e223d8d3b074,
3148 0x85c7056562757456, 0xf6872d5667844e49,
3149 0xa738c6bebb12d16c, 0xb428f8ac016561db,
3150 0xd106f86e69d785c7, 0xe13336d701beba52,
3151 0x82a45b450226b39c, 0xecc0024661173473,
3152 0xa34d721642b06084, 0x27f002d7f95d0190,
3153 0xcc20ce9bd35c78a5, 0x31ec038df7b441f4,
3154 0xff290242c83396ce, 0x7e67047175a15271,
3155 0x9f79a169bd203e41, 0xf0062c6e984d386,
3156 0xc75809c42c684dd1, 0x52c07b78a3e60868,
3157 0xf92e0c3537826145, 0xa7709a56ccdf8a82,
3158 0x9bbcc7a142b17ccb, 0x88a66076400bb691,
3159 0xc2abf989935ddbfe, 0x6acff893d00ea435,
3160 0xf356f7ebf83552fe, 0x583f6b8c4124d43,
3161 0x98165af37b2153de, 0xc3727a337a8b704a,
3162 0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c,
3163 0xeda2ee1c7064130c, 0x1162def06f79df73,
3164 0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8,
3165 0xb9a74a0637ce2ee1, 0x6d953e2bd7173692,
3166 0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437,
3167 0x910ab1d4db9914a0, 0x1d9c9892400a22a2,
3168 0xb54d5e4a127f59c8, 0x2503beb6d00cab4b,
3169 0xe2a0b5dc971f303a, 0x2e44ae64840fd61d,
3170 0x8da471a9de737e24, 0x5ceaecfed289e5d2,
3171 0xb10d8e1456105dad, 0x7425a83e872c5f47,
3172 0xdd50f1996b947518, 0xd12f124e28f77719,
3173 0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f,
3174 0xace73cbfdc0bfb7b, 0x636cc64d1001550b,
3175 0xd8210befd30efa5a, 0x3c47f7e05401aa4e,
3176 0x8714a775e3e95c78, 0x65acfaec34810a71,
3177 0xa8d9d1535ce3b396, 0x7f1839a741a14d0d,
3178 0xd31045a8341ca07c, 0x1ede48111209a050,
3179 0x83ea2b892091e44d, 0x934aed0aab460432,
3180 0xa4e4b66b68b65d60, 0xf81da84d5617853f,
3181 0xce1de40642e3f4b9, 0x36251260ab9d668e,
3182 0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019,
3183 0xa1075a24e4421730, 0xb24cf65b8612f81f,
3184 0xc94930ae1d529cfc, 0xdee033f26797b627,
3185 0xfb9b7cd9a4a7443c, 0x169840ef017da3b1,
3186 0x9d412e0806e88aa5, 0x8e1f289560ee864e,
3187 0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2,
3188 0xf5b5d7ec8acb58a2, 0xae10af696774b1db,
3189 0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29,
3190 0xbff610b0cc6edd3f, 0x17fd090a58d32af3,
3191 0xeff394dcff8a948e, 0xddfc4b4cef07f5b0,
3192 0x95f83d0a1fb69cd9, 0x4abdaf101564f98e,
3193 0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1,
3194 0xea53df5fd18d5513, 0x84c86189216dc5ed,
3195 0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4,
3196 0xb7118682dbb66a77, 0x3fbc8c33221dc2a1,
3197 0xe4d5e82392a40515, 0xfabaf3feaa5334a,
3198 0x8f05b1163ba6832d, 0x29cb4d87f2a7400e,
3199 0xb2c71d5bca9023f8, 0x743e20e9ef511012,
3200 0xdf78e4b2bd342cf6, 0x914da9246b255416,
3201 0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e,
3202 0xae9672aba3d0c320, 0xa184ac2473b529b1,
3203 0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e,
3204 0x8865899617fb1871, 0x7e2fa67c7a658892,
3205 0xaa7eebfb9df9de8d, 0xddbb901b98feeab7,
3206 0xd51ea6fa85785631, 0x552a74227f3ea565,
3207 0x8533285c936b35de, 0xd53a88958f87275f,
3208 0xa67ff273b8460356, 0x8a892abaf368f137,
3209 0xd01fef10a657842c, 0x2d2b7569b0432d85,
3210 0x8213f56a67f6b29b, 0x9c3b29620e29fc73,
3211 0xa298f2c501f45f42, 0x8349f3ba91b47b8f,
3212 0xcb3f2f7642717713, 0x241c70a936219a73,
3213 0xfe0efb53d30dd4d7, 0xed238cd383aa0110,
3214 0x9ec95d1463e8a506, 0xf4363804324a40aa,
3215 0xc67bb4597ce2ce48, 0xb143c6053edcd0d5,
3216 0xf81aa16fdc1b81da, 0xdd94b7868e94050a,
3217 0x9b10a4e5e9913128, 0xca7cf2b4191c8326,
3218 0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0,
3219 0xf24a01a73cf2dccf, 0xbc633b39673c8cec,
3220 0x976e41088617ca01, 0xd5be0503e085d813,
3221 0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18,
3222 0xec9c459d51852ba2, 0xddf8e7d60ed1219e,
3223 0x93e1ab8252f33b45, 0xcabb90e5c942b503,
3224 0xb8da1662e7b00a17, 0x3d6a751f3b936243,
3225 0xe7109bfba19c0c9d, 0xcc512670a783ad4,
3226 0x906a617d450187e2, 0x27fb2b80668b24c5,
3227 0xb484f9dc9641e9da, 0xb1f9f660802dedf6,
3228 0xe1a63853bbd26451, 0x5e7873f8a0396973,
3229 0x8d07e33455637eb2, 0xdb0b487b6423e1e8,
3230 0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62,
3231 0xdc5c5301c56b75f7, 0x7641a140cc7810fb,
3232 0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d,
3233 0xac2820d9623bf429, 0x546345fa9fbdcd44,
3234 0xd732290fbacaf133, 0xa97c177947ad4095,
3235 0x867f59a9d4bed6c0, 0x49ed8eabcccc485d,
3236 0xa81f301449ee8c70, 0x5c68f256bfff5a74,
3237 0xd226fc195c6a2f8c, 0x73832eec6fff3111,
3238 0x83585d8fd9c25db7, 0xc831fd53c5ff7eab,
3239 0xa42e74f3d032f525, 0xba3e7ca8b77f5e55,
3240 0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb,
3241 0x80444b5e7aa7cf85, 0x7980d163cf5b81b3,
3242 0xa0555e361951c366, 0xd7e105bcc332621f,
3243 0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7,
3244 0xfa856334878fc150, 0xb14f98f6f0feb951,
3245 0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3,
3246 0xc3b8358109e84f07, 0xa862f80ec4700c8,
3247 0xf4a642e14c6262c8, 0xcd27bb612758c0fa,
3248 0x98e7e9cccfbd7dbd, 0x8038d51cb897789c,
3249 0xbf21e44003acdd2c, 0xe0470a63e6bd56c3,
3250 0xeeea5d5004981478, 0x1858ccfce06cac74,
3251 0x95527a5202df0ccb, 0xf37801e0c43ebc8,
3252 0xbaa718e68396cffd, 0xd30560258f54e6ba,
3253 0xe950df20247c83fd, 0x47c6b82ef32a2069,
3254 0x91d28b7416cdd27e, 0x4cdc331d57fa5441,
3255 0xb6472e511c81471d, 0xe0133fe4adf8e952,
3256 0xe3d8f9e563a198e5, 0x58180fddd97723a6,
3257 0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648,
3258 };
3259};
3260
3261#if SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
3262
3263template <class unused>
3264constexpr uint64_t
3266
3267#endif
3268
3270
3271} // namespace simdjson_fast_float
3272
3273#endif
3274
3275#ifndef SIMDJSON_FASTFLOAT_DECIMAL_TO_BINARY_H
3276#define SIMDJSON_FASTFLOAT_DECIMAL_TO_BINARY_H
3277
3278#include <cfloat>
3279#include <cinttypes>
3280#include <cmath>
3281#include <cstdint>
3282#include <cstdlib>
3283#include <cstring>
3284
3285namespace simdjson_fast_float {
3286
3287// This will compute or rather approximate w * 5**q and return a pair of 64-bit
3288// words approximating the result, with the "high" part corresponding to the
3289// most significant bits and the low part corresponding to the least significant
3290// bits.
3291//
3292template <int bit_precision>
3293simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 value128
3294compute_product_approximation(int64_t q, uint64_t w) {
3295 int const index = 2 * int(q - powers::smallest_power_of_five);
3296 // For small values of q, e.g., q in [0,27], the answer is always exact
3297 // because The line value128 firstproduct = full_multiplication(w,
3298 // power_of_five_128[index]); gives the exact answer.
3299 value128 firstproduct =
3300 full_multiplication(w, powers::power_of_five_128[index]);
3301 static_assert((bit_precision >= 0) && (bit_precision <= 64),
3302 " precision should be in (0,64]");
3303 constexpr uint64_t precision_mask =
3304 (bit_precision < 64) ? (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
3305 : uint64_t(0xFFFFFFFFFFFFFFFF);
3306 if ((firstproduct.high & precision_mask) ==
3307 precision_mask) { // could further guard with (lower + w < lower)
3308 // regarding the second product, we only need secondproduct.high, but our
3309 // expectation is that the compiler will optimize this extra work away if
3310 // needed.
3311 value128 secondproduct =
3312 full_multiplication(w, powers::power_of_five_128[index + 1]);
3313 firstproduct.low += secondproduct.high;
3314 if (secondproduct.high > firstproduct.low) {
3315 firstproduct.high++;
3316 }
3317 }
3318 return firstproduct;
3319}
3320
3321namespace detail {
3337constexpr simdjson_fastfloat_really_inline int32_t power(int32_t q) noexcept {
3338 return (((152170 + 65536) * q) >> 16) + 63;
3339}
3340} // namespace detail
3341
3342// create an adjusted mantissa, biased by the invalid power2
3343// for significant digits already multiplied by 10 ** q.
3344template <typename binary>
3345simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 adjusted_mantissa
3346compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept {
3347 int hilz = int(w >> 63) ^ 1;
3348 adjusted_mantissa answer;
3349 answer.mantissa = w << hilz;
3350 int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent();
3351 answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 +
3352 invalid_am_bias);
3353 return answer;
3354}
3355
3356// w * 10 ** q, without rounding the representation up.
3357// the power2 in the exponent will be adjusted by invalid_am_bias.
3358template <typename binary>
3359simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 adjusted_mantissa
3360compute_error(int64_t q, uint64_t w) noexcept {
3361 int lz = leading_zeroes(w);
3362 w <<= lz;
3363 value128 product =
3364 compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
3365 return compute_error_scaled<binary>(q, product.high, lz);
3366}
3367
3368// Computers w * 10 ** q.
3369// The returned value should be a valid number that simply needs to be
3370// packed. However, in some very rare cases, the computation will fail. In such
3371// cases, we return an adjusted_mantissa with a negative power of 2: the caller
3372// should recompute in such cases.
3373template <typename binary>
3374simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 adjusted_mantissa
3375compute_float(int64_t q, uint64_t w) noexcept {
3376 adjusted_mantissa answer;
3377 if ((w == 0) || (q < binary::smallest_power_of_ten())) {
3378 answer.power2 = 0;
3379 answer.mantissa = 0;
3380 // result should be zero
3381 return answer;
3382 }
3383 if (q > binary::largest_power_of_ten()) {
3384 // we want to get infinity:
3385 answer.power2 = binary::infinite_power();
3386 answer.mantissa = 0;
3387 return answer;
3388 }
3389 // At this point in time q is in [powers::smallest_power_of_five,
3390 // powers::largest_power_of_five].
3391
3392 // We want the most significant bit of i to be 1. Shift if needed.
3393 int lz = leading_zeroes(w);
3394 w <<= lz;
3395
3396 // The required precision is binary::mantissa_explicit_bits() + 3 because
3397 // 1. We need the implicit bit
3398 // 2. We need an extra bit for rounding purposes
3399 // 3. We might lose a bit due to the "upperbit" routine (result too small,
3400 // requiring a shift)
3401
3402 value128 product =
3403 compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
3404 // The computed 'product' is always sufficient.
3405 // Mathematical proof:
3406 // Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to
3407 // appear) See script/mushtak_lemire.py
3408
3409 // The "compute_product_approximation" function can be slightly slower than a
3410 // branchless approach: value128 product = compute_product(q, w); but in
3411 // practice, we can win big with the compute_product_approximation if its
3412 // additional branch is easily predicted. Which is best is data specific.
3413 int upperbit = int(product.high >> 63);
3414 int shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3;
3415
3416 answer.mantissa = product.high >> shift;
3417
3418 answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz -
3419 binary::minimum_exponent());
3420 if (answer.power2 <= 0) { // we have a subnormal?
3421 // Here have that answer.power2 <= 0 so -answer.power2 >= 0
3422 if (-answer.power2 + 1 >=
3423 64) { // if we have more than 64 bits below the minimum exponent, you
3424 // have a zero for sure.
3425 answer.power2 = 0;
3426 answer.mantissa = 0;
3427 // result should be zero
3428 return answer;
3429 }
3430 // next line is safe because -answer.power2 + 1 < 64
3431 answer.mantissa >>= -answer.power2 + 1;
3432 // Thankfully, we can't have both "round-to-even" and subnormals because
3433 // "round-to-even" only occurs for powers close to 0 in the 32-bit and
3434 // and 64-bit case (with no more than 19 digits).
3435 answer.mantissa += (answer.mantissa & 1); // round up
3436 answer.mantissa >>= 1;
3437 // There is a weird scenario where we don't have a subnormal but just.
3438 // Suppose we start with 2.2250738585072013e-308, we end up
3439 // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal
3440 // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round
3441 // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer
3442 // subnormal, but we can only know this after rounding.
3443 // So we only declare a subnormal if we are smaller than the threshold.
3444 answer.power2 =
3445 (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits()))
3446 ? 0
3447 : 1;
3448 return answer;
3449 }
3450
3451 // usually, we round *up*, but if we fall right in between and and we have an
3452 // even basis, we need to round down
3453 // We are only concerned with the cases where 5**q fits in single 64-bit word.
3454 if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) &&
3455 (q <= binary::max_exponent_round_to_even()) &&
3456 ((answer.mantissa & 3) == 1)) { // we may fall between two floats!
3457 // To be in-between two floats we need that in doing
3458 // answer.mantissa = product.high >> (upperbit + 64 -
3459 // binary::mantissa_explicit_bits() - 3);
3460 // ... we dropped out only zeroes. But if this happened, then we can go
3461 // back!!!
3462 if ((answer.mantissa << shift) == product.high) {
3463 answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up
3464 }
3465 }
3466
3467 answer.mantissa += (answer.mantissa & 1); // round up
3468 answer.mantissa >>= 1;
3469 if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) {
3470 answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits());
3471 answer.power2++; // undo previous addition
3472 }
3473
3474 answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits());
3475 if (answer.power2 >= binary::infinite_power()) { // infinity
3476 answer.power2 = binary::infinite_power();
3477 answer.mantissa = 0;
3478 }
3479 return answer;
3480}
3481
3482} // namespace simdjson_fast_float
3483
3484#endif
3485
3486#ifndef SIMDJSON_FASTFLOAT_BIGINT_H
3487#define SIMDJSON_FASTFLOAT_BIGINT_H
3488
3489#include <algorithm>
3490#include <cstdint>
3491#include <climits>
3492#include <cstring>
3493
3494
3495namespace simdjson_fast_float {
3496
3497// the limb width: we want efficient multiplication of double the bits in
3498// limb, or for 64-bit limbs, at least 64-bit multiplication where we can
3499// extract the high and low parts efficiently. this is every 64-bit
3500// architecture except for sparc, which emulates 128-bit multiplication.
3501// we might have platforms where `CHAR_BIT` is not 8, so let's avoid
3502// doing `8 * sizeof(limb)`.
3503#if defined(SIMDJSON_FASTFLOAT_64BIT) && !defined(__sparc)
3504#define SIMDJSON_FASTFLOAT_64BIT_LIMB 1
3505typedef uint64_t limb;
3506constexpr size_t limb_bits = 64;
3507#else
3508#define SIMDJSON_FASTFLOAT_32BIT_LIMB
3509typedef uint32_t limb;
3510constexpr size_t limb_bits = 32;
3511#endif
3512
3513typedef span<limb> limb_span;
3514
3515// number of bits in a bigint. this needs to be at least the number
3516// of bits required to store the largest bigint, which is
3517// `log2(10**(digits + max_exp))`, or `log2(10**(767 + 342))`, or
3518// ~3600 bits, so we round to 4000.
3519constexpr size_t bigint_bits = 4000;
3520constexpr size_t bigint_limbs = bigint_bits / limb_bits;
3521
3522// vector-like type that is allocated on the stack. the entire
3523// buffer is pre-allocated, and only the length changes.
3524template <uint16_t size> struct stackvec {
3525 limb data[size];
3526 // we never need more than 150 limbs
3527 uint16_t length{0};
3528
3529 stackvec() = default;
3530 stackvec(stackvec const &) = delete;
3531 stackvec &operator=(stackvec const &) = delete;
3532 stackvec(stackvec &&) = delete;
3533 stackvec &operator=(stackvec &&other) = delete;
3534
3535 // create stack vector from existing limb span.
3536 SIMDJSON_FASTFLOAT_CONSTEXPR20 stackvec(limb_span s) {
3537 SIMDJSON_FASTFLOAT_ASSERT(try_extend(s));
3538 }
3539
3540 SIMDJSON_FASTFLOAT_CONSTEXPR14 limb &operator[](size_t index) noexcept {
3541 SIMDJSON_FASTFLOAT_DEBUG_ASSERT(index < length);
3542 return data[index];
3543 }
3544
3545 SIMDJSON_FASTFLOAT_CONSTEXPR14 const limb &operator[](size_t index) const noexcept {
3546 SIMDJSON_FASTFLOAT_DEBUG_ASSERT(index < length);
3547 return data[index];
3548 }
3549
3550 // index from the end of the container
3551 SIMDJSON_FASTFLOAT_CONSTEXPR14 const limb &rindex(size_t index) const noexcept {
3552 SIMDJSON_FASTFLOAT_DEBUG_ASSERT(index < length);
3553 size_t rindex = length - index - 1;
3554 return data[rindex];
3555 }
3556
3557 // set the length, without bounds checking.
3558 SIMDJSON_FASTFLOAT_CONSTEXPR14 void set_len(size_t len) noexcept {
3559 length = uint16_t(len);
3560 }
3561
3562 constexpr size_t len() const noexcept { return length; }
3563
3564 constexpr bool is_empty() const noexcept { return length == 0; }
3565
3566 constexpr size_t capacity() const noexcept { return size; }
3567
3568 // append item to vector, without bounds checking
3569 SIMDJSON_FASTFLOAT_CONSTEXPR14 void push_unchecked(limb value) noexcept {
3570 data[length] = value;
3571 length++;
3572 }
3573
3574 // append item to vector, returning if item was added
3575 SIMDJSON_FASTFLOAT_CONSTEXPR14 bool try_push(limb value) noexcept {
3576 if (len() < capacity()) {
3577 push_unchecked(value);
3578 return true;
3579 } else {
3580 return false;
3581 }
3582 }
3583
3584 // add items to the vector, from a span, without bounds checking
3585 SIMDJSON_FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept {
3586 limb *ptr = data + length;
3587 std::copy_n(s.ptr, s.len(), ptr);
3588 set_len(len() + s.len());
3589 }
3590
3591 // try to add items to the vector, returning if items were added
3592 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool try_extend(limb_span s) noexcept {
3593 if (len() + s.len() <= capacity()) {
3594 extend_unchecked(s);
3595 return true;
3596 } else {
3597 return false;
3598 }
3599 }
3600
3601 // resize the vector, without bounds checking
3602 // if the new size is longer than the vector, assign value to each
3603 // appended item.
3604 SIMDJSON_FASTFLOAT_CONSTEXPR20
3605 void resize_unchecked(size_t new_len, limb value) noexcept {
3606 if (new_len > len()) {
3607 size_t count = new_len - len();
3608 limb *first = data + len();
3609 limb *last = first + count;
3610 ::std::fill(first, last, value);
3611 set_len(new_len);
3612 } else {
3613 set_len(new_len);
3614 }
3615 }
3616
3617 // try to resize the vector, returning if the vector was resized.
3618 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool try_resize(size_t new_len, limb value) noexcept {
3619 if (new_len > capacity()) {
3620 return false;
3621 } else {
3622 resize_unchecked(new_len, value);
3623 return true;
3624 }
3625 }
3626
3627 // check if any limbs are non-zero after the given index.
3628 // this needs to be done in reverse order, since the index
3629 // is relative to the most significant limbs.
3630 SIMDJSON_FASTFLOAT_CONSTEXPR14 bool nonzero(size_t index) const noexcept {
3631 while (index < len()) {
3632 if (rindex(index) != 0) {
3633 return true;
3634 }
3635 index++;
3636 }
3637 return false;
3638 }
3639
3640 // normalize the big integer, so most-significant zero limbs are removed.
3641 SIMDJSON_FASTFLOAT_CONSTEXPR14 void normalize() noexcept {
3642 while (len() > 0 && rindex(0) == 0) {
3643 length--;
3644 }
3645 }
3646};
3647
3648simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 uint64_t
3649empty_hi64(bool &truncated) noexcept {
3650 truncated = false;
3651 return 0;
3652}
3653
3654simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 uint64_t
3655uint64_hi64(uint64_t r0, bool &truncated) noexcept {
3656 truncated = false;
3657 int shl = leading_zeroes(r0);
3658 return r0 << shl;
3659}
3660
3661simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 uint64_t
3662uint64_hi64(uint64_t r0, uint64_t r1, bool &truncated) noexcept {
3663 int shl = leading_zeroes(r0);
3664 if (shl == 0) {
3665 truncated = r1 != 0;
3666 return r0;
3667 } else {
3668 int shr = 64 - shl;
3669 truncated = (r1 << shl) != 0;
3670 return (r0 << shl) | (r1 >> shr);
3671 }
3672}
3673
3674simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 uint64_t
3675uint32_hi64(uint32_t r0, bool &truncated) noexcept {
3676 return uint64_hi64(r0, truncated);
3677}
3678
3679simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 uint64_t
3680uint32_hi64(uint32_t r0, uint32_t r1, bool &truncated) noexcept {
3681 uint64_t x0 = r0;
3682 uint64_t x1 = r1;
3683 return uint64_hi64((x0 << 32) | x1, truncated);
3684}
3685
3686simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 uint64_t
3687uint32_hi64(uint32_t r0, uint32_t r1, uint32_t r2, bool &truncated) noexcept {
3688 uint64_t x0 = r0;
3689 uint64_t x1 = r1;
3690 uint64_t x2 = r2;
3691 return uint64_hi64(x0, (x1 << 32) | x2, truncated);
3692}
3693
3694// add two small integers, checking for overflow.
3695// we want an efficient operation. for msvc, where
3696// we don't have built-in intrinsics, this is still
3697// pretty fast.
3698simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 limb
3699scalar_add(limb x, limb y, bool &overflow) noexcept {
3700 limb z;
3701// gcc and clang
3702#if defined(__has_builtin)
3703#if __has_builtin(__builtin_add_overflow)
3704 if (!cpp20_and_in_constexpr()) {
3705 overflow = __builtin_add_overflow(x, y, &z);
3706 return z;
3707 }
3708#endif
3709#endif
3710
3711 // generic, this still optimizes correctly on MSVC.
3712 z = x + y;
3713 overflow = z < x;
3714 return z;
3715}
3716
3717// multiply two small integers, getting both the high and low bits.
3718simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 limb
3719scalar_mul(limb x, limb y, limb &carry) noexcept {
3720#ifdef SIMDJSON_FASTFLOAT_64BIT_LIMB
3721#if defined(__SIZEOF_INT128__)
3722 // GCC and clang both define it as an extension.
3723 __uint128_t z = __uint128_t(x) * __uint128_t(y) + __uint128_t(carry);
3724 carry = limb(z >> limb_bits);
3725 return limb(z);
3726#else
3727 // fallback, no native 128-bit integer multiplication with carry.
3728 // on msvc, this optimizes identically, somehow.
3729 value128 z = full_multiplication(x, y);
3730 bool overflow;
3731 z.low = scalar_add(z.low, carry, overflow);
3732 z.high += uint64_t(overflow); // cannot overflow
3733 carry = z.high;
3734 return z.low;
3735#endif
3736#else
3737 uint64_t z = uint64_t(x) * uint64_t(y) + uint64_t(carry);
3738 carry = limb(z >> limb_bits);
3739 return limb(z);
3740#endif
3741}
3742
3743// add scalar value to bigint starting from offset.
3744// used in grade school multiplication
3745template <uint16_t size>
3746inline SIMDJSON_FASTFLOAT_CONSTEXPR20 bool small_add_from(stackvec<size> &vec, limb y,
3747 size_t start) noexcept {
3748 size_t index = start;
3749 limb carry = y;
3750 bool overflow;
3751 while (carry != 0 && index < vec.len()) {
3752 vec[index] = scalar_add(vec[index], carry, overflow);
3753 carry = limb(overflow);
3754 index += 1;
3755 }
3756 if (carry != 0) {
3757 SIMDJSON_FASTFLOAT_TRY(vec.try_push(carry));
3758 }
3759 return true;
3760}
3761
3762// add scalar value to bigint.
3763template <uint16_t size>
3764simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 bool
3765small_add(stackvec<size> &vec, limb y) noexcept {
3766 return small_add_from(vec, y, 0);
3767}
3768
3769// multiply bigint by scalar value.
3770template <uint16_t size>
3771inline SIMDJSON_FASTFLOAT_CONSTEXPR20 bool small_mul(stackvec<size> &vec,
3772 limb y) noexcept {
3773 limb carry = 0;
3774 for (size_t index = 0; index < vec.len(); index++) {
3775 vec[index] = scalar_mul(vec[index], y, carry);
3776 }
3777 if (carry != 0) {
3778 SIMDJSON_FASTFLOAT_TRY(vec.try_push(carry));
3779 }
3780 return true;
3781}
3782
3783// add bigint to bigint starting from index.
3784// used in grade school multiplication
3785template <uint16_t size>
3786SIMDJSON_FASTFLOAT_CONSTEXPR20 bool large_add_from(stackvec<size> &x, limb_span y,
3787 size_t start) noexcept {
3788 // the effective x buffer is from `xstart..x.len()`, so exit early
3789 // if we can't get that current range.
3790 if (x.len() < start || y.len() > x.len() - start) {
3791 SIMDJSON_FASTFLOAT_TRY(x.try_resize(y.len() + start, 0));
3792 }
3793
3794 bool carry = false;
3795 for (size_t index = 0; index < y.len(); index++) {
3796 limb xi = x[index + start];
3797 limb yi = y[index];
3798 bool c1 = false;
3799 bool c2 = false;
3800 xi = scalar_add(xi, yi, c1);
3801 if (carry) {
3802 xi = scalar_add(xi, 1, c2);
3803 }
3804 x[index + start] = xi;
3805 carry = c1 | c2;
3806 }
3807
3808 // handle overflow
3809 if (carry) {
3810 SIMDJSON_FASTFLOAT_TRY(small_add_from(x, 1, y.len() + start));
3811 }
3812 return true;
3813}
3814
3815// add bigint to bigint.
3816template <uint16_t size>
3817simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 bool
3818large_add_from(stackvec<size> &x, limb_span y) noexcept {
3819 return large_add_from(x, y, 0);
3820}
3821
3822// grade-school multiplication algorithm
3823template <uint16_t size>
3824SIMDJSON_FASTFLOAT_CONSTEXPR20 bool long_mul(stackvec<size> &x, limb_span y) noexcept {
3825 limb_span xs = limb_span(x.data, x.len());
3826 stackvec<size> z(xs);
3827 limb_span zs = limb_span(z.data, z.len());
3828
3829 if (y.len() != 0) {
3830 limb y0 = y[0];
3831 SIMDJSON_FASTFLOAT_TRY(small_mul(x, y0));
3832 for (size_t index = 1; index < y.len(); index++) {
3833 limb yi = y[index];
3834 stackvec<size> zi;
3835 if (yi != 0) {
3836 // re-use the same buffer throughout
3837 zi.set_len(0);
3838 SIMDJSON_FASTFLOAT_TRY(zi.try_extend(zs));
3839 SIMDJSON_FASTFLOAT_TRY(small_mul(zi, yi));
3840 limb_span zis = limb_span(zi.data, zi.len());
3841 SIMDJSON_FASTFLOAT_TRY(large_add_from(x, zis, index));
3842 }
3843 }
3844 }
3845
3846 x.normalize();
3847 return true;
3848}
3849
3850// grade-school multiplication algorithm
3851template <uint16_t size>
3852SIMDJSON_FASTFLOAT_CONSTEXPR20 bool large_mul(stackvec<size> &x, limb_span y) noexcept {
3853 if (y.len() == 1) {
3854 SIMDJSON_FASTFLOAT_TRY(small_mul(x, y[0]));
3855 } else {
3856 SIMDJSON_FASTFLOAT_TRY(long_mul(x, y));
3857 }
3858 return true;
3859}
3860
3861template <typename = void> struct pow5_tables {
3862 static constexpr uint32_t large_step = 135;
3863 static constexpr uint64_t small_power_of_5[] = {
3864 1UL,
3865 5UL,
3866 25UL,
3867 125UL,
3868 625UL,
3869 3125UL,
3870 15625UL,
3871 78125UL,
3872 390625UL,
3873 1953125UL,
3874 9765625UL,
3875 48828125UL,
3876 244140625UL,
3877 1220703125UL,
3878 6103515625UL,
3879 30517578125UL,
3880 152587890625UL,
3881 762939453125UL,
3882 3814697265625UL,
3883 19073486328125UL,
3884 95367431640625UL,
3885 476837158203125UL,
3886 2384185791015625UL,
3887 11920928955078125UL,
3888 59604644775390625UL,
3889 298023223876953125UL,
3890 1490116119384765625UL,
3891 7450580596923828125UL,
3892 };
3893#ifdef SIMDJSON_FASTFLOAT_64BIT_LIMB
3894 constexpr static limb large_power_of_5[] = {
3895 1414648277510068013UL, 9180637584431281687UL, 4539964771860779200UL,
3896 10482974169319127550UL, 198276706040285095UL};
3897#else
3898 constexpr static limb large_power_of_5[] = {
3899 4279965485U, 329373468U, 4020270615U, 2137533757U, 4287402176U,
3900 1057042919U, 1071430142U, 2440757623U, 381945767U, 46164893U};
3901#endif
3902};
3903
3904#if SIMDJSON_FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
3905
3906template <typename T> constexpr uint32_t pow5_tables<T>::large_step;
3907
3908template <typename T> constexpr uint64_t pow5_tables<T>::small_power_of_5[];
3909
3910template <typename T> constexpr limb pow5_tables<T>::large_power_of_5[];
3911
3912#endif
3913
3914// big integer type. implements a small subset of big integer
3915// arithmetic, using simple algorithms since asymptotically
3916// faster algorithms are slower for a small number of limbs.
3917// all operations assume the big-integer is normalized.
3919 // storage of the limbs, in little-endian order.
3921
3922 SIMDJSON_FASTFLOAT_CONSTEXPR20 bigint() : vec() {}
3923
3924 bigint(bigint const &) = delete;
3925 bigint &operator=(bigint const &) = delete;
3926 bigint(bigint &&) = delete;
3927 bigint &operator=(bigint &&other) = delete;
3928
3929 SIMDJSON_FASTFLOAT_CONSTEXPR20 bigint(uint64_t value) : vec() {
3930#ifdef SIMDJSON_FASTFLOAT_64BIT_LIMB
3931 vec.push_unchecked(value);
3932#else
3933 vec.push_unchecked(uint32_t(value));
3934 vec.push_unchecked(uint32_t(value >> 32));
3935#endif
3936 vec.normalize();
3937 }
3938
3939 // get the high 64 bits from the vector, and if bits were truncated.
3940 // this is to get the significant digits for the float.
3941 SIMDJSON_FASTFLOAT_CONSTEXPR20 uint64_t hi64(bool &truncated) const noexcept {
3942#ifdef SIMDJSON_FASTFLOAT_64BIT_LIMB
3943 if (vec.len() == 0) {
3944 return empty_hi64(truncated);
3945 } else if (vec.len() == 1) {
3946 return uint64_hi64(vec.rindex(0), truncated);
3947 } else {
3948 uint64_t result = uint64_hi64(vec.rindex(0), vec.rindex(1), truncated);
3949 truncated |= vec.nonzero(2);
3950 return result;
3951 }
3952#else
3953 if (vec.len() == 0) {
3954 return empty_hi64(truncated);
3955 } else if (vec.len() == 1) {
3956 return uint32_hi64(vec.rindex(0), truncated);
3957 } else if (vec.len() == 2) {
3958 return uint32_hi64(vec.rindex(0), vec.rindex(1), truncated);
3959 } else {
3960 uint64_t result =
3961 uint32_hi64(vec.rindex(0), vec.rindex(1), vec.rindex(2), truncated);
3962 truncated |= vec.nonzero(3);
3963 return result;
3964 }
3965#endif
3966 }
3967
3968 // compare two big integers, returning the large value.
3969 // assumes both are normalized. if the return value is
3970 // negative, other is larger, if the return value is
3971 // positive, this is larger, otherwise they are equal.
3972 // the limbs are stored in little-endian order, so we
3973 // must compare the limbs in ever order.
3974 SIMDJSON_FASTFLOAT_CONSTEXPR20 int compare(bigint const &other) const noexcept {
3975 if (vec.len() > other.vec.len()) {
3976 return 1;
3977 } else if (vec.len() < other.vec.len()) {
3978 return -1;
3979 } else {
3980 for (size_t index = vec.len(); index > 0; index--) {
3981 limb xi = vec[index - 1];
3982 limb yi = other.vec[index - 1];
3983 if (xi > yi) {
3984 return 1;
3985 } else if (xi < yi) {
3986 return -1;
3987 }
3988 }
3989 return 0;
3990 }
3991 }
3992
3993 // shift left each limb n bits, carrying over to the new limb
3994 // returns true if we were able to shift all the digits.
3995 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool shl_bits(size_t n) noexcept {
3996 // Internally, for each item, we shift left by n, and add the previous
3997 // right shifted limb-bits.
3998 // For example, we transform (for u8) shifted left 2, to:
3999 // b10100100 b01000010
4000 // b10 b10010001 b00001000
4001 SIMDJSON_FASTFLOAT_DEBUG_ASSERT(n != 0);
4002 SIMDJSON_FASTFLOAT_DEBUG_ASSERT(n < sizeof(limb) * 8);
4003
4004 size_t shl = n;
4005 size_t shr = limb_bits - shl;
4006 limb prev = 0;
4007 for (size_t index = 0; index < vec.len(); index++) {
4008 limb xi = vec[index];
4009 vec[index] = (xi << shl) | (prev >> shr);
4010 prev = xi;
4011 }
4012
4013 limb carry = prev >> shr;
4014 if (carry != 0) {
4015 return vec.try_push(carry);
4016 }
4017 return true;
4018 }
4019
4020 // move the limbs left by `n` limbs.
4021 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool shl_limbs(size_t n) noexcept {
4022 SIMDJSON_FASTFLOAT_DEBUG_ASSERT(n != 0);
4023 if (n + vec.len() > vec.capacity()) {
4024 return false;
4025 } else if (!vec.is_empty()) {
4026 // move limbs
4027 limb *dst = vec.data + n;
4028 limb const *src = vec.data;
4029 std::copy_backward(src, src + vec.len(), dst + vec.len());
4030 // fill in empty limbs
4031 limb *first = vec.data;
4032 limb *last = first + n;
4033 ::std::fill(first, last, 0);
4034 vec.set_len(n + vec.len());
4035 return true;
4036 } else {
4037 return true;
4038 }
4039 }
4040
4041 // move the limbs left by `n` bits.
4042 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool shl(size_t n) noexcept {
4043 size_t rem = n % limb_bits;
4044 size_t div = n / limb_bits;
4045 if (rem != 0) {
4046 SIMDJSON_FASTFLOAT_TRY(shl_bits(rem));
4047 }
4048 if (div != 0) {
4049 SIMDJSON_FASTFLOAT_TRY(shl_limbs(div));
4050 }
4051 return true;
4052 }
4053
4054 // get the number of leading zeros in the bigint.
4055 SIMDJSON_FASTFLOAT_CONSTEXPR20 int ctlz() const noexcept {
4056 if (vec.is_empty()) {
4057 return 0;
4058 } else {
4059#ifdef SIMDJSON_FASTFLOAT_64BIT_LIMB
4060 return leading_zeroes(vec.rindex(0));
4061#else
4062 // no use defining a specialized leading_zeroes for a 32-bit type.
4063 uint64_t r0 = vec.rindex(0);
4064 return leading_zeroes(r0 << 32);
4065#endif
4066 }
4067 }
4068
4069 // get the number of bits in the bigint.
4070 SIMDJSON_FASTFLOAT_CONSTEXPR20 int bit_length() const noexcept {
4071 int lz = ctlz();
4072 return int(limb_bits * vec.len()) - lz;
4073 }
4074
4075 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool mul(limb y) noexcept { return small_mul(vec, y); }
4076
4077 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool add(limb y) noexcept { return small_add(vec, y); }
4078
4079 // multiply as if by 2 raised to a power.
4080 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool pow2(uint32_t exp) noexcept { return shl(exp); }
4081
4082 // multiply as if by 5 raised to a power.
4083 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool pow5(uint32_t exp) noexcept {
4084 // multiply by a power of 5
4085 size_t large_length = sizeof(large_power_of_5) / sizeof(limb);
4086 limb_span large = limb_span(large_power_of_5, large_length);
4087 while (exp >= large_step) {
4088 SIMDJSON_FASTFLOAT_TRY(large_mul(vec, large));
4089 exp -= large_step;
4090 }
4091#ifdef SIMDJSON_FASTFLOAT_64BIT_LIMB
4092 uint32_t small_step = 27;
4093 limb max_native = 7450580596923828125UL;
4094#else
4095 uint32_t small_step = 13;
4096 limb max_native = 1220703125U;
4097#endif
4098 while (exp >= small_step) {
4099 SIMDJSON_FASTFLOAT_TRY(small_mul(vec, max_native));
4100 exp -= small_step;
4101 }
4102 if (exp != 0) {
4103 // Work around clang bug https://godbolt.org/z/zedh7rrhc
4104 // This is similar to https://github.com/llvm/llvm-project/issues/47746,
4105 // except the workaround described there don't work here
4106 SIMDJSON_FASTFLOAT_TRY(small_mul(vec, limb((static_cast<void>(small_power_of_5[0]),
4107 small_power_of_5[exp]))));
4108 }
4109
4110 return true;
4111 }
4112
4113 // multiply as if by 10 raised to a power.
4114 SIMDJSON_FASTFLOAT_CONSTEXPR20 bool pow10(uint32_t exp) noexcept {
4115 SIMDJSON_FASTFLOAT_TRY(pow5(exp));
4116 return pow2(exp);
4117 }
4118};
4119
4120} // namespace simdjson_fast_float
4121
4122#endif
4123
4124#ifndef SIMDJSON_FASTFLOAT_DIGIT_COMPARISON_H
4125#define SIMDJSON_FASTFLOAT_DIGIT_COMPARISON_H
4126
4127#include <cstdint>
4128#include <cstring>
4129#include <iterator>
4130
4131
4132namespace simdjson_fast_float {
4133
4134// 1e0 to 1e19
4135constexpr static uint64_t powers_of_ten_uint64[] = {1UL,
4136 10UL,
4137 100UL,
4138 1000UL,
4139 10000UL,
4140 100000UL,
4141 1000000UL,
4142 10000000UL,
4143 100000000UL,
4144 1000000000UL,
4145 10000000000UL,
4146 100000000000UL,
4147 1000000000000UL,
4148 10000000000000UL,
4149 100000000000000UL,
4150 1000000000000000UL,
4151 10000000000000000UL,
4152 100000000000000000UL,
4153 1000000000000000000UL,
4154 10000000000000000000UL};
4155
4156// calculate the exponent, in scientific notation, of the number.
4157// this algorithm is not even close to optimized, but it has no practical
4158// effect on performance: in order to have a faster algorithm, we'd need
4159// to slow down performance for faster algorithms, and this is still fast.
4160simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 int32_t
4161scientific_exponent(uint64_t mantissa, int32_t exponent) noexcept {
4162 while (mantissa >= 10000) {
4163 mantissa /= 10000;
4164 exponent += 4;
4165 }
4166 while (mantissa >= 100) {
4167 mantissa /= 100;
4168 exponent += 2;
4169 }
4170 while (mantissa >= 10) {
4171 mantissa /= 10;
4172 exponent += 1;
4173 }
4174 return exponent;
4175}
4176
4177// this converts a native floating-point number to an extended-precision float.
4178template <typename T>
4179simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 adjusted_mantissa
4180to_extended(T value) noexcept {
4181 using equiv_uint = equiv_uint_t<T>;
4182 constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
4183 constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
4184 constexpr equiv_uint hidden_bit_mask = binary_format<T>::hidden_bit_mask();
4185
4186 adjusted_mantissa am;
4187 int32_t bias = binary_format<T>::mantissa_explicit_bits() -
4188 binary_format<T>::minimum_exponent();
4189 equiv_uint bits;
4190#if SIMDJSON_FASTFLOAT_HAS_BIT_CAST
4191 bits = std::bit_cast<equiv_uint>(value);
4192#else
4193 ::memcpy(&bits, &value, sizeof(T));
4194#endif
4195 if ((bits & exponent_mask) == 0) {
4196 // denormal
4197 am.power2 = 1 - bias;
4198 am.mantissa = bits & mantissa_mask;
4199 } else {
4200 // normal
4201 am.power2 = int32_t((bits & exponent_mask) >>
4202 binary_format<T>::mantissa_explicit_bits());
4203 am.power2 -= bias;
4204 am.mantissa = (bits & mantissa_mask) | hidden_bit_mask;
4205 }
4206
4207 return am;
4208}
4209
4210// get the extended precision value of the halfway point between b and b+u.
4211// we are given a native float that represents b, so we need to adjust it
4212// halfway between b and b+u.
4213template <typename T>
4214simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 adjusted_mantissa
4215to_extended_halfway(T value) noexcept {
4216 adjusted_mantissa am = to_extended(value);
4217 am.mantissa <<= 1;
4218 am.mantissa += 1;
4219 am.power2 -= 1;
4220 return am;
4221}
4222
4223// round an extended-precision float to the nearest machine float.
4224template <typename T, typename callback>
4225simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 void round(adjusted_mantissa &am,
4226 callback cb) noexcept {
4227 int32_t mantissa_shift = 64 - binary_format<T>::mantissa_explicit_bits() - 1;
4228 if (-am.power2 >= mantissa_shift) {
4229 // have a denormal float
4230 int32_t shift = -am.power2 + 1;
4231 cb(am, (shift < 64 ? shift : 64));
4232 // check for round-up: if rounding-nearest carried us to the hidden bit.
4233 am.power2 = (am.mantissa <
4234 (uint64_t(1) << binary_format<T>::mantissa_explicit_bits()))
4235 ? 0
4236 : 1;
4237 return;
4238 }
4239
4240 // have a normal float, use the default shift.
4241 cb(am, mantissa_shift);
4242
4243 // check for carry
4244 if (am.mantissa >=
4245 (uint64_t(2) << binary_format<T>::mantissa_explicit_bits())) {
4246 am.mantissa = (uint64_t(1) << binary_format<T>::mantissa_explicit_bits());
4247 am.power2++;
4248 }
4249
4250 // check for infinite: we could have carried to an infinite power
4251 am.mantissa &= ~(uint64_t(1) << binary_format<T>::mantissa_explicit_bits());
4252 if (am.power2 >= binary_format<T>::infinite_power()) {
4253 am.power2 = binary_format<T>::infinite_power();
4254 am.mantissa = 0;
4255 }
4256}
4257
4258template <typename callback>
4259simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 void
4260round_nearest_tie_even(adjusted_mantissa &am, int32_t shift,
4261 callback cb) noexcept {
4262 uint64_t const mask = (shift == 64) ? UINT64_MAX : (uint64_t(1) << shift) - 1;
4263 uint64_t const halfway = (shift == 0) ? 0 : uint64_t(1) << (shift - 1);
4264 uint64_t truncated_bits = am.mantissa & mask;
4265 bool is_above = truncated_bits > halfway;
4266 bool is_halfway = truncated_bits == halfway;
4267
4268 // shift digits into position
4269 if (shift == 64) {
4270 am.mantissa = 0;
4271 } else {
4272 am.mantissa >>= shift;
4273 }
4274 am.power2 += shift;
4275
4276 bool is_odd = (am.mantissa & 1) == 1;
4277 am.mantissa += uint64_t(cb(is_odd, is_halfway, is_above));
4278}
4279
4280simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 void
4281round_down(adjusted_mantissa &am, int32_t shift) noexcept {
4282 if (shift == 64) {
4283 am.mantissa = 0;
4284 } else {
4285 am.mantissa >>= shift;
4286 }
4287 am.power2 += shift;
4288}
4289
4290template <typename UC>
4291simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 void
4292skip_zeros(UC const *&first, UC const *last) noexcept {
4293 uint64_t val;
4294 while (!cpp20_and_in_constexpr() &&
4295 std::distance(first, last) >= int_cmp_len<UC>()) {
4296 ::memcpy(&val, first, sizeof(uint64_t));
4297 if (val != int_cmp_zeros<UC>()) {
4298 break;
4299 }
4300 first += int_cmp_len<UC>();
4301 }
4302 while (first != last) {
4303 if (*first != UC('0')) {
4304 break;
4305 }
4306 first++;
4307 }
4308}
4309
4310// determine if any non-zero digits were truncated.
4311// all characters must be valid digits.
4312template <typename UC>
4313simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 bool
4314is_truncated(UC const *first, UC const *last) noexcept {
4315 // do 8-bit optimizations, can just compare to 8 literal 0s.
4316 uint64_t val;
4317 while (!cpp20_and_in_constexpr() &&
4318 std::distance(first, last) >= int_cmp_len<UC>()) {
4319 ::memcpy(&val, first, sizeof(uint64_t));
4320 if (val != int_cmp_zeros<UC>()) {
4321 return true;
4322 }
4323 first += int_cmp_len<UC>();
4324 }
4325 while (first != last) {
4326 if (*first != UC('0')) {
4327 return true;
4328 }
4329 ++first;
4330 }
4331 return false;
4332}
4333
4334template <typename UC>
4335simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 bool
4336is_truncated(span<UC const> s) noexcept {
4337 return is_truncated(s.ptr, s.ptr + s.len());
4338}
4339
4340template <typename UC>
4341simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 void
4342parse_eight_digits(UC const *&p, limb &value, size_t &counter,
4343 size_t &count) noexcept {
4344 value = value * 100000000 + parse_eight_digits_unrolled(p);
4345 p += 8;
4346 counter += 8;
4347 count += 8;
4348}
4349
4350template <typename UC>
4351simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR14 void
4352parse_one_digit(UC const *&p, limb &value, size_t &counter,
4353 size_t &count) noexcept {
4354 value = value * 10 + limb(*p - UC('0'));
4355 p++;
4356 counter++;
4357 count++;
4358}
4359
4360simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 void
4361add_native(bigint &big, limb power, limb value) noexcept {
4362 big.mul(power);
4363 big.add(value);
4364}
4365
4366simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 void
4367round_up_bigint(bigint &big, size_t &count) noexcept {
4368 // need to round-up the digits, but need to avoid rounding
4369 // ....9999 to ...10000, which could cause a false halfway point.
4370 add_native(big, 10, 1);
4371 count++;
4372}
4373
4374// parse the significant digits into a big integer
4375template <typename UC>
4376inline SIMDJSON_FASTFLOAT_CONSTEXPR20 void
4377parse_mantissa(bigint &result, parsed_number_string_t<UC> &num,
4378 size_t max_digits, size_t &digits) noexcept {
4379 // try to minimize the number of big integer and scalar multiplication.
4380 // therefore, try to parse 8 digits at a time, and multiply by the largest
4381 // scalar value (9 or 19 digits) for each step.
4382 size_t counter = 0;
4383 digits = 0;
4384 limb value = 0;
4385#ifdef SIMDJSON_FASTFLOAT_64BIT_LIMB
4386 size_t step = 19;
4387#else
4388 size_t step = 9;
4389#endif
4390
4391 // process all integer digits.
4392 UC const *p = num.integer.ptr;
4393 UC const *pend = p + num.integer.len();
4394 skip_zeros(p, pend);
4395 // process all digits, in increments of step per loop
4396 while (p != pend) {
4397 while ((std::distance(p, pend) >= 8) && (step - counter >= 8) &&
4398 (max_digits - digits >= 8)) {
4399 parse_eight_digits(p, value, counter, digits);
4400 }
4401 while (counter < step && p != pend && digits < max_digits) {
4402 parse_one_digit(p, value, counter, digits);
4403 }
4404 if (digits == max_digits) {
4405 // add the temporary value, then check if we've truncated any digits
4406 add_native(result, limb(powers_of_ten_uint64[counter]), value);
4407 bool truncated = is_truncated(p, pend);
4408 if (num.fraction.ptr != nullptr) {
4409 truncated |= is_truncated(num.fraction);
4410 }
4411 if (truncated) {
4412 round_up_bigint(result, digits);
4413 }
4414 return;
4415 } else {
4416 add_native(result, limb(powers_of_ten_uint64[counter]), value);
4417 counter = 0;
4418 value = 0;
4419 }
4420 }
4421
4422 // add our fraction digits, if they're available.
4423 if (num.fraction.ptr != nullptr) {
4424 p = num.fraction.ptr;
4425 pend = p + num.fraction.len();
4426 if (digits == 0) {
4427 skip_zeros(p, pend);
4428 }
4429 // process all digits, in increments of step per loop
4430 while (p != pend) {
4431 while ((std::distance(p, pend) >= 8) && (step - counter >= 8) &&
4432 (max_digits - digits >= 8)) {
4433 parse_eight_digits(p, value, counter, digits);
4434 }
4435 while (counter < step && p != pend && digits < max_digits) {
4436 parse_one_digit(p, value, counter, digits);
4437 }
4438 if (digits == max_digits) {
4439 // add the temporary value, then check if we've truncated any digits
4440 add_native(result, limb(powers_of_ten_uint64[counter]), value);
4441 bool truncated = is_truncated(p, pend);
4442 if (truncated) {
4443 round_up_bigint(result, digits);
4444 }
4445 return;
4446 } else {
4447 add_native(result, limb(powers_of_ten_uint64[counter]), value);
4448 counter = 0;
4449 value = 0;
4450 }
4451 }
4452 }
4453
4454 if (counter != 0) {
4455 add_native(result, limb(powers_of_ten_uint64[counter]), value);
4456 }
4457}
4458
4459template <typename T>
4460inline SIMDJSON_FASTFLOAT_CONSTEXPR20 adjusted_mantissa
4461positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept {
4462 SIMDJSON_FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent)));
4463 adjusted_mantissa answer;
4464 bool truncated;
4465 answer.mantissa = bigmant.hi64(truncated);
4466 int bias = binary_format<T>::mantissa_explicit_bits() -
4467 binary_format<T>::minimum_exponent();
4468 answer.power2 = bigmant.bit_length() - 64 + bias;
4469
4470 round<T>(answer, [truncated](adjusted_mantissa &a, int32_t shift) {
4471 round_nearest_tie_even(
4472 a, shift,
4473 [truncated](bool is_odd, bool is_halfway, bool is_above) -> bool {
4474 return is_above || (is_halfway && truncated) ||
4475 (is_odd && is_halfway);
4476 });
4477 });
4478
4479 return answer;
4480}
4481
4482// the scaling here is quite simple: we have, for the real digits `m * 10^e`,
4483// and for the theoretical digits `n * 2^f`. Since `e` is always negative,
4484// to scale them identically, we do `n * 2^f * 5^-f`, so we now have `m * 2^e`.
4485// we then need to scale by `2^(f- e)`, and then the two significant digits
4486// are of the same magnitude.
4487template <typename T>
4488inline SIMDJSON_FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp(
4489 bigint &bigmant, adjusted_mantissa am, int32_t exponent) noexcept {
4490 bigint &real_digits = bigmant;
4491 int32_t real_exp = exponent;
4492
4493 // get the value of `b`, rounded down, and get a bigint representation of b+h
4494 adjusted_mantissa am_b = am;
4495 // gcc7 buf: use a lambda to remove the noexcept qualifier bug with
4496 // -Wnoexcept-type.
4497 round<T>(am_b,
4498 [](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); });
4499 T b;
4500 to_float(false, am_b, b);
4501 adjusted_mantissa theor = to_extended_halfway(b);
4502 bigint theor_digits(theor.mantissa);
4503 int32_t theor_exp = theor.power2;
4504
4505 // scale real digits and theor digits to be same power.
4506 int32_t pow2_exp = theor_exp - real_exp;
4507 uint32_t pow5_exp = uint32_t(-real_exp);
4508 if (pow5_exp != 0) {
4509 SIMDJSON_FASTFLOAT_ASSERT(theor_digits.pow5(pow5_exp));
4510 }
4511 if (pow2_exp > 0) {
4512 SIMDJSON_FASTFLOAT_ASSERT(theor_digits.pow2(uint32_t(pow2_exp)));
4513 } else if (pow2_exp < 0) {
4514 SIMDJSON_FASTFLOAT_ASSERT(real_digits.pow2(uint32_t(-pow2_exp)));
4515 }
4516
4517 // compare digits, and use it to direct rounding
4518 int ord = real_digits.compare(theor_digits);
4519 adjusted_mantissa answer = am;
4520 round<T>(answer, [ord](adjusted_mantissa &a, int32_t shift) {
4521 round_nearest_tie_even(
4522 a, shift, [ord](bool is_odd, bool _, bool __) -> bool {
4523 static_cast<void>(_); // not needed, since we've done our comparison
4524 static_cast<void>(__); // not needed, since we've done our comparison
4525 if (ord > 0) {
4526 return true;
4527 } else if (ord < 0) {
4528 return false;
4529 } else {
4530 return is_odd;
4531 }
4532 });
4533 });
4534
4535 return answer;
4536}
4537
4538// parse the significant digits as a big integer to unambiguously round
4539// the significant digits. here, we are trying to determine how to round
4540// an extended float representation close to `b+h`, halfway between `b`
4541// (the float rounded-down) and `b+u`, the next positive float. this
4542// algorithm is always correct, and uses one of two approaches. when
4543// the exponent is positive relative to the significant digits (such as
4544// 1234), we create a big-integer representation, get the high 64-bits,
4545// determine if any lower bits are truncated, and use that to direct
4546// rounding. in case of a negative exponent relative to the significant
4547// digits (such as 1.2345), we create a theoretical representation of
4548// `b` as a big-integer type, scaled to the same binary exponent as
4549// the actual digits. we then compare the big integer representations
4550// of both, and use that to direct rounding.
4551template <typename T, typename UC>
4552inline SIMDJSON_FASTFLOAT_CONSTEXPR20 adjusted_mantissa
4553digit_comp(parsed_number_string_t<UC> &num, adjusted_mantissa am) noexcept {
4554 // remove the invalid exponent bias
4555 am.power2 -= invalid_am_bias;
4556
4557 int32_t sci_exp =
4558 scientific_exponent(num.mantissa, static_cast<int32_t>(num.exponent));
4559 size_t max_digits = binary_format<T>::max_digits();
4560 size_t digits = 0;
4561 bigint bigmant;
4562 parse_mantissa(bigmant, num, max_digits, digits);
4563 // can't underflow, since digits is at most max_digits.
4564 int32_t exponent = sci_exp + 1 - int32_t(digits);
4565 if (exponent >= 0) {
4566 return positive_digit_comp<T>(bigmant, exponent);
4567 } else {
4568 return negative_digit_comp<T>(bigmant, am, exponent);
4569 }
4570}
4571
4572} // namespace simdjson_fast_float
4573
4574#endif
4575
4576#ifndef SIMDJSON_FASTFLOAT_PARSE_NUMBER_H
4577#define SIMDJSON_FASTFLOAT_PARSE_NUMBER_H
4578
4579
4580#include <cmath>
4581#include <cstring>
4582#include <limits>
4583#include <system_error>
4584
4585namespace simdjson_fast_float {
4586
4587namespace detail {
4593template <typename T, typename UC>
4594from_chars_result_t<UC>
4595 SIMDJSON_FASTFLOAT_CONSTEXPR14 parse_infnan(UC const *first, UC const *last,
4596 T &value, chars_format fmt) noexcept {
4597 from_chars_result_t<UC> answer{};
4598 answer.ptr = first;
4599 answer.ec = std::errc(); // be optimistic
4600 // assume first < last, so dereference without checks;
4601 bool const minusSign = (*first == UC('-'));
4602 // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
4603 if ((*first == UC('-')) ||
4604 (uint64_t(fmt & chars_format::allow_leading_plus) &&
4605 (*first == UC('+')))) {
4606 ++first;
4607 }
4608 if (last - first >= 3) {
4609 if (simdjson_fastfloat_strncasecmp3(first, str_const_nan<UC>())) {
4610 answer.ptr = (first += 3);
4611 value = minusSign ? -std::numeric_limits<T>::quiet_NaN()
4612 : std::numeric_limits<T>::quiet_NaN();
4613 // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7,
4614 // C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan).
4615 if (first != last && *first == UC('(')) {
4616 for (UC const *ptr = first + 1; ptr != last; ++ptr) {
4617 if (*ptr == UC(')')) {
4618 answer.ptr = ptr + 1; // valid nan(n-char-seq-opt)
4619 break;
4620 } else if (!((UC('a') <= *ptr && *ptr <= UC('z')) ||
4621 (UC('A') <= *ptr && *ptr <= UC('Z')) ||
4622 (UC('0') <= *ptr && *ptr <= UC('9')) || *ptr == UC('_')))
4623 break; // forbidden char, not nan(n-char-seq-opt)
4624 }
4625 }
4626 return answer;
4627 }
4628 if (simdjson_fastfloat_strncasecmp3(first, str_const_inf<UC>())) {
4629 if ((last - first >= 8) &&
4630 simdjson_fastfloat_strncasecmp5(first + 3, str_const_inf<UC>() + 3)) {
4631 answer.ptr = first + 8;
4632 } else {
4633 answer.ptr = first + 3;
4634 }
4635 value = minusSign ? -std::numeric_limits<T>::infinity()
4636 : std::numeric_limits<T>::infinity();
4637 return answer;
4638 }
4639 }
4640 answer.ec = std::errc::invalid_argument;
4641 return answer;
4642}
4643
4649simdjson_fastfloat_really_inline bool rounds_to_nearest() noexcept {
4650 // https://lemire.me/blog/2020/06/26/gcc-not-nearest/
4651#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
4652 return false;
4653#endif
4654 // See
4655 // A fast function to check your floating-point rounding mode
4656 // https://lemire.me/blog/2022/11/16/a-fast-function-to-check-your-floating-point-rounding-mode/
4657 //
4658 // This function is meant to be equivalent to :
4659 // prior: #include <cfenv>
4660 // return fegetround() == FE_TONEAREST;
4661 // However, it is expected to be much faster than the fegetround()
4662 // function call.
4663 //
4664 // The volatile keyword prevents the compiler from computing the function
4665 // at compile-time.
4666 // There might be other ways to prevent compile-time optimizations (e.g.,
4667 // asm). The value does not need to be std::numeric_limits<float>::min(), any
4668 // small value so that 1 + x should round to 1 would do (after accounting for
4669 // excess precision, as in 387 instructions).
4670 static float volatile fmin = (std::numeric_limits<float>::min)();
4671 float fmini = fmin; // we copy it so that it gets loaded at most once.
4672//
4673// Explanation:
4674// Only when fegetround() == FE_TONEAREST do we have that
4675// fmin + 1.0f == 1.0f - fmin.
4676//
4677// FE_UPWARD:
4678// fmin + 1.0f > 1
4679// 1.0f - fmin == 1
4680//
4681// FE_DOWNWARD or FE_TOWARDZERO:
4682// fmin + 1.0f == 1
4683// 1.0f - fmin < 1
4684//
4685// Note: This may fail to be accurate if fast-math has been
4686// enabled, as rounding conventions may not apply.
4687#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
4688#pragma warning(push)
4689// todo: is there a VS warning?
4690// see
4691// https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013
4692#elif defined(__clang__)
4693#pragma clang diagnostic push
4694#pragma clang diagnostic ignored "-Wfloat-equal"
4695#elif defined(__GNUC__)
4696#pragma GCC diagnostic push
4697#pragma GCC diagnostic ignored "-Wfloat-equal"
4698#endif
4699 return (fmini + 1.0f == 1.0f - fmini);
4700#ifdef SIMDJSON_FASTFLOAT_VISUAL_STUDIO
4701#pragma warning(pop)
4702#elif defined(__clang__)
4703#pragma clang diagnostic pop
4704#elif defined(__GNUC__)
4705#pragma GCC diagnostic pop
4706#endif
4707}
4708
4709} // namespace detail
4710
4711template <typename T> struct from_chars_caller {
4712 template <typename UC>
4713 SIMDJSON_FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
4714 call(UC const *first, UC const *last, T &value,
4715 parse_options_t<UC> options) noexcept {
4716 return from_chars_advanced(first, last, value, options);
4717 }
4718};
4719
4720#ifdef __STDCPP_FLOAT32_T__
4721template <> struct from_chars_caller<std::float32_t> {
4722 template <typename UC>
4723 SIMDJSON_FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
4724 call(UC const *first, UC const *last, std::float32_t &value,
4725 parse_options_t<UC> options) noexcept {
4726 // if std::float32_t is defined, and we are in C++23 mode; macro set for
4727 // float32; set value to float due to equivalence between float and
4728 // float32_t
4729 float val = 0.0f;
4730 auto ret = from_chars_advanced(first, last, val, options);
4731 value = val;
4732 return ret;
4733 }
4734};
4735#endif
4736
4737#ifdef __STDCPP_FLOAT64_T__
4738template <> struct from_chars_caller<std::float64_t> {
4739 template <typename UC>
4740 SIMDJSON_FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
4741 call(UC const *first, UC const *last, std::float64_t &value,
4742 parse_options_t<UC> options) noexcept {
4743 // if std::float64_t is defined, and we are in C++23 mode; macro set for
4744 // float64; set value as double due to equivalence between double and
4745 // float64_t
4746 double val = 0.0;
4747 auto ret = from_chars_advanced(first, last, val, options);
4748 value = val;
4749 return ret;
4750 }
4751};
4752#endif
4753
4754template <typename T, typename UC, typename>
4755SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
4756from_chars(UC const *first, UC const *last, T &value,
4757 chars_format fmt /*= chars_format::general*/) noexcept {
4758 return from_chars_caller<T>::call(first, last, value,
4759 parse_options_t<UC>(fmt));
4760}
4761
4762template <typename T>
4763simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 bool
4764clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative,
4765 T &value) noexcept {
4766 // The implementation of the Clinger's fast path is convoluted because
4767 // we want round-to-nearest in all cases, irrespective of the rounding mode
4768 // selected on the thread.
4769 // We proceed optimistically, assuming that detail::rounds_to_nearest()
4770 // returns true.
4771 if (binary_format<T>::min_exponent_fast_path() <= exponent &&
4772 exponent <= binary_format<T>::max_exponent_fast_path() &&
4773 mantissa <= binary_format<T>::max_mantissa_fast_path()) {
4774 // The mantissa bound above is a necessary condition for BOTH branches
4775 // below: the rounding-mode-dependent branch checks the tighter
4776 // max_mantissa_fast_path(exponent) <= max_mantissa_fast_path(). Testing
4777 // it before detail::rounds_to_nearest() spares long-mantissa inputs
4778 // (which can never take the fast path) the volatile-float probe.
4779 //
4780 // Unfortunately, the conventional Clinger's fast path is only possible
4781 // when the system rounds to the nearest float.
4782 //
4783 // We expect the next branch to almost always be selected.
4784 // We could check it first (before the previous branch), but
4785 // there might be performance advantages at having the check
4786 // be last.
4787 if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
4788 // We have that fegetround() == FE_TONEAREST.
4789 // Next is Clinger's fast path.
4790 value = T(mantissa);
4791 if (exponent < 0) {
4792 value = value / binary_format<T>::exact_power_of_ten(-exponent);
4793 } else {
4794 value = value * binary_format<T>::exact_power_of_ten(exponent);
4795 }
4796 if (is_negative) {
4797 value = -value;
4798 }
4799 return true;
4800 } else {
4801 // We do not have that fegetround() == FE_TONEAREST.
4802 // Next is a modified Clinger's fast path, inspired by Jakub Jelinek's
4803 // proposal
4804 if (exponent >= 0 &&
4805 mantissa <= binary_format<T>::max_mantissa_fast_path(exponent)) {
4806#if defined(__clang__) || defined(SIMDJSON_FASTFLOAT_32BIT)
4807 // Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD
4808 if (mantissa == 0) {
4809 value = is_negative ? T(-0.) : T(0.);
4810 return true;
4811 }
4812#endif
4813 value = T(mantissa) * binary_format<T>::exact_power_of_ten(exponent);
4814 if (is_negative) {
4815 value = -value;
4816 }
4817 return true;
4818 }
4819 }
4820 }
4821 return false;
4822}
4823
4829template <typename T, typename UC>
4830simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
4831from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
4832 static_assert(is_supported_float_type<T>::value,
4833 "only some floating-point types are supported");
4834 static_assert(is_supported_char_type<UC>::value,
4835 "only char, wchar_t, char16_t and char32_t are supported");
4836
4837 from_chars_result_t<UC> answer;
4838
4839 answer.ec = std::errc(); // be optimistic
4840 answer.ptr = pns.lastmatch;
4841
4842 if (!pns.too_many_digits &&
4843 clinger_fast_path_impl(pns.mantissa, pns.exponent, pns.negative, value))
4844 return answer;
4845
4846 adjusted_mantissa am =
4847 compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
4848 if (pns.too_many_digits && am.power2 >= 0) {
4849 if (am != compute_float<binary_format<T>>(pns.exponent, pns.mantissa + 1)) {
4850 am = compute_error<binary_format<T>>(pns.exponent, pns.mantissa);
4851 }
4852 }
4853 // If we called compute_float<binary_format<T>>(pns.exponent, pns.mantissa)
4854 // and we have an invalid power (am.power2 < 0), then we need to go the long
4855 // way around again. This is very uncommon.
4856 if (am.power2 < 0) {
4857 am = digit_comp<T>(pns, am);
4858 }
4859 to_float(pns.negative, am, value);
4860 // Test for over/underflow.
4861 if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) ||
4862 am.power2 == binary_format<T>::infinite_power()) {
4863 answer.ec = std::errc::result_out_of_range;
4864 }
4865 return answer;
4866}
4867
4868// Slow path: re-parse materializing the integer/fraction spans the hot no-span
4869// parse skipped, then run the full algorithm. The two callers reach it only
4870// through a simdjson_fastfloat_unlikely branch, so the optimizer keeps this re-parse off
4871// the hot path on its own (no function-level noinline needed).
4872// from_chars_advanced already handles both the too_many_digits disambiguation
4873// and the am.power2<0 digit_comp recompute, so both slow branches collapse to
4874// one helper call.
4875template <typename T, typename UC>
4876SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
4877parse_number_slow_path(UC const *first, UC const *last, T &value,
4878 parse_options_t<UC> options, bool bjf) noexcept {
4879 parsed_number_string_t<UC> pns =
4880 bjf ? parse_number_string<true, UC>(first, last, options, true)
4881 : parse_number_string<false, UC>(first, last, options, true);
4882 return from_chars_advanced(pns, value);
4883}
4884
4885template <typename T, typename UC>
4886simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
4887from_chars_float_advanced(UC const *first, UC const *last, T &value,
4888 parse_options_t<UC> options) noexcept {
4889
4890 static_assert(is_supported_float_type<T>::value,
4891 "only some floating-point types are supported");
4892 static_assert(is_supported_char_type<UC>::value,
4893 "only char, wchar_t, char16_t and char32_t are supported");
4894
4895 chars_format const fmt = detail::adjust_for_feature_macros(options.format);
4896
4897 from_chars_result_t<UC> answer;
4898 if (uint64_t(fmt & chars_format::skip_white_space)) {
4899 while ((first != last) && simdjson_fast_float::is_space(*first)) {
4900 first++;
4901 }
4902 }
4903 if (first == last) {
4904 answer.ec = std::errc::invalid_argument;
4905 answer.ptr = first;
4906 return answer;
4907 }
4908 bool const bjf = uint64_t(fmt & detail::basic_json_fmt) != 0;
4909
4910 // Fast path: parse WITHOUT materializing the integer/fraction spans (read
4911 // only by the rare slow paths). Skipping their stores keeps the fat
4912 // parsed_number_string_t off the hot path. store_spans is a runtime argument,
4913 // so this reuses the single parse_number_string instantiation.
4914 parsed_number_string_t<UC> pns =
4915 bjf ? parse_number_string<true, UC>(first, last, options, false)
4916 : parse_number_string<false, UC>(first, last, options, false);
4917 if (!pns.valid) {
4918 if (uint64_t(fmt & chars_format::no_infnan)) {
4919 answer.ec = std::errc::invalid_argument;
4920 answer.ptr = first;
4921 return answer;
4922 } else {
4923 return detail::parse_infnan(first, last, value, fmt);
4924 }
4925 }
4926
4927 // Slow path A (rare): > 19 significant digits. The no-span parse left the
4928 // mantissa un-truncated and skipped the span-based recompute; the cold helper
4929 // re-parses with spans and runs the full algorithm.
4930 //
4931// We have to disable -Wc++20-extensions for the [[unlikely]] attribute
4932// See comment for @jwakely at
4933// https://github.com/fastfloat/simdjson_fast_float/pull/387#discussion_r3366943539
4934// This is unfortunate.
4935#ifdef __clang__
4936#pragma clang diagnostic push
4937#if (!defined(__APPLE_CC__) && __clang_major__ >= 10) || (__clang_major__ >= 13)
4938#pragma clang diagnostic ignored "-Wc++20-extensions"
4939#endif
4940#endif
4941 if simdjson_fastfloat_unlikely (pns.too_many_digits) {
4942 return parse_number_slow_path<T, UC>(first, last, value, options, bjf);
4943 }
4944 answer.ec = std::errc(); // be optimistic
4945 answer.ptr = pns.lastmatch;
4946
4947 if (clinger_fast_path_impl(pns.mantissa, pns.exponent, pns.negative, value)) {
4948 return answer;
4949 }
4950
4951 adjusted_mantissa am =
4952 compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
4953 // Slow path B (rare): Eisel-Lemire could not resolve; digit_comp needs the
4954 // integer/fraction spans. Route to the cold helper (clinger there is a
4955 // dead-effect since it already failed here; the cold re-parse + digit_comp
4956 // via from_chars_advanced reproduces this branch).
4957 if simdjson_fastfloat_unlikely (am.power2 < 0) {
4958 return parse_number_slow_path<T, UC>(first, last, value, options, bjf);
4959 }
4960#ifdef __clang__
4961#pragma clang diagnostic pop
4962#endif
4963 to_float(pns.negative, am, value);
4964 // Test for over/underflow.
4965 if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) ||
4966 am.power2 == binary_format<T>::infinite_power()) {
4967 answer.ec = std::errc::result_out_of_range;
4968 }
4969 return answer;
4970}
4971
4972template <typename T, typename UC, typename>
4973SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
4974from_chars(UC const *first, UC const *last, T &value, int base) noexcept {
4975
4976 static_assert(is_supported_integer_type<T>::value,
4977 "only integer types are supported");
4978 static_assert(is_supported_char_type<UC>::value,
4979 "only char, wchar_t, char16_t and char32_t are supported");
4980
4981 parse_options_t<UC> options;
4982 options.base = base;
4983 return from_chars_advanced(first, last, value, options);
4984}
4985
4986template <typename T>
4987SIMDJSON_FASTFLOAT_CONSTEXPR20
4988 typename std::enable_if<is_supported_float_type<T>::value, T>::type
4989 integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
4990 T value;
4991 if (clinger_fast_path_impl(mantissa, decimal_exponent, false, value))
4992 return value;
4993
4994 adjusted_mantissa am =
4995 compute_float<binary_format<T>>(decimal_exponent, mantissa);
4996 to_float(false, am, value);
4997 return value;
4998}
4999
5000template <typename T>
5001SIMDJSON_FASTFLOAT_CONSTEXPR20
5002 typename std::enable_if<is_supported_float_type<T>::value, T>::type
5003 integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
5004 const bool is_negative = mantissa < 0;
5005 const uint64_t m = static_cast<uint64_t>(is_negative ? -mantissa : mantissa);
5006
5007 T value;
5008 if (clinger_fast_path_impl(m, decimal_exponent, is_negative, value))
5009 return value;
5010
5011 adjusted_mantissa am = compute_float<binary_format<T>>(decimal_exponent, m);
5012 to_float(is_negative, am, value);
5013 return value;
5014}
5015
5016SIMDJSON_FASTFLOAT_CONSTEXPR20 inline double
5017integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
5018 return integer_times_pow10<double>(mantissa, decimal_exponent);
5019}
5020
5021SIMDJSON_FASTFLOAT_CONSTEXPR20 inline double
5022integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
5023 return integer_times_pow10<double>(mantissa, decimal_exponent);
5024}
5025
5026// the following overloads are here to avoid surprising ambiguity for int,
5027// unsigned, etc.
5028template <typename T, typename Int>
5029SIMDJSON_FASTFLOAT_CONSTEXPR20
5030 typename std::enable_if<is_supported_float_type<T>::value &&
5031 std::is_integral<Int>::value &&
5032 !std::is_signed<Int>::value,
5033 T>::type
5034 integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
5035 return integer_times_pow10<T>(static_cast<uint64_t>(mantissa),
5036 decimal_exponent);
5037}
5038
5039template <typename T, typename Int>
5040SIMDJSON_FASTFLOAT_CONSTEXPR20
5041 typename std::enable_if<is_supported_float_type<T>::value &&
5042 std::is_integral<Int>::value &&
5043 std::is_signed<Int>::value,
5044 T>::type
5045 integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
5046 return integer_times_pow10<T>(static_cast<int64_t>(mantissa),
5047 decimal_exponent);
5048}
5049
5050template <typename Int>
5051SIMDJSON_FASTFLOAT_CONSTEXPR20 typename std::enable_if<
5052 std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type
5053integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
5054 return integer_times_pow10(static_cast<uint64_t>(mantissa), decimal_exponent);
5055}
5056
5057template <typename Int>
5058SIMDJSON_FASTFLOAT_CONSTEXPR20 typename std::enable_if<
5059 std::is_integral<Int>::value && std::is_signed<Int>::value, double>::type
5060integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
5061 return integer_times_pow10(static_cast<int64_t>(mantissa), decimal_exponent);
5062}
5063
5064template <typename T, typename UC>
5065SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
5066from_chars_int_advanced(UC const *first, UC const *last, T &value,
5067 parse_options_t<UC> options) noexcept {
5068
5069 static_assert(is_supported_integer_type<T>::value,
5070 "only integer types are supported");
5071 static_assert(is_supported_char_type<UC>::value,
5072 "only char, wchar_t, char16_t and char32_t are supported");
5073
5074 chars_format const fmt = detail::adjust_for_feature_macros(options.format);
5075 int const base = options.base;
5076
5077 from_chars_result_t<UC> answer;
5078 if (uint64_t(fmt & chars_format::skip_white_space)) {
5079 while ((first != last) && simdjson_fast_float::is_space(*first)) {
5080 first++;
5081 }
5082 }
5083 if (first == last || base < 2 || base > 36) {
5084 answer.ec = std::errc::invalid_argument;
5085 answer.ptr = first;
5086 return answer;
5087 }
5088
5089 return parse_int_string(first, last, value, options);
5090}
5091
5092template <size_t TypeIx> struct from_chars_advanced_caller {
5093 static_assert(TypeIx > 0, "unsupported type");
5094};
5095
5096template <> struct from_chars_advanced_caller<1> {
5097 template <typename T, typename UC>
5098 simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
5099 call(UC const *first, UC const *last, T &value,
5100 parse_options_t<UC> options) noexcept {
5101 return from_chars_float_advanced(first, last, value, options);
5102 }
5103};
5104
5105template <> struct from_chars_advanced_caller<2> {
5106 template <typename T, typename UC>
5107 simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
5108 call(UC const *first, UC const *last, T &value,
5109 parse_options_t<UC> options) noexcept {
5110 return from_chars_int_advanced(first, last, value, options);
5111 }
5112};
5113
5114template <typename T, typename UC>
5115simdjson_fastfloat_really_inline SIMDJSON_FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
5116from_chars_advanced(UC const *first, UC const *last, T &value,
5117 parse_options_t<UC> options) noexcept {
5120 2 * size_t(is_supported_integer_type<T>::value)>::call(first, last, value,
5121 options);
5122}
5123
5124} // namespace simdjson_fast_float
5125
5126#endif
5127
UC decimal_point
The character used as decimal point.
Definition fast_float.h:244
chars_format format
Which number formats are accepted.
Definition fast_float.h:242
int base
The base used for integers.
Definition fast_float.h:246
When mapping numbers from decimal to binary, we go from w * 10^q to m * 2^p but we have 10^q = 5^q * ...