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#if SIMDJSON_STATIC_REFLECTION
171 simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
173 simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
187 if((firstproduct.high & 0x1FF) == 0x1FF) {
208#if SIMDJSON_STATIC_REFLECTION
209 simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
211 simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
213 firstproduct.low += secondproduct.high;
214 if(secondproduct.high > firstproduct.low) { firstproduct.high++; }
219 uint64_t lower = firstproduct.low;
220 uint64_t upper = firstproduct.high;
224 uint64_t upperbit = upper >> 63;
225 uint64_t mantissa = upper >> (upperbit + 9);
226 lz += int(1 ^ upperbit);
229 int64_t real_exponent = exponent - lz;
230 if (simdjson_unlikely(real_exponent <= 0)) {
232 if(-real_exponent + 1 >= 64) {
233 d = negative ? -0.0 : 0.0;
237 mantissa >>= -real_exponent + 1;
240 mantissa += (mantissa & 1);
249 real_exponent = (mantissa < (uint64_t(1) << 52)) ? 0 : 1;
250 d = to_double(mantissa, real_exponent, negative);
275 if (simdjson_unlikely((lower <= 1) && (power >= -4) && (power <= 23) && ((mantissa & 3) == 1))) {
276 if((mantissa << (upperbit + 64 - 53 - 2)) == upper) {
281 mantissa += mantissa & 1;
285 if (mantissa >= (1ULL << 53)) {
289 mantissa = (1ULL << 52);
292 mantissa &= ~(1ULL << 52);
294 if (simdjson_unlikely(real_exponent > 2046)) {
298 d = to_double(mantissa, real_exponent, negative);
309static bool parse_float_fallback(
const uint8_t *ptr,
double *outDouble) {
310 *outDouble = simdjson::internal::from_chars(
reinterpret_cast<const char *
>(ptr));
321 return !(*outDouble > (std::numeric_limits<double>::max)() || *outDouble < std::numeric_limits<double>::lowest());
324static bool parse_float_fallback(
const uint8_t *ptr,
const uint8_t *end_ptr,
double *outDouble) {
325 *outDouble = simdjson::internal::from_chars(
reinterpret_cast<const char *
>(ptr),
reinterpret_cast<const char *
>(end_ptr));
336 return !(*outDouble > (std::numeric_limits<double>::max)() || *outDouble < std::numeric_limits<double>::lowest());
342simdjson_inline
bool is_made_of_eight_digits_fast(
const uint8_t *chars) {
346 static_assert(7 <=
SIMDJSON_PADDING,
"SIMDJSON_PADDING must be bigger than 7");
347 std::memcpy(&val, chars, 8);
352 return (((val & 0xF0F0F0F0F0F0F0F0) |
353 (((val + 0x0606060606060606) & 0xF0F0F0F0F0F0F0F0) >> 4)) ==
358SIMDJSON_NO_SANITIZE_UNDEFINED
359simdjson_inline
bool parse_digit(
const uint8_t c, I &i) {
360 const uint8_t digit =
static_cast<uint8_t
>(c -
'0');
369simdjson_inline
bool is_digit(
const uint8_t c) {
370 return static_cast<uint8_t
>(c -
'0') <= 9;
373simdjson_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) {
378 const uint8_t *
const first_after_period = p;
380#ifdef SIMDJSON_SWAR_NUMBER_PARSING
381#if SIMDJSON_SWAR_NUMBER_PARSING
384 if (is_made_of_eight_digits_fast(p)) {
385 i = i * 100000000 + parse_eight_digits_unrolled(p);
391 if (parse_digit(*p, i)) { ++p; }
392 while (parse_digit(*p, i)) { p++; }
393 exponent = first_after_period - p;
396 return INVALID_NUMBER(src);
401simdjson_warn_unused simdjson_inline
error_code parse_exponent(simdjson_unused
const uint8_t *
const src,
const uint8_t *&p, int64_t &exponent) {
403 bool neg_exp = (
'-' == *p);
404 if (neg_exp ||
'+' == *p) { p++; }
408 int64_t exp_number = 0;
409 while (parse_digit(*p, exp_number)) { ++p; }
421 if (simdjson_unlikely(p == start_exp)) {
422 return INVALID_NUMBER(src);
429 if (simdjson_unlikely(p > start_exp+18)) {
431 while (*start_exp ==
'0') { start_exp++; }
441 if (p > start_exp+18) { exp_number = 999999999999999999; }
448 exponent += (neg_exp ? -exp_number : exp_number);
452simdjson_inline
bool check_if_integer(
const uint8_t *
const src,
size_t max_length) {
453 const uint8_t *
const srcend = src + max_length;
454 bool negative = (*src ==
'-');
455 const uint8_t *p = src + uint8_t(negative);
456 if(p == srcend) {
return false; }
459 if(p == srcend) {
return true; }
460 if(jsoncharutils::is_not_structural_or_whitespace(*p)) {
return false; }
463 while(p != srcend && is_digit(*p)) { ++p; }
464 if(p == srcend) {
return true; }
465 if(jsoncharutils::is_not_structural_or_whitespace(*p)) {
return false; }
469simdjson_inline
size_t significant_digits(
const uint8_t * start_digits,
size_t digit_count) {
472 const uint8_t *start = start_digits;
473 while ((*start ==
'0') || (*start ==
'.')) { ++start; }
475 return digit_count - size_t(start - start_digits);
481static error_code slow_float_parsing(simdjson_unused
const uint8_t * src,
double* answer) {
482 if (parse_float_fallback(src, answer)) {
485 return INVALID_NUMBER(src);
490simdjson_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) {
498 if (simdjson_unlikely(digit_count > 19 && significant_digits(start_digits, digit_count) > 19)) {
511 error_code error = slow_float_parsing(src, &d);
512 writer.append_double(d);
518 if (simdjson_unlikely(exponent < simdjson::internal::smallest_power) || (exponent > simdjson::internal::largest_power)) {
523 static_assert(simdjson::internal::smallest_power <= -342,
"smallest_power is not small enough");
525 if((exponent < simdjson::internal::smallest_power) || (i == 0)) {
527 WRITE_DOUBLE(negative ? -0.0 : 0.0, src, writer);
531 return INVALID_NUMBER(src);
535 if (!compute_float_64(exponent, i, negative, d)) {
537 if (!parse_float_fallback(src, &d)) {
return INVALID_NUMBER(src); }
539 WRITE_DOUBLE(d, src, writer);
553simdjson_warn_unused simdjson_inline
error_code parse_number(
const uint8_t *
const src, W &writer);
556#ifdef SIMDJSON_SKIPNUMBERPARSING
559simdjson_warn_unused simdjson_inline
error_code parse_number(
const uint8_t *
const, W &writer) {
560 writer.append_s64(0);
564simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src)
noexcept {
return 0; }
565simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *
const src)
noexcept {
return 0; }
566simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t *
const src)
noexcept {
return 0; }
567simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned_in_string(
const uint8_t *
const src)
noexcept {
return 0; }
568simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer_in_string(
const uint8_t *
const src)
noexcept {
return 0; }
569simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(
const uint8_t *
const src)
noexcept {
return 0; }
570simdjson_unused simdjson_inline
bool is_negative(
const uint8_t * src)
noexcept {
return false; }
571simdjson_unused simdjson_inline simdjson_result<bool> is_integer(
const uint8_t * src)
noexcept {
return false; }
572simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(
const uint8_t * src)
noexcept {
return number_type::signed_integer; }
585simdjson_warn_unused simdjson_inline
error_code parse_number(
const uint8_t *
const src, W &writer) {
589 bool negative = (*src ==
'-');
590 const uint8_t *p = src + uint8_t(negative);
596 const uint8_t *
const start_digits = p;
598 while (parse_digit(*p, i)) { p++; }
602 size_t digit_count = size_t(p - start_digits);
603 if (digit_count == 0 || (
'0' == *start_digits && digit_count > 1)) {
return INVALID_NUMBER(src); }
608 int64_t exponent = 0;
609 bool is_float =
false;
613 SIMDJSON_TRY( parse_decimal_after_separator(src, p, i, exponent) );
614 digit_count = int(p - start_digits);
616 if ((
'e' == *p) || (
'E' == *p)) {
619 SIMDJSON_TRY( parse_exponent(src, p, exponent) );
622 const bool dirty_end = jsoncharutils::is_not_structural_or_whitespace(*p);
623 SIMDJSON_TRY( write_float(src, negative, i, start_digits, digit_count, exponent, writer) );
624 if (dirty_end) {
return INVALID_NUMBER(src); }
631 size_t longest_digit_count = negative ? 19 : 20;
632 if (digit_count > longest_digit_count) {
return BIGINT_NUMBER(src); }
633 if (digit_count == longest_digit_count) {
636 if (i > uint64_t(INT64_MAX)+1) {
return BIGINT_NUMBER(src); }
637 WRITE_INTEGER(~i+1, src, writer);
638 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return INVALID_NUMBER(src); }
652 }
else if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INVALID_NUMBER(src); }
656 if (i > uint64_t(INT64_MAX)) {
657 WRITE_UNSIGNED(i, src, writer);
659#if SIMDJSON_MINUS_ZERO_AS_FLOAT
660 if(i == 0 && negative) {
662 WRITE_DOUBLE(-0.0, src, writer);
664 WRITE_INTEGER(negative ? (~i+1) : i, src, writer);
667 WRITE_INTEGER(negative ? (~i+1) : i, src, writer);
670 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return INVALID_NUMBER(src); }
688const uint8_t integer_string_finisher[256] = {
743simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src)
noexcept {
744 const uint8_t *p = src;
749 const uint8_t *
const start_digits = p;
751 while (parse_digit(*p, i)) { p++; }
755 size_t digit_count = size_t(p - start_digits);
761 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
763 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
769 if (integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
771 if (digit_count == 20) {
784 if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
793simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned(
const uint8_t *
const src,
const uint8_t *
const src_end)
noexcept {
794 const uint8_t *p = src;
799 const uint8_t *
const start_digits = p;
801 while ((p != src_end) && parse_digit(*p, i)) { p++; }
805 size_t digit_count = size_t(p - start_digits);
811 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
813 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
819 if ((p != src_end) && integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
821 if (digit_count == 20) {
834 if (src[0] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
841simdjson_unused simdjson_inline simdjson_result<uint64_t> parse_unsigned_in_string(
const uint8_t *
const src)
noexcept {
842 const uint8_t *p = src + 1;
847 const uint8_t *
const start_digits = p;
849 while (parse_digit(*p, i)) { p++; }
853 size_t digit_count = size_t(p - start_digits);
859 if ((digit_count == 0) || (digit_count > 20)) {
return INCORRECT_TYPE; }
861 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
869 if (digit_count == 20) {
884 if (src[1] != uint8_t(
'1') || i <= uint64_t(INT64_MAX)) {
return INCORRECT_TYPE; }
891simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *src)
noexcept {
895 bool negative = (*src ==
'-');
896 const uint8_t *p = src + uint8_t(negative);
902 const uint8_t *
const start_digits = p;
904 while (parse_digit(*p, i)) { p++; }
908 size_t digit_count = size_t(p - start_digits);
912 size_t longest_digit_count = 19;
916 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
918 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
924 if(integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
928 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
929 return negative ? (~i+1) : i;
934simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer(
const uint8_t *
const src,
const uint8_t *
const src_end)
noexcept {
939 bool negative = (*src ==
'-');
940 const uint8_t *p = src + uint8_t(negative);
946 const uint8_t *
const start_digits = p;
948 while ((p != src_end) && parse_digit(*p, i)) { p++; }
952 size_t digit_count = size_t(p - start_digits);
956 size_t longest_digit_count = 19;
960 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
962 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
968 if((p != src_end) && integer_string_finisher[*p] !=
SUCCESS) {
return error_code(integer_string_finisher[*p]); }
972 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
973 return negative ? (~i+1) : i;
977simdjson_unused simdjson_inline simdjson_result<int64_t> parse_integer_in_string(
const uint8_t *src)
noexcept {
981 bool negative = (*(src + 1) ==
'-');
982 src += uint8_t(negative) + 1;
988 const uint8_t *
const start_digits = src;
990 while (parse_digit(*src, i)) { src++; }
994 size_t digit_count = size_t(src - start_digits);
998 size_t longest_digit_count = 19;
1002 if ((digit_count == 0) || (digit_count > longest_digit_count)) {
return INCORRECT_TYPE; }
1004 if ((
'0' == *start_digits) && (digit_count > 1)) {
return NUMBER_ERROR; }
1014 if(i > uint64_t(INT64_MAX) + uint64_t(negative)) {
return INCORRECT_TYPE; }
1015 return negative ? (~i+1) : i;
1018simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t * src)
noexcept {
1022 bool negative = (*src ==
'-');
1023 src += uint8_t(negative);
1029 const uint8_t *p = src;
1030 p += parse_digit(*p, i);
1031 bool leading_zero = (i == 0);
1032 while (parse_digit(*p, i)) { p++; }
1035 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1040 int64_t exponent = 0;
1042 if (simdjson_likely(*p ==
'.')) {
1044 const uint8_t *start_decimal_digits = p;
1047 while (parse_digit(*p, i)) { p++; }
1048 exponent = -(p - start_decimal_digits);
1051 overflow = p-src-1 > 19;
1052 if (simdjson_unlikely(overflow && leading_zero)) {
1054 const uint8_t *start_digits = src + 2;
1055 while (*start_digits ==
'0') { start_digits++; }
1056 overflow = p-start_digits > 19;
1059 overflow = p-src > 19;
1065 if (*p ==
'e' || *p ==
'E') {
1067 bool exp_neg = *p ==
'-';
1068 p += exp_neg || *p ==
'+';
1071 const uint8_t *start_exp_digits = p;
1072 while (parse_digit(*p, exp)) { p++; }
1074 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1076 exponent += exp_neg ? 0-exp : exp;
1079 if (jsoncharutils::is_not_structural_or_whitespace(*p)) {
return NUMBER_ERROR; }
1081 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1087 if (simdjson_likely(!overflow)) {
1088 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1090 if (!parse_float_fallback(src - uint8_t(negative), &d)) {
1096simdjson_unused simdjson_inline
bool is_negative(
const uint8_t * src)
noexcept {
1097 return (*src ==
'-');
1100simdjson_unused simdjson_inline simdjson_result<bool> is_integer(
const uint8_t * src)
noexcept {
1101 bool negative = (*src ==
'-');
1102 src += uint8_t(negative);
1103 const uint8_t *p = src;
1104 while(
static_cast<uint8_t
>(*p -
'0') <= 9) { p++; }
1106 if (jsoncharutils::is_structural_or_whitespace(*p)) {
return true; }
1110simdjson_unused simdjson_inline simdjson_result<number_type> get_number_type(
const uint8_t * src)
noexcept {
1111 bool negative = (*src ==
'-');
1112 src += uint8_t(negative);
1113 const uint8_t *p = src;
1114 while(
static_cast<uint8_t
>(*p -
'0') <= 9) { p++; }
1115 size_t digit_count = size_t(p - src);
1117 if (jsoncharutils::is_structural_or_whitespace(*p)) {
1118 static const uint8_t * smaller_big_integer =
reinterpret_cast<const uint8_t *
>(
"9223372036854775808");
1120 if(simdjson_unlikely(digit_count > 20)) {
1121 return number_type::big_integer;
1125 if (simdjson_unlikely(digit_count > 19))
return number_type::big_integer;
1126 if (simdjson_unlikely(digit_count == 19 && memcmp(src, smaller_big_integer, 19) > 0)) {
1127 return number_type::big_integer;
1129#if SIMDJSON_MINUS_ZERO_AS_FLOAT
1130 if(digit_count == 1 && src[0] ==
'0') {
1132 return number_type::floating_point_number;
1135 return number_type::signed_integer;
1138 static const uint8_t * two_to_sixtyfour =
reinterpret_cast<const uint8_t *
>(
"18446744073709551616");
1139 if((digit_count > 20) || (digit_count == 20 && memcmp(src, two_to_sixtyfour, 20) >= 0)) {
1140 return number_type::big_integer;
1145 if((digit_count == 20) || (digit_count >= 19 && memcmp(src, smaller_big_integer, 19) >= 0)) {
1146 return number_type::unsigned_integer;
1148 return number_type::signed_integer;
1151 return number_type::floating_point_number;
1155simdjson_unused simdjson_inline simdjson_result<double> parse_double(
const uint8_t * src,
const uint8_t *
const src_end)
noexcept {
1160 bool negative = (*src ==
'-');
1161 src += uint8_t(negative);
1167 const uint8_t *p = src;
1169 p += parse_digit(*p, i);
1170 bool leading_zero = (i == 0);
1171 while ((p != src_end) && parse_digit(*p, i)) { p++; }
1174 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1179 int64_t exponent = 0;
1181 if (simdjson_likely((p != src_end) && (*p ==
'.'))) {
1183 const uint8_t *start_decimal_digits = p;
1184 if ((p == src_end) || !parse_digit(*p, i)) {
return NUMBER_ERROR; }
1186 while ((p != src_end) && parse_digit(*p, i)) { p++; }
1187 exponent = -(p - start_decimal_digits);
1190 overflow = p-src-1 > 19;
1191 if (simdjson_unlikely(overflow && leading_zero)) {
1193 const uint8_t *start_digits = src + 2;
1194 while (*start_digits ==
'0') { start_digits++; }
1195 overflow = start_digits-src > 19;
1198 overflow = p-src > 19;
1204 if ((p != src_end) && (*p ==
'e' || *p ==
'E')) {
1207 bool exp_neg = *p ==
'-';
1208 p += exp_neg || *p ==
'+';
1211 const uint8_t *start_exp_digits = p;
1212 while ((p != src_end) && parse_digit(*p, exp)) { p++; }
1214 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1216 exponent += exp_neg ? 0-exp : exp;
1219 if ((p != src_end) && jsoncharutils::is_not_structural_or_whitespace(*p)) {
return NUMBER_ERROR; }
1221 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1227 if (simdjson_likely(!overflow)) {
1228 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1230 if (!parse_float_fallback(src - uint8_t(negative), src_end, &d)) {
1236simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(
const uint8_t * src)
noexcept {
1240 bool negative = (*(src + 1) ==
'-');
1241 src += uint8_t(negative) + 1;
1247 const uint8_t *p = src;
1248 p += parse_digit(*p, i);
1249 bool leading_zero = (i == 0);
1250 while (parse_digit(*p, i)) { p++; }
1253 if ( (leading_zero && p != src+1)) {
return NUMBER_ERROR; }
1258 int64_t exponent = 0;
1260 if (simdjson_likely(*p ==
'.')) {
1262 const uint8_t *start_decimal_digits = p;
1265 while (parse_digit(*p, i)) { p++; }
1266 exponent = -(p - start_decimal_digits);
1269 overflow = p-src-1 > 19;
1270 if (simdjson_unlikely(overflow && leading_zero)) {
1272 const uint8_t *start_digits = src + 2;
1273 while (*start_digits ==
'0') { start_digits++; }
1274 overflow = p-start_digits > 19;
1277 overflow = p-src > 19;
1283 if (*p ==
'e' || *p ==
'E') {
1285 bool exp_neg = *p ==
'-';
1286 p += exp_neg || *p ==
'+';
1289 const uint8_t *start_exp_digits = p;
1290 while (parse_digit(*p, exp)) { p++; }
1292 if (p-start_exp_digits == 0 || p-start_exp_digits > 19) {
return NUMBER_ERROR; }
1294 exponent += exp_neg ? 0-exp : exp;
1299 overflow = overflow || exponent < simdjson::internal::smallest_power || exponent > simdjson::internal::largest_power;
1305 if (simdjson_likely(!overflow)) {
1306 if (compute_float_64(exponent, i, negative, d)) {
return d; }
1308 if (!parse_float_fallback(src - uint8_t(negative), &d)) {
1319inline std::ostream& operator<<(std::ostream& out, number_type type)
noexcept {
1321 case number_type::signed_integer: out <<
"integer in [-9223372036854775808,9223372036854775808)";
break;
1322 case number_type::unsigned_integer: out <<
"unsigned integer in [9223372036854775808,18446744073709551616)";
break;
1323 case number_type::floating_point_number: out <<
"floating-point number (binary64)";
break;
1324 case number_type::big_integer: out <<
"big integer";
break;
1325 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.