Use chars_format instead of parse_rules for parsing as JSON

This commit is contained in:
Maya Warrier 2023-09-13 20:03:10 -04:00
parent 396f41271f
commit 3f250c5a98
2 changed files with 6 additions and 14 deletions

View File

@ -273,7 +273,6 @@ template <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 fastfloat_really_inline FASTFLOAT_CONSTEXPR20
parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, parse_options_t<UC> options) noexcept { parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, parse_options_t<UC> options) noexcept {
chars_format const fmt = options.format; chars_format const fmt = options.format;
parse_rules const rules = options.rules;
UC const decimal_point = options.decimal_point; UC const decimal_point = options.decimal_point;
parsed_number_string_t<UC> answer; parsed_number_string_t<UC> answer;
@ -289,12 +288,11 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
if (p == pend) { if (p == pend) {
return answer; return answer;
} }
if (rules == parse_rules::json) { if (fmt == chars_format::json) {
if (!is_integer(*p)) { // a sign must be followed by an integer if (!is_integer(*p)) { // a sign must be followed by an integer
return answer; return answer;
} }
} else { } else {
FASTFLOAT_DEBUG_ASSERT(rules == parse_rules::std);
if (!is_integer(*p) && (*p != decimal_point)) { // a sign must be followed by an integer or the dot if (!is_integer(*p) && (*p != decimal_point)) { // a sign must be followed by an integer or the dot
return answer; return answer;
} }
@ -315,7 +313,7 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
int64_t digit_count = int64_t(end_of_integer_part - start_digits); int64_t digit_count = int64_t(end_of_integer_part - start_digits);
answer.integer = span<const UC>(start_digits, size_t(digit_count)); answer.integer = span<const UC>(start_digits, size_t(digit_count));
// disallow leading zeros // disallow leading zeros
if (rules == parse_rules::json && start_digits[0] == UC('0') && digit_count > 1) { if (fmt == chars_format::json && start_digits[0] == UC('0') && digit_count > 1) {
return answer; return answer;
} }
@ -342,7 +340,7 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
return answer; return answer;
} }
// or at least two if a decimal point exists, with json rules // or at least two if a decimal point exists, with json rules
else if (rules == parse_rules::json && has_decimal_point && digit_count == 1) { else if (fmt == chars_format::json && has_decimal_point && digit_count == 1) {
return answer; return answer;
} }
int64_t exp_number = 0; // explicit exponential part int64_t exp_number = 0; // explicit exponential part

View File

@ -16,14 +16,10 @@ enum chars_format {
scientific = 1 << 0, scientific = 1 << 0,
fixed = 1 << 2, fixed = 1 << 2,
hex = 1 << 3, hex = 1 << 3,
json = 1 << 4 | fixed | scientific,
general = fixed | scientific general = fixed | scientific
}; };
enum class parse_rules {
std,
json
};
template <typename UC> template <typename UC>
struct from_chars_result_t { struct from_chars_result_t {
UC const* ptr; UC const* ptr;
@ -34,15 +30,13 @@ using from_chars_result = from_chars_result_t<char>;
template <typename UC> template <typename UC>
struct parse_options_t { struct parse_options_t {
constexpr explicit parse_options_t(chars_format fmt = chars_format::general, constexpr explicit parse_options_t(chars_format fmt = chars_format::general,
UC dot = UC('.'), parse_rules prules = parse_rules::std) UC dot = UC('.'))
: format(fmt), decimal_point(dot), rules(prules) {} : format(fmt), decimal_point(dot) {}
/** Which number formats are accepted */ /** Which number formats are accepted */
chars_format format; chars_format format;
/** The character used as decimal point */ /** The character used as decimal point */
UC decimal_point; UC decimal_point;
/** Rules to use for parsing */
parse_rules rules;
}; };
using parse_options = parse_options_t<char>; using parse_options = parse_options_t<char>;