mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-07 01:06:48 +08:00
reducing the overhead of 'json' and 'allow plus' options
This commit is contained in:
parent
1504792a9f
commit
13ba430893
@ -279,7 +279,7 @@ report_parse_error(UC const *p, parse_error error) {
|
|||||||
|
|
||||||
// Assuming that you use no more than 19 digits, this will
|
// Assuming that you use no more than 19 digits, this will
|
||||||
// parse an ASCII string.
|
// parse an ASCII string.
|
||||||
template <typename UC>
|
template <bool allow_leading_plus, bool basic_json_fmt, typename UC>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
|
||||||
parse_number_string(UC const *p, UC const *pend,
|
parse_number_string(UC const *p, UC const *pend,
|
||||||
parse_options_t<UC> options) noexcept {
|
parse_options_t<UC> options) noexcept {
|
||||||
@ -293,14 +293,14 @@ parse_number_string(UC const *p, UC const *pend,
|
|||||||
answer.negative = (*p == UC('-'));
|
answer.negative = (*p == UC('-'));
|
||||||
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
||||||
if ((*p == UC('-')) ||
|
if ((*p == UC('-')) ||
|
||||||
(uint64_t(fmt & chars_format::allow_leading_plus) &&
|
(allow_leading_plus &&
|
||||||
!uint64_t(fmt & detail::basic_json_fmt) && *p == UC('+'))) {
|
!basic_json_fmt && *p == UC('+'))) {
|
||||||
++p;
|
++p;
|
||||||
if (p == pend) {
|
if (p == pend) {
|
||||||
return report_parse_error<UC>(
|
return report_parse_error<UC>(
|
||||||
p, parse_error::missing_integer_or_dot_after_sign);
|
p, parse_error::missing_integer_or_dot_after_sign);
|
||||||
}
|
}
|
||||||
if (uint64_t(fmt & detail::basic_json_fmt)) {
|
if (basic_json_fmt) {
|
||||||
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 report_parse_error<UC>(p,
|
return report_parse_error<UC>(p,
|
||||||
parse_error::missing_integer_after_sign);
|
parse_error::missing_integer_after_sign);
|
||||||
@ -329,7 +329,7 @@ parse_number_string(UC const *p, UC const *pend,
|
|||||||
UC const *const end_of_integer_part = p;
|
UC const *const end_of_integer_part = p;
|
||||||
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<UC const>(start_digits, size_t(digit_count));
|
answer.integer = span<UC const>(start_digits, size_t(digit_count));
|
||||||
if (uint64_t(fmt & detail::basic_json_fmt)) {
|
if (basic_json_fmt) {
|
||||||
// at least 1 digit in integer part, without leading zeros
|
// at least 1 digit in integer part, without leading zeros
|
||||||
if (digit_count == 0) {
|
if (digit_count == 0) {
|
||||||
return report_parse_error<UC>(p, parse_error::no_digits_in_integer_part);
|
return report_parse_error<UC>(p, parse_error::no_digits_in_integer_part);
|
||||||
@ -358,7 +358,7 @@ parse_number_string(UC const *p, UC const *pend,
|
|||||||
answer.fraction = span<UC const>(before, size_t(p - before));
|
answer.fraction = span<UC const>(before, size_t(p - before));
|
||||||
digit_count -= exponent;
|
digit_count -= exponent;
|
||||||
}
|
}
|
||||||
if (uint64_t(fmt & detail::basic_json_fmt)) {
|
if (basic_json_fmt) {
|
||||||
// at least 1 digit in fractional part
|
// at least 1 digit in fractional part
|
||||||
if (has_decimal_point && exponent == 0) {
|
if (has_decimal_point && exponent == 0) {
|
||||||
return report_parse_error<UC>(p,
|
return report_parse_error<UC>(p,
|
||||||
@ -470,11 +470,11 @@ parse_number_string(UC const *p, UC const *pend,
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename UC>
|
template <bool allow_leading_plus = false, typename T, typename UC>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
parse_int_string(UC const *p, UC const *pend, T &value,
|
parse_int_string(UC const *p, UC const *pend, T &value,
|
||||||
parse_options_t<UC> options) {
|
parse_options_t<UC> options) {
|
||||||
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
//chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
||||||
int const base = options.base;
|
int const base = options.base;
|
||||||
|
|
||||||
from_chars_result_t<UC> answer;
|
from_chars_result_t<UC> answer;
|
||||||
@ -495,7 +495,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
if ((*p == UC('-')) ||
|
if ((*p == UC('-')) ||
|
||||||
(uint64_t(fmt & chars_format::allow_leading_plus) && (*p == UC('+')))) {
|
(allow_leading_plus && (*p == UC('+')))) {
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -304,8 +304,11 @@ from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
|||||||
answer.ptr = first;
|
answer.ptr = first;
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
parsed_number_string_t<UC> pns =
|
bool allow_leading_plus = uint64_t(fmt & chars_format::allow_leading_plus);
|
||||||
parse_number_string<UC>(first, last, options);
|
bool basic_json_fmt = uint64_t(fmt & detail::basic_json_fmt);
|
||||||
|
parsed_number_string_t<UC> pns = allow_leading_plus ?
|
||||||
|
(basic_json_fmt ? parse_number_string<true, true, UC>(first, last, options): parse_number_string<true, false, UC>(first, last, options)) :
|
||||||
|
(basic_json_fmt ? parse_number_string<false, true, UC>(first, last, options): parse_number_string<false, false, UC>(first, last, options));
|
||||||
if (!pns.valid) {
|
if (!pns.valid) {
|
||||||
if (uint64_t(fmt & chars_format::no_infnan)) {
|
if (uint64_t(fmt & chars_format::no_infnan)) {
|
||||||
answer.ec = std::errc::invalid_argument;
|
answer.ec = std::errc::invalid_argument;
|
||||||
|
|||||||
@ -131,7 +131,7 @@ int main() {
|
|||||||
for (std::size_t i = 0; i < reject.size(); ++i) {
|
for (std::size_t i = 0; i < reject.size(); ++i) {
|
||||||
auto const &f = reject[i].input;
|
auto const &f = reject[i].input;
|
||||||
auto const &expected_reason = reject[i].reason;
|
auto const &expected_reason = reject[i].reason;
|
||||||
auto answer = fast_float::parse_number_string(
|
auto answer = fast_float::parse_number_string<true, true>(
|
||||||
f.data(), f.data() + f.size(),
|
f.data(), f.data() + f.size(),
|
||||||
fast_float::parse_options(
|
fast_float::parse_options(
|
||||||
fast_float::chars_format::json |
|
fast_float::chars_format::json |
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user