1#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H
3#ifndef SIMDJSON_CONDITIONAL_INCLUDE
4#define SIMDJSON_GENERIC_NUMBERPARSING_H
5#include "simdjson/generic/base.h"
6#include "simdjson/generic/jsoncharutils.h"
7#include "simdjson/internal/numberparsing_tables.h"
15namespace SIMDJSON_IMPLEMENTATION {
16namespace numberparsing {
18#ifdef JSON_TEST_NUMBERS
19#define INVALID_NUMBER(SRC) (found_invalid_number((SRC)), NUMBER_ERROR)
20#define WRITE_INTEGER(VALUE, SRC, WRITER) (found_integer((VALUE), (SRC)), (WRITER).append_s64((VALUE)))
21#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (found_unsigned_integer((VALUE), (SRC)), (WRITER).append_u64((VALUE)))
22#define WRITE_DOUBLE(VALUE, SRC, WRITER) (found_float((VALUE), (SRC)), (WRITER).append_double((VALUE)))
23#define BIGINT_NUMBER(SRC) (found_invalid_number((SRC)), BIGINT_ERROR)
25#define INVALID_NUMBER(SRC) (NUMBER_ERROR)
26#define WRITE_INTEGER(VALUE, SRC, WRITER) (WRITER).append_s64((VALUE))
27#define WRITE_UNSIGNED(VALUE, SRC, WRITER) (WRITER).append_u64((VALUE))
28#define WRITE_DOUBLE(VALUE, SRC, WRITER) (WRITER).append_double((VALUE))
29#define BIGINT_NUMBER(SRC) (BIGINT_ERROR)
37simdjson_inline
double to_double(uint64_t mantissa, uint64_t real_exponent,
bool negative) {
39 mantissa &= ~(1ULL << 52);
40 mantissa |= real_exponent << 52;
41 mantissa |= ((
static_cast<uint64_t
>(negative)) << 63);
42 std::memcpy(&d, &mantissa,
sizeof(d));
52simdjson_inline
bool compute_float_64(int64_t power, uint64_t i,
bool negative,
double &d) {
57#ifndef FLT_EVAL_METHOD
58#error "FLT_EVAL_METHOD should be defined, please include cfloat."
60#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
62 if (0 <= power && power <= 22 && i <= 9007199254740991)
64 if (-22 <= power && power <= 22 && i <= 9007199254740991)
81 d = d / simdjson::internal::power_of_ten[-power];
83 d = d * simdjson::internal::power_of_ten[power];
113 d = negative ? -0.0 : 0.0;
144 int64_t exponent = (((152170 + 65536) * power) >> 16) + 1024 + 63;
148 int lz = leading_zeroes(i);
163 const uint32_t index = 2 * uint32_t(power - simdjson::internal::smallest_power);
170 simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
182 if((firstproduct.high & 0x1FF) == 0x1FF) {
203 simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
204 firstproduct.low += secondproduct.high;
205 if(secondproduct.high > firstproduct.low) { firstproduct.high++; }
210 uint64_t lower = firstproduct.low;
211 uint64_t upper = firstproduct.high;
215 uint64_t upperbit = upper >> 63;
216 uint64_t mantissa = upper >> (upperbit + 9);
217 lz += int(1 ^ upperbit);
220 int64_t real_exponent = exponent - lz;
221 if (simdjson_unlikely(real_exponent <= 0)) {
223 if(-real_exponent + 1 >= 64) {
224 d = negative ? -0.0 : 0.0;
228 mantissa >>= -real_exponent + 1;
231 mantissa += (mantissa & 1);
240 real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1;
241 d = to_double(mantissa, real_exponent, negative);
266 if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) {
267 if((mantissa << (upperbit + 64 - 53 - 2)) == upper) {
272 mantissa += mantissa & 1;
276 if (mantissa >= (1ULL << 53)) {
280 mantissa = (1ULL << 52);
283 mantissa &= ~(1ULL << 52);
285 if (simdjson_unlikely(real_exponent > 2046)) {
289 d = to_double(mantissa, real_exponent, negative);
300static bool parse_float_fallback(
const uint8_t *ptr,
double *outDouble) {
301 *outDouble = simdjson::internal::from_chars(
reinterpret_cast<const char *
>(ptr));
312 return !(*outDouble > (std::numeric_limits<double>::max)() || *outDouble < std::numeric_limits<double>::lowest());
315static bool parse_float_fallback(
const uint8_t *ptr,
const uint8_t *end_ptr,
double *outDouble) {
316 *outDouble = simdjson::internal::from_chars(
reinterpret_cast<const char *
>(ptr),
reinterpret_cast<const char *
>(end_ptr));
327 return !(*outDouble > (std::numeric_limits<double>::max)() || *outDouble < std::numeric_limits<double>::lowest());
333simdjson_inline
bool is_made_of_eight_digits_fast(
const uint8_t *chars) {
337 static_assert(7 <=
SIMDJSON_PADDING,
"SIMDJSON_PADDING must be bigger than 7");
338 std::memcpy(&val, chars, 8);
343 return (((val & 0xF0F0F0F0F0F0F0F0) |
344 (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) ==
349SIMDJSON_NO_SANITIZE_UNDEFINED
350simdjson_inline
bool parse_digit(
const uint8_t c, I &i) {
351 const uint8_t digit =
static_cast<uint8_t
>(c -
'0');
360simdjson_inline
bool is_digit(
const uint8_t c) {
361 return static_cast<uint8_t
>(c -
'0') <= 9;
364simdjson_warn_unused simdjson_inline
error_code parse_decimal_after_separator(simdjson_unused
const uint8_t *
const src,
const uint8_t *&p, uint64_t &i, int64_t &exponent) {
369 const uint8_t *
const first_after_period = p;
371#ifdef SIMDJSON_SWAR_NUMBER_PARSING
372#if SIMDJSON_SWAR_NUMBER_PARSING
375 if (is_made_of_eight_digits_fast(p)) {
376 i = i * 100000000 + parse_eight_digits_unrolled(p);
382 if (parse_digit(*p, i)) { ++p; }
383 while (parse_digit(*p, i)) { p++; }
384 exponent = first_after_period - p;
387 return INVALID_NUMBER(src);
392simdjson_warn_unused simdjson_inline
error_code parse_exponent(simdjson_unused
const uint8_t *
const src,
const uint8_t *&p, int64_t &exponent) {
394 bool neg_exp = (
'-' == *p);
395 if (neg_exp ||
'+' == *p) { p++; }
399 int64_t exp_number = 0;
400 while (parse_digit(*p, exp_number)) { ++p; }
412 if (simdjson_unlikely(p == start_exp)) {
413 return INVALID_NUMBER(src);
420 if (simdjson_unlikely(p > start_exp+18)) {
422 while (*start_exp ==
'0') { start_exp++; }
432 if (p > start_exp+18) { exp_number = 999999999999999999; }
439 exponent += (neg_exp ? -exp_number : exp_number);
443simdjson_inline
bool check_if_integer(
const uint8_t *
const src,
size_t max_length) {
444 const uint8_t *
const srcend = src + max_length;
445 bool negative = (*src ==
'-');
446 const uint8_t *p = src + uint8_t(negative);
447 if(p == srcend) {
return false; }
450 if(p == srcend) {
return true; }
451 if(jsoncharutils::is_not_structural_or_whitespace(*p)) {
return false; }
454 while(p != srcend && is_digit(*p)) { ++p; }
455 if(p == srcend) {
return true; }
456 if(jsoncharutils::is_not_structural_or_whitespace(*p)) {
return false; }
460simdjson_inline
size_t significant_digits(
const uint8_t * start_digits,
size_t digit_count) {
463 const uint8_t *start = start_digits;
464 while ((*start ==
'0') || (*start ==
'.')) { ++start; }
466 return digit_count - size_t(start - start_digits);
472static error_code slow_float_parsing(simdjson_unused
const uint8_t * src,
double* answer) {
473 if (parse_float_fallback(src, answer)) {
476 return INVALID_NUMBER(src);
481simdjson_warn_unused simdjson_inline
error_code write_float(
const uint8_t *
const src,
bool negative, uint64_t i,
const uint8_t * start_digits,
size_t digit_count, int64_t exponent, W &writer) {
489 if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) {
502 error_code error = slow_float_parsing(src, &d);
503 writer.append_double(d);
509 if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) {
514 static_assert(simdjson::internal::smallest_power <= -342,
"smallest_power is not small enough");
516 if((exponent < simdjson::internal::smallest_power) || (i == 0)) {
518 WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer);
522 return INVALID_NUMBER(src);
526 if (!compute_float_64(exponent, i, negative, d)) {
528 if (!parse_float_fallback(src, &d)) {
return INVALID_NUMBER(src); }
530 WRITE_DOUBLE(d, src, writer);
544simdjson_warn_unused simdjson_inline
error_code parse_number(
const uint8_t *
const src, W &writer);
547#ifdef SIMDJSON_SKIPNUMBERPARSING
550simdjson_warn_unused simdjson_inline
error_code parse_number(
const uint8_t *
const, W &writer) {
551 writer.append_s64(0);
555simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src)
noexcept {
return 0; }
556simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *
const src)
noexcept {
return 0; }
557simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t *
const src)
noexcept {
return 0; }
558simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned_in_string(
const uint8_t *
const src)
noexcept {
return 0; }
559simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer_in_string(
const uint8_t *
const src)
noexcept {
return 0; }
560simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(
const uint8_t *
const src)
noexcept {
return 0; }
561simdjson_unused simdjson_inline
bool is_negative(
const uint8_t * src)
noexcept {
return false; }
562simdjson_unused simdjson_inline simdjson_result<bool> is_integer(
const uint8_t * src)
noexcept {
return false; }
563simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(
const uint8_t * src)
noexcept {
return number_type::signed_integer; }
576simdjson_warn_unused simdjson_inline
error_code parse_number(
const uint8_t *
const src, W &writer) {
580 bool negative = (*src ==
'-');
581 const uint8_t *p = src + uint8_t(negative);
587 const uint8_t *
const start_digits = p;
589 while (parse_digit(*p, i)) { p++; }
593 size_t digit_count = size_t(p - start_digits);
594 if (digit_count == 0 || (
'0' == *start_digits && digit_count > 1)) {
return INVALID_NUMBER(src); }
599 int64_t exponent = 0;
600 bool is_float =
false;
604 SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) );
605 digit_count = int(p - start_digits);
607 if ((
'e' == *p) || (
'E' == *p)) {
610 SIMDJSON_TRY( parse_exponent(src, p, exponent) );
613 const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p);
614 SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) );
615 if (dirty_end) {
return INVALID_NUMBER(src); }
622 size_t longest_digit_count = negative ? 19 : 20;
623 if (digit_count > longest_digit_count) {
return BIGINT_NUMBER(src); }
624 if (digit_count == longest_digit_count) {
627 if (i > uint64_t(INT64_MAX)+1) {
return BIGINT_NUMBER(src); }
628 WRITE_INTEGER(~i+1, src, writer);
629 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return INVALID_NUMBER(src); }
643 }
else if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INVALID_NUMBER(src); }
647 if (i > uint64_t(INT64_MAX)) {
648 WRITE_UNSIGNED(i, src, writer);
650#if SIMDJSON_MINUS_ZERO_AS_FLOAT
651 if(i == 0 && negative) {
653 WRITE_DOUBLE(-0.0, src, writer);
655 WRITE_INTEGER(negative ? (~i+1) : i, src, writer);
658 WRITE_INTEGER(negative ? (~i+1) : i, src, writer);
661 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return INVALID_NUMBER(src); }
679const uint8_t integer_string_finisher[256] = {
734simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src)
noexcept {
735 const uint8_t *p = src;
740 const uint8_t *
const start_digits = p;
742 while (parse_digit(*p, i)) { p++; }
746 size_t digit_count = size_t(p - start_digits);
752 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
754 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
760 if (integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
762 if (digit_count == 20) {
775 if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
784simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src,
const uint8_t *
const src_end)
noexcept {
785 const uint8_t *p = src;
790 const uint8_t *
const start_digits = p;
792 while ((p != src_end) && parse_digit(*p, i)) { p++; }
796 size_t digit_count = size_t(p - start_digits);
802 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
804 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
810 if ((p != src_end) && integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
812 if (digit_count == 20) {
825 if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
832simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned_in_string(
const uint8_t *
const src)
noexcept {
833 const uint8_t *p = src + 1;
838 const uint8_t *
const start_digits = p;
840 while (parse_digit(*p, i)) { p++; }
844 size_t digit_count = size_t(p - start_digits);
850 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
852 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
860 if (digit_count == 20) {
875 if (src[1] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
882simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *src)
noexcept {
886 bool negative = (*src ==
'-');
887 const uint8_t *p = src + uint8_t(negative);
893 const uint8_t *
const start_digits = p;
895 while (parse_digit(*p, i)) { p++; }
899 size_t digit_count = size_t(p - start_digits);
903 size_t longest_digit_count = 19;
907 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
909 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
915 if(integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
919 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
920 return negative ? (~i+1) : i;
925simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *
const src,
const uint8_t *
const src_end)
noexcept {
930 bool negative = (*src ==
'-');
931 const uint8_t *p = src + uint8_t(negative);
937 const uint8_t *
const start_digits = p;
939 while ((p != src_end) && parse_digit(*p, i)) { p++; }
943 size_t digit_count = size_t(p - start_digits);
947 size_t longest_digit_count = 19;
951 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
953 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
959 if((p != src_end) && integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
963 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
964 return negative ? (~i+1) : i;
968simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer_in_string(
const uint8_t *src)
noexcept {
972 bool negative = (*(src + 1) ==
'-');
973 src += uint8_t(negative) + 1;
979 const uint8_t *
const start_digits = src;
981 while (parse_digit(*src, i)) { src++; }
985 size_t digit_count = size_t(src - start_digits);
989 size_t longest_digit_count = 19;
993 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
995 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
1005 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
1006 return negative ? (~i+1) : i;
1009simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t * src)
noexcept {
1013 bool negative = (*src ==
'-');
1014 src += uint8_t(negative);
1020 const uint8_t *p = src;
1021 p += parse_digit(*p, i);
1022 bool leading_zero = (i == 0);
1023 while (parse_digit(*p, i)) { p++; }
1026 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1031 int64_t exponent = 0;
1033 if (simdjson_likely(*p ==
'.')) {
1035 const uint8_t *start_decimal_digits = p;
1038 while (parse_digit(*p, i)) { p++; }
1039 exponent = -(p - start_decimal_digits);
1042 overflow = p-src-1 > 19;
1043 if (simdjson_unlikely(overflow && leading_zero)) {
1045 const uint8_t *start_digits = src + 2;
1046 while (*start_digits ==
'0') { start_digits++; }
1047 overflow = p-start_digits > 19;
1050 overflow = p-src > 19;
1056 if (*p ==
'e' || *p ==
'E') {
1058 bool exp_neg = *p ==
'-';
1059 p += exp_neg || *p ==
'+';
1062 const uint8_t *start_exp_digits = p;
1063 while (parse_digit(*p, exp)) { p++; }
1065 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1067 exponent += exp_neg ? 0-exp : exp;
1070 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return NUMBER_ERROR; }
1072 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1078 if (simdjson_likely(!overflow)) {
1079 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1081 if (!parse_float_fallback(src - uint8_t(negative), &d)) {
1087simdjson_unused simdjson_inline
bool is_negative(
const uint8_t * src)
noexcept {
1088 return (*src ==
'-');
1091simdjson_unused simdjson_inline simdjson_result<bool> is_integer(
const uint8_t * src)
noexcept {
1092 bool negative = (*src ==
'-');
1093 src += uint8_t(negative);
1094 const uint8_t *p = src;
1095 while(
static_cast<uint8_t
>(*p -
'0') <= 9) { p++; }
1097 if (jsoncharutils::is_structural_or_whitespace(*p)) {
return true; }
1101simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(
const uint8_t * src)
noexcept {
1102 bool negative = (*src ==
'-');
1103 src += uint8_t(negative);
1104 const uint8_t *p = src;
1105 while(
static_cast<uint8_t
>(*p -
'0') <= 9) { p++; }
1106 size_t digit_count = size_t(p - src);
1108 if (jsoncharutils::is_structural_or_whitespace(*p)) {
1109 static const uint8_t * smaller_big_integer =
reinterpret_cast<const uint8_t *
>(
"9223372036854775808");
1111 if(simdjson_unlikely(digit_count > 20)) {
1112 return number_type::big_integer;
1116 if (simdjson_unlikely(digit_count > 19))
return number_type::big_integer;
1117 if (simdjson_unlikely(digit_count == 19 && memcmp(src, smaller_big_integer, 19) > 0)) {
1118 return number_type::big_integer;
1120#if SIMDJSON_MINUS_ZERO_AS_FLOAT
1121 if(digit_count == 1 && src[0] ==
'0') {
1123 return number_type::floating_point_number;
1126 return number_type::signed_integer;
1129 static const uint8_t * two_to_sixtyfour =
reinterpret_cast<const uint8_t *
>(
"18446744073709551616");
1130 if((digit_count > 20) || (digit_count == 20 && memcmp(src, two_to_sixtyfour, 20) >= 0)) {
1131 return number_type::big_integer;
1136 if((digit_count == 20) || (digit_count >= 19 && memcmp(src, smaller_big_integer, 19) >= 0)) {
1137 return number_type::unsigned_integer;
1139 return number_type::signed_integer;
1142 return number_type::floating_point_number;
1146simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t * src,
const uint8_t *
const src_end)
noexcept {
1151 bool negative = (*src ==
'-');
1152 src += uint8_t(negative);
1158 const uint8_t *p = src;
1160 p += parse_digit(*p, i);
1161 bool leading_zero = (i == 0);
1162 while ((p != src_end) && parse_digit(*p, i)) { p++; }
1165 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1170 int64_t exponent = 0;
1172 if (simdjson_likely((p != src_end) && (*p ==
'.'))) {
1174 const uint8_t *start_decimal_digits = p;
1175 if ((p == src_end) || !parse_digit(*p, i)) {
return NUMBER_ERROR; }
1177 while ((p != src_end) && parse_digit(*p, i)) { p++; }
1178 exponent = -(p - start_decimal_digits);
1181 overflow = p-src-1 > 19;
1182 if (simdjson_unlikely(overflow && leading_zero)) {
1184 const uint8_t *start_digits = src + 2;
1185 while (*start_digits ==
'0') { start_digits++; }
1186 overflow = start_digits-src > 19;
1189 overflow = p-src > 19;
1195 if ((p != src_end) && (*p ==
'e' || *p ==
'E')) {
1198 bool exp_neg = *p ==
'-';
1199 p += exp_neg || *p ==
'+';
1202 const uint8_t *start_exp_digits = p;
1203 while ((p != src_end) && parse_digit(*p, exp)) { p++; }
1205 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1207 exponent += exp_neg ? 0-exp : exp;
1210 if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) {
return NUMBER_ERROR; }
1212 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1218 if (simdjson_likely(!overflow)) {
1219 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1221 if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) {
1227simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(
const uint8_t * src)
noexcept {
1231 bool negative = (*(src + 1) ==
'-');
1232 src += uint8_t(negative) + 1;
1238 const uint8_t *p = src;
1239 p += parse_digit(*p, i);
1240 bool leading_zero = (i == 0);
1241 while (parse_digit(*p, i)) { p++; }
1244 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1249 int64_t exponent = 0;
1251 if (simdjson_likely(*p ==
'.')) {
1253 const uint8_t *start_decimal_digits = p;
1256 while (parse_digit(*p, i)) { p++; }
1257 exponent = -(p - start_decimal_digits);
1260 overflow = p-src-1 > 19;
1261 if (simdjson_unlikely(overflow && leading_zero)) {
1263 const uint8_t *start_digits = src + 2;
1264 while (*start_digits ==
'0') { start_digits++; }
1265 overflow = p-start_digits > 19;
1268 overflow = p-src > 19;
1274 if (*p ==
'e' || *p ==
'E') {
1276 bool exp_neg = *p ==
'-';
1277 p += exp_neg || *p ==
'+';
1280 const uint8_t *start_exp_digits = p;
1281 while (parse_digit(*p, exp)) { p++; }
1283 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1285 exponent += exp_neg ? 0-exp : exp;
1290 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1296 if (simdjson_likely(!overflow)) {
1297 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1299 if (!parse_float_fallback(src - uint8_t(negative), &d)) {
1310inline std::ostream& operator<<(std::ostream& out, number_type type)
noexcept {
1312 case number_type::signed_integer: out <<
"integer in [-9223372036854775808,9223372036854775808)";
break;
1313 case number_type::unsigned_integer: out <<
"unsigned integer in [9223372036854775808,18446744073709551616)";
break;
1314 case number_type::floating_point_number: out <<
"floating-point number (binary64)";
break;
1315 case number_type::big_integer: out <<
"big integer";
break;
1316 default: SIMDJSON_UNREACHABLE();
The top level simdjson namespace, containing everything the library provides.
error_code
All possible errors returned by simdjson.
@ INCORRECT_TYPE
JSON element has a different type than user expected.
@ NUMBER_ERROR
Problem while parsing a number.
constexpr size_t SIMDJSON_PADDING
The amount of padding needed in a buffer to parse JSON.