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"
15 namespace SIMDJSON_IMPLEMENTATION {
16 namespace 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)
37 simdjson_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));
52 simdjson_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);
300 static 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());
315 static 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());
333 simdjson_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)) ==
349 SIMDJSON_NO_SANITIZE_UNDEFINED
350 simdjson_inline
bool parse_digit(
const uint8_t c, I &i) {
351 const uint8_t digit =
static_cast<uint8_t
>(c -
'0');
360 simdjson_inline
bool is_digit(
const uint8_t c) {
361 return static_cast<uint8_t
>(c -
'0') <= 9;
364 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);
392 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);
443 simdjson_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; }
460 simdjson_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);
472 static 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);
481 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);
544 simdjson_inline
error_code parse_number(
const uint8_t *
const src, W &writer);
547 #ifdef SIMDJSON_SKIPNUMBERPARSING
550 simdjson_inline
error_code parse_number(
const uint8_t *
const, W &writer) {
551 writer.append_s64(0);
555 simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src) noexcept {
return 0; }
556 simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *
const src) noexcept {
return 0; }
557 simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t *
const src) noexcept {
return 0; }
558 simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned_in_string(
const uint8_t *
const src) noexcept {
return 0; }
559 simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer_in_string(
const uint8_t *
const src) noexcept {
return 0; }
560 simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(
const uint8_t *
const src) noexcept {
return 0; }
561 simdjson_unused simdjson_inline
bool is_negative(
const uint8_t * src) noexcept {
return false; }
562 simdjson_unused simdjson_inline simdjson_result<bool> is_integer(
const uint8_t * src) noexcept {
return false; }
563 simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(
const uint8_t * src) noexcept {
return number_type::signed_integer; }
576 simdjson_inline
error_code parse_number(
const uint8_t *
const src, W &writer) {
581 bool negative = (*src ==
'-');
582 const uint8_t *p = src + uint8_t(negative);
588 const uint8_t *
const start_digits = p;
590 while (parse_digit(*p, i)) { p++; }
594 size_t digit_count = size_t(p - start_digits);
595 if (digit_count == 0 || (
'0' == *start_digits && digit_count > 1)) {
return INVALID_NUMBER(src); }
600 int64_t exponent = 0;
601 bool is_float =
false;
605 SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) );
606 digit_count = int(p - start_digits);
608 if ((
'e' == *p) || (
'E' == *p)) {
611 SIMDJSON_TRY( parse_exponent(src, p, exponent) );
614 const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p);
615 SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) );
616 if (dirty_end) {
return INVALID_NUMBER(src); }
623 size_t longest_digit_count = negative ? 19 : 20;
624 if (digit_count > longest_digit_count) {
return BIGINT_NUMBER(src); }
625 if (digit_count == longest_digit_count) {
628 if (i > uint64_t(INT64_MAX)+1) {
return BIGINT_NUMBER(src); }
629 WRITE_INTEGER(~i+1, src, writer);
630 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return INVALID_NUMBER(src); }
644 }
else if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INVALID_NUMBER(src); }
648 if (i > uint64_t(INT64_MAX)) {
649 WRITE_UNSIGNED(i, src, writer);
651 WRITE_INTEGER(negative ? (~i+1) : i, src, writer);
653 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return INVALID_NUMBER(src); }
671 const uint8_t integer_string_finisher[256] = {
726 simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src) noexcept {
727 const uint8_t *p = src;
732 const uint8_t *
const start_digits = p;
734 while (parse_digit(*p, i)) { p++; }
738 size_t digit_count = size_t(p - start_digits);
744 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
746 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
752 if (integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
754 if (digit_count == 20) {
767 if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
776 simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src,
const uint8_t *
const src_end) noexcept {
777 const uint8_t *p = src;
782 const uint8_t *
const start_digits = p;
784 while ((p != src_end) && parse_digit(*p, i)) { p++; }
788 size_t digit_count = size_t(p - start_digits);
794 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
796 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
802 if ((p != src_end) && integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
804 if (digit_count == 20) {
817 if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
824 simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned_in_string(
const uint8_t *
const src) noexcept {
825 const uint8_t *p = src + 1;
830 const uint8_t *
const start_digits = p;
832 while (parse_digit(*p, i)) { p++; }
836 size_t digit_count = size_t(p - start_digits);
842 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
844 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
852 if (digit_count == 20) {
867 if (src[1] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
874 simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *src) noexcept {
878 bool negative = (*src ==
'-');
879 const uint8_t *p = src + uint8_t(negative);
885 const uint8_t *
const start_digits = p;
887 while (parse_digit(*p, i)) { p++; }
891 size_t digit_count = size_t(p - start_digits);
895 size_t longest_digit_count = 19;
899 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
901 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
907 if(integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
911 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
912 return negative ? (~i+1) : i;
917 simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *
const src,
const uint8_t *
const src_end) noexcept {
922 bool negative = (*src ==
'-');
923 const uint8_t *p = src + uint8_t(negative);
929 const uint8_t *
const start_digits = p;
931 while ((p != src_end) && parse_digit(*p, i)) { p++; }
935 size_t digit_count = size_t(p - start_digits);
939 size_t longest_digit_count = 19;
943 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
945 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
951 if((p != src_end) && integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
955 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
956 return negative ? (~i+1) : i;
960 simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer_in_string(
const uint8_t *src) noexcept {
964 bool negative = (*(src + 1) ==
'-');
965 src += uint8_t(negative) + 1;
971 const uint8_t *
const start_digits = src;
973 while (parse_digit(*src, i)) { src++; }
977 size_t digit_count = size_t(src - start_digits);
981 size_t longest_digit_count = 19;
985 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
987 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
997 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
998 return negative ? (~i+1) : i;
1001 simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t * src) noexcept {
1005 bool negative = (*src ==
'-');
1006 src += uint8_t(negative);
1012 const uint8_t *p = src;
1013 p += parse_digit(*p, i);
1014 bool leading_zero = (i == 0);
1015 while (parse_digit(*p, i)) { p++; }
1018 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1023 int64_t exponent = 0;
1025 if (simdjson_likely(*p ==
'.')) {
1027 const uint8_t *start_decimal_digits = p;
1030 while (parse_digit(*p, i)) { p++; }
1031 exponent = -(p - start_decimal_digits);
1034 overflow = p-src-1 > 19;
1035 if (simdjson_unlikely(overflow && leading_zero)) {
1037 const uint8_t *start_digits = src + 2;
1038 while (*start_digits ==
'0') { start_digits++; }
1039 overflow = p-start_digits > 19;
1042 overflow = p-src > 19;
1048 if (*p ==
'e' || *p ==
'E') {
1050 bool exp_neg = *p ==
'-';
1051 p += exp_neg || *p ==
'+';
1054 const uint8_t *start_exp_digits = p;
1055 while (parse_digit(*p, exp)) { p++; }
1057 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1059 exponent += exp_neg ? 0-exp : exp;
1062 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return NUMBER_ERROR; }
1064 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1070 if (simdjson_likely(!overflow)) {
1071 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1073 if (!parse_float_fallback(src - uint8_t(negative), &d)) {
1079 simdjson_unused simdjson_inline
bool is_negative(
const uint8_t * src) noexcept {
1080 return (*src ==
'-');
1083 simdjson_unused simdjson_inline simdjson_result<bool> is_integer(
const uint8_t * src) noexcept {
1084 bool negative = (*src ==
'-');
1085 src += uint8_t(negative);
1086 const uint8_t *p = src;
1087 while(
static_cast<uint8_t
>(*p -
'0') <= 9) { p++; }
1089 if (jsoncharutils::is_structural_or_whitespace(*p)) {
return true; }
1093 simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(
const uint8_t * src) noexcept {
1094 bool negative = (*src ==
'-');
1095 src += uint8_t(negative);
1096 const uint8_t *p = src;
1097 while(
static_cast<uint8_t
>(*p -
'0') <= 9) { p++; }
1098 size_t digit_count = size_t(p - src);
1100 if (jsoncharutils::is_structural_or_whitespace(*p)) {
1101 static const uint8_t * smaller_big_integer =
reinterpret_cast<const uint8_t *
>(
"9223372036854775808");
1103 if(simdjson_unlikely(digit_count > 20)) {
1104 return number_type::big_integer;
1108 if (simdjson_unlikely(digit_count > 19))
return number_type::big_integer;
1109 if (simdjson_unlikely(digit_count == 19 && memcmp(src, smaller_big_integer, 19) > 0)) {
1110 return number_type::big_integer;
1112 return number_type::signed_integer;
1115 static const uint8_t * two_to_sixtyfour =
reinterpret_cast<const uint8_t *
>(
"18446744073709551616");
1116 if((digit_count > 20) || (digit_count == 20 && memcmp(src, two_to_sixtyfour, 20) >= 0)) {
1117 return number_type::big_integer;
1122 if((digit_count == 20) || (digit_count >= 19 && memcmp(src, smaller_big_integer, 19) >= 0)) {
1123 return number_type::unsigned_integer;
1125 return number_type::signed_integer;
1128 return number_type::floating_point_number;
1132 simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t * src,
const uint8_t *
const src_end) noexcept {
1137 bool negative = (*src ==
'-');
1138 src += uint8_t(negative);
1144 const uint8_t *p = src;
1146 p += parse_digit(*p, i);
1147 bool leading_zero = (i == 0);
1148 while ((p != src_end) && parse_digit(*p, i)) { p++; }
1151 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1156 int64_t exponent = 0;
1158 if (simdjson_likely((p != src_end) && (*p ==
'.'))) {
1160 const uint8_t *start_decimal_digits = p;
1161 if ((p == src_end) || !parse_digit(*p, i)) {
return NUMBER_ERROR; }
1163 while ((p != src_end) && parse_digit(*p, i)) { p++; }
1164 exponent = -(p - start_decimal_digits);
1167 overflow = p-src-1 > 19;
1168 if (simdjson_unlikely(overflow && leading_zero)) {
1170 const uint8_t *start_digits = src + 2;
1171 while (*start_digits ==
'0') { start_digits++; }
1172 overflow = start_digits-src > 19;
1175 overflow = p-src > 19;
1181 if ((p != src_end) && (*p ==
'e' || *p ==
'E')) {
1184 bool exp_neg = *p ==
'-';
1185 p += exp_neg || *p ==
'+';
1188 const uint8_t *start_exp_digits = p;
1189 while ((p != src_end) && parse_digit(*p, exp)) { p++; }
1191 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1193 exponent += exp_neg ? 0-exp : exp;
1196 if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) {
return NUMBER_ERROR; }
1198 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1204 if (simdjson_likely(!overflow)) {
1205 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1207 if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) {
1213 simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(
const uint8_t * src) noexcept {
1217 bool negative = (*(src + 1) ==
'-');
1218 src += uint8_t(negative) + 1;
1224 const uint8_t *p = src;
1225 p += parse_digit(*p, i);
1226 bool leading_zero = (i == 0);
1227 while (parse_digit(*p, i)) { p++; }
1230 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1235 int64_t exponent = 0;
1237 if (simdjson_likely(*p ==
'.')) {
1239 const uint8_t *start_decimal_digits = p;
1242 while (parse_digit(*p, i)) { p++; }
1243 exponent = -(p - start_decimal_digits);
1246 overflow = p-src-1 > 19;
1247 if (simdjson_unlikely(overflow && leading_zero)) {
1249 const uint8_t *start_digits = src + 2;
1250 while (*start_digits ==
'0') { start_digits++; }
1251 overflow = p-start_digits > 19;
1254 overflow = p-src > 19;
1260 if (*p ==
'e' || *p ==
'E') {
1262 bool exp_neg = *p ==
'-';
1263 p += exp_neg || *p ==
'+';
1266 const uint8_t *start_exp_digits = p;
1267 while (parse_digit(*p, exp)) { p++; }
1269 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1271 exponent += exp_neg ? 0-exp : exp;
1276 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1282 if (simdjson_likely(!overflow)) {
1283 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1285 if (!parse_float_fallback(src - uint8_t(negative), &d)) {
1296 inline std::ostream&
operator<<(std::ostream& out, number_type type) noexcept {
1298 case number_type::signed_integer: out <<
"integer in [-9223372036854775808,9223372036854775808)";
break;
1299 case number_type::unsigned_integer: out <<
"unsigned integer in [9223372036854775808,18446744073709551616)";
break;
1300 case number_type::floating_point_number: out <<
"floating-point number (binary64)";
break;
1301 case number_type::big_integer: out <<
"big integer";
break;
1302 default: SIMDJSON_UNREACHABLE();
The top level simdjson namespace, containing everything the library provides.
std::ostream & operator<<(std::ostream &out, error_code error) noexcept
Write the error message to the output stream.
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.