From e08c55c38051883e5e9cad82957cc749a1fbda35 Mon Sep 17 00:00:00 2001 From: Maya Warrier Date: Mon, 1 May 2023 19:45:50 -0400 Subject: [PATCH] Remove json parse rules/allow inf_nan --- .gitignore | 2 +- include/fast_float/ascii_number.h | 16 ++++------- include/fast_float/fast_float.h | 37 ++---------------------- include/fast_float/parse_number.h | 47 +++++++++++-------------------- 4 files changed, 25 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index a2601ad..5cc2dd6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ compile_commands.json .vs/ Debug/ Release/ -/out/build/ +/out/ *.sln *.vcxproj *.vcxproj.filters diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index cc9619c..f583c2b 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -51,7 +51,7 @@ fastfloat_really_inline uint64_t simd_read8_to_u64(const char16_t* chars, const __m128i packus_masks) { FASTFLOAT_SIMD_DISABLE_WARNINGS // process 4 and 4 chars simultaneously (loadu_si64 has high latency) - // with AVX512BW + AVX512VL, masking is not required as we have cvtepi16_epi8 + // with AVX512BW + AVX512VL, masking is not required as we can use cvtepi16_epi8 const char* const p = reinterpret_cast(chars); __m128i i1 = _mm_and_si128(_mm_loadu_si64(p), packus_masks); __m128i i2 = _mm_and_si128(_mm_loadu_si64(p + 8), packus_masks); @@ -223,8 +223,7 @@ template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string parse_number_string(const CharT *p, const CharT *pend, parse_options options) noexcept { const chars_format fmt = options.format; - const parse_rules rules = options.rules; - const CharT decimal_point = CharT(options.decimal_point); + const CharT decimal_point = options.decimal_point; parsed_number_string answer; answer.valid = false; @@ -240,7 +239,7 @@ parsed_number_string parse_number_string(const CharT *p, const CharT *pen return answer; } // a sign must be followed by an integer or the dot - if (!is_integer(*p) && (rules == parse_rules::json_rules || *p != decimal_point)) + if (!is_integer(*p) && *p != decimal_point) return answer; } const CharT *const start_digits = p; @@ -275,8 +274,8 @@ parsed_number_string parse_number_string(const CharT *p, const CharT *pen answer.fraction = span(before, size_t(p - before)); digit_count -= exponent; } - // we must have encountered at least one integer (or two if a decimal point exists, with json rules). - if (digit_count == 0 || (rules == parse_rules::json_rules && has_decimal_point && digit_count == 1)) { + // we must have encountered at least one integer + if (digit_count == 0) { return answer; } int64_t exp_number = 0; // explicit exponential part @@ -312,11 +311,6 @@ parsed_number_string parse_number_string(const CharT *p, const CharT *pen // If it scientific and not fixed, we have to bail out. if((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { return answer; } } - - // disallow leading zeros before the decimal point - if (rules == parse_rules::json_rules && start_digits[0] == CharT('0') && digit_count >= 2 && is_integer(start_digits[1])) - return answer; - answer.lastmatch = p; answer.valid = true; answer.exp_number = exp_number; diff --git a/include/fast_float/fast_float.h b/include/fast_float/fast_float.h index 470d05a..57d39b3 100644 --- a/include/fast_float/fast_float.h +++ b/include/fast_float/fast_float.h @@ -13,11 +13,6 @@ enum chars_format { general = fixed | scientific }; -enum parse_rules { - std_rules, - json_rules, -}; - template struct from_chars_result { const CharT *ptr; @@ -26,34 +21,15 @@ struct from_chars_result { struct parse_options { constexpr explicit parse_options( - chars_format fmt = chars_format::general, - parse_rules rules = parse_rules::std_rules, - char dot = '.', bool allow_inf_nan = true) - : format(fmt), rules(rules), allow_inf_nan(allow_inf_nan), decimal_point(dot) {} + chars_format fmt = chars_format::general, char dot = '.') + : format(fmt), decimal_point(dot) {} /** Which number formats are accepted */ chars_format format; - /** Which parsing rules to use */ - parse_rules rules; - /** Whether to allow inf and nan */ - bool allow_inf_nan; /** The character used as decimal point */ char decimal_point; }; -struct preparsed_parse_options { - constexpr explicit preparsed_parse_options( - bool allow_inf_nan = true) - : allow_inf_nan(allow_inf_nan) {} - - constexpr preparsed_parse_options( - const parse_options& options) - : allow_inf_nan(options.allow_inf_nan) {} - - /** Whether to allow inf and nan */ - bool allow_inf_nan; -}; - /** * This function parses the character sequence [first,last) for a number. It parses floating-point numbers expecting * a locale-indepent format equivalent to what is used by std::strtod in the default ("C") locale. @@ -86,15 +62,6 @@ FASTFLOAT_CONSTEXPR20 from_chars_result from_chars_advanced(const CharT *first, const CharT *last, T &value, parse_options options) noexcept; -} - -#include "ascii_number.h" // parsed_number_string - -namespace fast_float { -template -FASTFLOAT_CONSTEXPR20 -from_chars_result from_chars_preparsed(parsed_number_string parsed, - const CharT* first, const CharT* last, T& value, preparsed_parse_options options) noexcept; } // namespace fast_float diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index 1cc220b..99ccd49 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -143,23 +143,30 @@ from_chars_result from_chars(const CharT *first, const CharT *last, template FASTFLOAT_CONSTEXPR20 -from_chars_result from_chars_preparsed(parsed_number_string pns, const CharT* first, const CharT* last, T& value, preparsed_parse_options options) noexcept +from_chars_result from_chars_advanced(const CharT *first, const CharT *last, + T &value, parse_options options) noexcept { { static_assert (std::is_same::value || std::is_same::value, "only float and double are supported"); from_chars_result answer; - if (!pns.valid) { - if (options.allow_inf_nan) - return detail::parse_infnan(first, last, value); - else { - answer.ec = std::errc::invalid_argument; - answer.ptr = first; - return answer; - } +#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default + while ((first != last) && fast_float::is_space(uint8_t(*first))) { + first++; } - if (pns.too_many_digits) +#endif + if (first == last) { + answer.ec = std::errc::invalid_argument; + answer.ptr = first; + return answer; + } + parsed_number_string pns = parse_number_string(first, last, options); + if (!pns.valid) { + return detail::parse_infnan(first, last, value); + } + if (pns.too_many_digits) { parse_truncated_number_string(pns); + } answer.ec = std::errc(); // be optimistic answer.ptr = pns.lastmatch; @@ -220,26 +227,6 @@ from_chars_result from_chars_preparsed(parsed_number_string pns, c return answer; } -template -FASTFLOAT_CONSTEXPR20 -from_chars_result from_chars_advanced(const CharT *first, const CharT *last, - T &value, parse_options options) noexcept { - - from_chars_result answer; -#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default - while ((first != last) && fast_float::is_space(uint8_t(*first))) { - first++; - } -#endif - if (first == last) { - answer.ec = std::errc::invalid_argument; - answer.ptr = first; - return answer; - } - answer = from_chars_preparsed(parse_number_string(first, last, options), first, last, value, options); - return answer; -} - } // namespace fast_float #endif