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) {
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 WRITE_INTEGER(negative ? (~i+1) : i, src, writer);
652 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return INVALID_NUMBER(src); }
670 const uint8_t integer_string_finisher[256] = {
725 simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src) noexcept {
726 const uint8_t *p = src;
731 const uint8_t *
const start_digits = p;
733 while (parse_digit(*p, i)) { p++; }
737 size_t digit_count = size_t(p - start_digits);
743 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
745 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
751 if (integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
753 if (digit_count == 20) {
766 if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
775 simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src,
const uint8_t *
const src_end) noexcept {
776 const uint8_t *p = src;
781 const uint8_t *
const start_digits = p;
783 while ((p != src_end) && parse_digit(*p, i)) { p++; }
787 size_t digit_count = size_t(p - start_digits);
793 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
795 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
801 if ((p != src_end) && integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
803 if (digit_count == 20) {
816 if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
823 simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned_in_string(
const uint8_t *
const src) noexcept {
824 const uint8_t *p = src + 1;
829 const uint8_t *
const start_digits = p;
831 while (parse_digit(*p, i)) { p++; }
835 size_t digit_count = size_t(p - start_digits);
841 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
843 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
851 if (digit_count == 20) {
866 if (src[1] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
873 simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *src) noexcept {
877 bool negative = (*src ==
'-');
878 const uint8_t *p = src + uint8_t(negative);
884 const uint8_t *
const start_digits = p;
886 while (parse_digit(*p, i)) { p++; }
890 size_t digit_count = size_t(p - start_digits);
894 size_t longest_digit_count = 19;
898 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
900 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
906 if(integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
910 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
911 return negative ? (~i+1) : i;
916 simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *
const src,
const uint8_t *
const src_end) noexcept {
921 bool negative = (*src ==
'-');
922 const uint8_t *p = src + uint8_t(negative);
928 const uint8_t *
const start_digits = p;
930 while ((p != src_end) && parse_digit(*p, i)) { p++; }
934 size_t digit_count = size_t(p - start_digits);
938 size_t longest_digit_count = 19;
942 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
944 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
950 if((p != src_end) && integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
954 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
955 return negative ? (~i+1) : i;
959 simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer_in_string(
const uint8_t *src) noexcept {
963 bool negative = (*(src + 1) ==
'-');
964 src += uint8_t(negative) + 1;
970 const uint8_t *
const start_digits = src;
972 while (parse_digit(*src, i)) { src++; }
976 size_t digit_count = size_t(src - start_digits);
980 size_t longest_digit_count = 19;
984 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
986 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
996 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
997 return negative ? (~i+1) : i;
1000 simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t * src) noexcept {
1004 bool negative = (*src ==
'-');
1005 src += uint8_t(negative);
1011 const uint8_t *p = src;
1012 p += parse_digit(*p, i);
1013 bool leading_zero = (i == 0);
1014 while (parse_digit(*p, i)) { p++; }
1017 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1022 int64_t exponent = 0;
1024 if (simdjson_likely(*p ==
'.')) {
1026 const uint8_t *start_decimal_digits = p;
1029 while (parse_digit(*p, i)) { p++; }
1030 exponent = -(p - start_decimal_digits);
1033 overflow = p-src-1 > 19;
1034 if (simdjson_unlikely(overflow && leading_zero)) {
1036 const uint8_t *start_digits = src + 2;
1037 while (*start_digits ==
'0') { start_digits++; }
1038 overflow = p-start_digits > 19;
1041 overflow = p-src > 19;
1047 if (*p ==
'e' || *p ==
'E') {
1049 bool exp_neg = *p ==
'-';
1050 p += exp_neg || *p ==
'+';
1053 const uint8_t *start_exp_digits = p;
1054 while (parse_digit(*p, exp)) { p++; }
1056 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1058 exponent += exp_neg ? 0-exp : exp;
1061 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return NUMBER_ERROR; }
1063 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1069 if (simdjson_likely(!overflow)) {
1070 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1072 if (!parse_float_fallback(src - uint8_t(negative), &d)) {
1078 simdjson_unused simdjson_inline
bool is_negative(
const uint8_t * src) noexcept {
1079 return (*src ==
'-');
1082 simdjson_unused simdjson_inline simdjson_result<bool> is_integer(
const uint8_t * src) noexcept {
1083 bool negative = (*src ==
'-');
1084 src += uint8_t(negative);
1085 const uint8_t *p = src;
1086 while(
static_cast<uint8_t
>(*p -
'0') <= 9) { p++; }
1088 if (jsoncharutils::is_structural_or_whitespace(*p)) {
return true; }
1092 simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(
const uint8_t * src) noexcept {
1093 bool negative = (*src ==
'-');
1094 src += uint8_t(negative);
1095 const uint8_t *p = src;
1096 while(
static_cast<uint8_t
>(*p -
'0') <= 9) { p++; }
1097 size_t digit_count = size_t(p - src);
1099 if (jsoncharutils::is_structural_or_whitespace(*p)) {
1100 static const uint8_t * smaller_big_integer =
reinterpret_cast<const uint8_t *
>(
"9223372036854775808");
1102 if(simdjson_unlikely(digit_count > 20)) {
1103 return number_type::big_integer;
1107 if (simdjson_unlikely(digit_count > 19))
return number_type::big_integer;
1108 if (simdjson_unlikely(digit_count == 19 && memcmp(src, smaller_big_integer, 19) > 0)) {
1109 return number_type::big_integer;
1111 return number_type::signed_integer;
1114 static const uint8_t * two_to_sixtyfour =
reinterpret_cast<const uint8_t *
>(
"18446744073709551616");
1115 if((digit_count > 20) || (digit_count == 20 && memcmp(src, two_to_sixtyfour, 20) >= 0)) {
1116 return number_type::big_integer;
1121 if((digit_count == 20) || (digit_count >= 19 && memcmp(src, smaller_big_integer, 19) >= 0)) {
1122 return number_type::unsigned_integer;
1124 return number_type::signed_integer;
1127 return number_type::floating_point_number;
1131 simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t * src,
const uint8_t *
const src_end) noexcept {
1136 bool negative = (*src ==
'-');
1137 src += uint8_t(negative);
1143 const uint8_t *p = src;
1145 p += parse_digit(*p, i);
1146 bool leading_zero = (i == 0);
1147 while ((p != src_end) && parse_digit(*p, i)) { p++; }
1150 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1155 int64_t exponent = 0;
1157 if (simdjson_likely((p != src_end) && (*p ==
'.'))) {
1159 const uint8_t *start_decimal_digits = p;
1160 if ((p == src_end) || !parse_digit(*p, i)) {
return NUMBER_ERROR; }
1162 while ((p != src_end) && parse_digit(*p, i)) { p++; }
1163 exponent = -(p - start_decimal_digits);
1166 overflow = p-src-1 > 19;
1167 if (simdjson_unlikely(overflow && leading_zero)) {
1169 const uint8_t *start_digits = src + 2;
1170 while (*start_digits ==
'0') { start_digits++; }
1171 overflow = start_digits-src > 19;
1174 overflow = p-src > 19;
1180 if ((p != src_end) && (*p ==
'e' || *p ==
'E')) {
1183 bool exp_neg = *p ==
'-';
1184 p += exp_neg || *p ==
'+';
1187 const uint8_t *start_exp_digits = p;
1188 while ((p != src_end) && parse_digit(*p, exp)) { p++; }
1190 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1192 exponent += exp_neg ? 0-exp : exp;
1195 if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) {
return NUMBER_ERROR; }
1197 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1203 if (simdjson_likely(!overflow)) {
1204 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1206 if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) {
1212 simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(
const uint8_t * src) noexcept {
1216 bool negative = (*(src + 1) ==
'-');
1217 src += uint8_t(negative) + 1;
1223 const uint8_t *p = src;
1224 p += parse_digit(*p, i);
1225 bool leading_zero = (i == 0);
1226 while (parse_digit(*p, i)) { p++; }
1229 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1234 int64_t exponent = 0;
1236 if (simdjson_likely(*p ==
'.')) {
1238 const uint8_t *start_decimal_digits = p;
1241 while (parse_digit(*p, i)) { p++; }
1242 exponent = -(p - start_decimal_digits);
1245 overflow = p-src-1 > 19;
1246 if (simdjson_unlikely(overflow && leading_zero)) {
1248 const uint8_t *start_digits = src + 2;
1249 while (*start_digits ==
'0') { start_digits++; }
1250 overflow = p-start_digits > 19;
1253 overflow = p-src > 19;
1259 if (*p ==
'e' || *p ==
'E') {
1261 bool exp_neg = *p ==
'-';
1262 p += exp_neg || *p ==
'+';
1265 const uint8_t *start_exp_digits = p;
1266 while (parse_digit(*p, exp)) { p++; }
1268 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1270 exponent += exp_neg ? 0-exp : exp;
1275 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1281 if (simdjson_likely(!overflow)) {
1282 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1284 if (!parse_float_fallback(src - uint8_t(negative), &d)) {
1295 inline std::ostream&
operator<<(std::ostream& out, number_type type) noexcept {
1297 case number_type::signed_integer: out <<
"integer in [-9223372036854775808,9223372036854775808)";
break;
1298 case number_type::unsigned_integer: out <<
"unsigned integer in [9223372036854775808,18446744073709551616)";
break;
1299 case number_type::floating_point_number: out <<
"floating-point number (binary64)";
break;
1300 case number_type::big_integer: out <<
"big integer";
break;
1301 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.