@@ -240,7 +240,7 @@ loop_parse_if_digits(char const *&p, char const *const pend, uint64_t &i) {
240240 while (std::distance (p, pend) >= sizeof (uint64_t )) {
241241 auto const val = read_chars_to_unsigned<uint64_t >(p);
242242 if (is_made_of_eight_digits_fast (val)) {
243- i = i * 100000000 /* 10 ^ sizeof(uint64_t)*/ +
243+ i = i * 100000000 /* 10 ^ sizeof(uint64_t)*/ +
244244 parse_eight_digits_unrolled (val); // may overflow, that's ok
245245 p += sizeof (uint64_t );
246246 } else {
@@ -253,7 +253,7 @@ loop_parse_if_digits(char const *&p, char const *const pend, uint64_t &i) {
253253 if (std::distance (p, pend) >= sizeof (uint32_t )) {
254254 auto const val = read_chars_to_unsigned<uint32_t >(p);
255255 if (is_made_of_four_digits_fast (val)) {
256- i = i * 10000 /* 10 ^ sizeof(uint32_t)*/ +
256+ i = i * 10000 /* 10 ^ sizeof(uint32_t)*/ +
257257 parse_four_digits_unrolled (val); // may overflow, that's ok
258258 p += sizeof (uint32_t );
259259 }
@@ -300,6 +300,7 @@ template <typename UC> struct parsed_number_string_t {
300300using byte_span = span<char const >;
301301using parsed_number_string = parsed_number_string_t <char >;
302302
303+ // Helper for error creating
303304template <typename UC >
304305fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t <UC >
305306report_parse_error (parsed_number_string_t <UC > &answer, UC const *p,
@@ -325,29 +326,29 @@ parse_number_string(UC const *p, UC const *pend,
325326 parse_options_t <UC > const options,
326327 bool store_spans = true ) noexcept {
327328 parsed_number_string_t <UC > answer{};
328- // so dereference without checks
329- FASTFLOAT_ASSUME (p < pend);
329+ FASTFLOAT_ASSUME (p < pend); // so dereference without checks
330330#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
331331 answer.negative = (*p == UC (' -' ));
332- // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
333332 if (answer.negative ||
333+ // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
334334 ((chars_format_t (options.format & chars_format::allow_leading_plus)) &&
335335 (!basic_json_fmt && *p == UC (' +' )))) {
336336 ++p;
337337 if (p == pend) {
338338 return report_parse_error<UC >(
339339 answer, p, parse_error::missing_integer_or_dot_after_sign);
340340 }
341+
341342 FASTFLOAT_IF_CONSTEXPR17 (basic_json_fmt) {
342- // a sign must be followed by an integer
343343 if (!is_integer (*p)) {
344+ // a sign must be followed by an integer
344345 return report_parse_error<UC >(answer, p,
345346 parse_error::missing_integer_after_sign);
346347 }
347348 }
348349 else {
349- // a sign must be followed by an integer or the dot
350350 if (!is_integer (*p) && (*p != options.decimal_point )) {
351+ // a sign must be followed by an integer or the dot
351352 return report_parse_error<UC >(
352353 answer, p, parse_error::missing_integer_or_dot_after_sign);
353354 }
@@ -359,7 +360,8 @@ parse_number_string(UC const *p, UC const *pend,
359360 // Straight-line unroll of the integer-part scan: most integer parts are
360361 // 1-5 digits, so peeling the first iterations eliminates the loop back-edge
361362 // for the common case. Semantics are identical to the original `while` loop:
362- // i = 10*i + digit, advancing p.
363+ // i = 10*i + digit, advancing p: a multiplication by 10 is cheaper than an
364+ // arbitrary integer multiplication. might overflow, handled later
363365 if ((p != pend) && is_integer (*p)) {
364366 answer.mantissa = static_cast <fast_float::am_mant_t >(*p - UC (' 0' ));
365367 ++p;
@@ -384,12 +386,9 @@ parse_number_string(UC const *p, UC const *pend,
384386 static_cast <fast_float::am_mant_t >(*p - UC (' 0' )));
385387 ++p;
386388 while ((p != pend) && is_integer (*p)) {
387- // a multiplication by 10 is cheaper than an arbitrary integer
388- // multiplication
389389 answer.mantissa = static_cast <fast_float::am_mant_t >(
390390 answer.mantissa * 10 +
391- static_cast <fast_float::am_mant_t >(
392- *p - UC (' 0' ))); // might overflow, handled later
391+ static_cast <fast_float::am_mant_t >(*p - UC (' 0' )));
393392 ++p;
394393 }
395394 }
@@ -426,11 +425,10 @@ parse_number_string(UC const *p, UC const *pend,
426425 loop_parse_if_digits (p, pend, answer.mantissa );
427426
428427 while ((p != pend) && is_integer (*p)) {
429- auto const digit = uint8_t (*p - UC (' 0' ));
430- ++p;
431428 answer.mantissa = static_cast <fast_float::am_mant_t >(
432429 answer.mantissa * 10 +
433- digit); // in rare cases, this will overflow, but that's ok
430+ static_cast <fast_float::am_mant_t >(*p - UC (' 0' )));
431+ ++p;
434432 }
435433 answer.exponent = static_cast <am_pow_t >(before - p);
436434 if fastfloat_unlikely (store_spans) {
@@ -532,19 +530,19 @@ parse_number_string(UC const *p, UC const *pend,
532530 // of a 64-bit integer. However, this is uncommon.
533531 //
534532 // We can deal with up to 19 digits.
535- if fastfloat_unlikely (digit_count > 19 ) { // this is uncommon
533+ if fastfloat_unlikely (digit_count > 19 ) {
536534 // It is possible that the integer had an overflow.
537535 // We have to handle the case where we have 0.0000somenumber.
538536 // We need to be mindful of the case where we only have zeroes...
539537 // E.g., 0.000000000...000.
540538 auto const *start = start_digits;
541- while ((start != pend) &&
542- (*start == UC (' 0' ) || *start == options.decimal_point )) {
539+ do {
543540 if (*start == UC (' 0' )) {
544541 --digit_count;
542+ } else if (*start != options.decimal_point ) {
543+ break ;
545544 }
546- ++start;
547- }
545+ } while (++start != pend);
548546
549547 // We have to check if number has more than 19 significant digits.
550548 if (digit_count > 19 ) {
@@ -553,20 +551,19 @@ parse_number_string(UC const *p, UC const *pend,
553551 // store_spans is false we didn't materialize them, so just flag
554552 // too_many_digits; the caller re-parses with store_spans=true to obtain
555553 // the corrected mantissa/exponent before taking the slow path.
556- if fastfloat_unlikely (store_spans) {
554+ if (store_spans) {
557555 // Let us start again, this time, avoiding overflows.
558556 // We don't need to call if is_integer, since we use the
559557 // pre-tokenized spans from above.
560558 answer.mantissa = 0 ;
561559 p = answer.integer .ptr ;
562560 UC const *int_end = p + answer.integer .len ();
563561 constexpr am_mant_t minimal_nineteen_digit_integer{1000000000000000000 };
564- while ((p != int_end) &&
565- (answer.mantissa < minimal_nineteen_digit_integer)) {
562+ do {
566563 answer.mantissa =
567564 answer.mantissa * 10 + static_cast <am_mant_t >(*p - UC (' 0' ));
568- ++p;
569- }
565+ } while (( ++p != int_end) &&
566+ (answer. mantissa < minimal_nineteen_digit_integer));
570567 if (answer.mantissa >= minimal_nineteen_digit_integer) {
571568 // We have a big integers, so skip the fraction part completely.
572569 answer.exponent = am_pow_t (end_of_integer_part - p) + exp_number;
@@ -797,7 +794,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
797794 // and a single threshold separates wrapped from non-wrapped values. A
798795 // leading digit above dmax always overflows; below dmax always fits.
799796 uint64_t const ms = min_safe_u64 (options.base );
800- uint64_t const dmax = ( std::numeric_limits<uint64_t >::max) () / ms;
797+ uint64_t const dmax = std::numeric_limits<uint64_t >::max () / ms;
801798 uint64_t const lead = ch_to_digit (*start_digits);
802799 if (lead > dmax || (lead == dmax && i < dmax * ms)) {
803800 answer.ec = std::errc::result_out_of_range;
0 commit comments