This commit is contained in:
IRainman 2025-03-12 20:23:05 +03:00
parent f3c60527d5
commit 27c0cd581c
3 changed files with 47 additions and 41 deletions

View File

@ -60,11 +60,11 @@ read8_to_u64(UC const *chars) {
::memcpy(&val, chars, sizeof(uint64_t)); ::memcpy(&val, chars, sizeof(uint64_t));
#if FASTFLOAT_IS_BIG_ENDIAN == 1 #if FASTFLOAT_IS_BIG_ENDIAN == 1
// Need to read as-if the number was in little-endian order. // Need to read as-if the number was in little-endian order.
val = val =
#if FASTFLOAT_HAS_BYTESWAP == 1 #if FASTFLOAT_HAS_BYTESWAP == 1
std:: std::
#endif #endif
byteswap(val); byteswap(val);
#endif #endif
return val; return val;
} }
@ -208,7 +208,8 @@ template <typename UC>
template <typename UC, FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>()) = 0> template <typename UC, FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>()) = 0>
#endif #endif
// dummy for compile // dummy for compile
FASTFLOAT_CONSTEVAL20 bool simd_parse_if_eight_digits_unrolled(UC const *, uint64_t &) { FASTFLOAT_CONSTEVAL20 bool simd_parse_if_eight_digits_unrolled(UC const *,
uint64_t &) {
return 0; return 0;
} }
@ -302,12 +303,12 @@ 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(options.format & chars_format::allow_leading_plus) && (uint64_t(options.format & chars_format::allow_leading_plus) &&
*p == UC('+'))) { *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);
} }
FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) { FASTFLOAT_IF_CONSTEXPR17(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
@ -317,8 +318,8 @@ parse_number_string(UC const *p, UC const *pend,
} }
else { else {
if (!is_integer(*p) && if (!is_integer(*p) &&
(*p != (*p != options.decimal_point)) { // a sign must be followed by an
options.decimal_point)) { // a sign must be followed by an integer or the dot // integer or the dot
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);
} }
@ -385,26 +386,27 @@ parse_number_string(UC const *p, UC const *pend,
((UC('e') == *p) || (UC('E') == *p))) ((UC('e') == *p) || (UC('E') == *p)))
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|| (uint64_t(options.format & detail::basic_fortran_fmt) && || (uint64_t(options.format & detail::basic_fortran_fmt) &&
((UC('+') == *p) || (UC('-') == *p) || ((UC('+') == *p) || (UC('-') == *p) || (UC('d') == *p) ||
(UC('d') == *p) || (UC('D') == *p))) (UC('D') == *p)))
#endif #endif
) { ) {
UC const *location_of_e = p; UC const *location_of_e = p;
if (((UC('e') == *p) || (UC('E') == *p)) if (((UC('e') == *p) || (UC('E') == *p))
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|| (UC('d') == *p) || (UC('D') == *p) || (UC('d') == *p) || (UC('D') == *p)
#endif #endif
) { ) {
++p; ++p;
} }
bool neg_exp = false; bool neg_exp = false;
if (p != pend) { if (p != pend) {
if ( UC('-') == *p) { if (UC('-') == *p) {
neg_exp = true; neg_exp = true;
++p; ++p;
} else if (UC('+') == *p) { // '+' on exponent is allowed by C++17 20.19.3.(7.1) } else if (UC('+') ==
++p; *p) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
} ++p;
}
} }
if ((p == pend) || !is_integer(*p)) { if ((p == pend) || !is_integer(*p)) {
if (!uint64_t(options.format & chars_format::fixed)) { if (!uint64_t(options.format & chars_format::fixed)) {
@ -449,8 +451,8 @@ parse_number_string(UC const *p, UC const *pend,
// We need to be mindful of the case where we only have zeroes... // We need to be mindful of the case where we only have zeroes...
// E.g., 0.000000000...000. // E.g., 0.000000000...000.
UC const *start = start_digits; UC const *start = start_digits;
while ((start != pend) && (*start == UC('0') || while ((start != pend) &&
*start == options.decimal_point)) { (*start == UC('0') || *start == options.decimal_point)) {
if (*start == UC('0')) { if (*start == UC('0')) {
digit_count--; digit_count--;
} }
@ -504,18 +506,19 @@ parse_int_string(UC const *p, UC const *pend, T &value,
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4127) #pragma warning(disable : 4127)
#endif #endif
if (!std::is_signed<T>::value && negative) { if (!std::is_signed<T>::value && negative) {
#ifdef FASTFLOAT_VISUAL_STUDIO #ifdef FASTFLOAT_VISUAL_STUDIO
#pragma warning(pop) #pragma warning(pop)
#endif #endif
answer.ec = std::errc::invalid_argument; answer.ec = std::errc::invalid_argument;
answer.ptr = first; answer.ptr = first;
return answer; return answer;
} }
if ((*p == UC('-')) || if ((*p == UC('-')) ||
(uint64_t(options.format & chars_format::allow_leading_plus) && (*p == UC('+')))) { (uint64_t(options.format & chars_format::allow_leading_plus) &&
++p; (*p == UC('+')))) {
} ++p;
}
#endif #endif
UC const *const start_num = p; UC const *const start_num = p;
@ -538,7 +541,8 @@ parse_int_string(UC const *p, UC const *pend, T &value,
if (digit >= options.base) { if (digit >= options.base) {
break; break;
} }
i = static_cast<uint64_t>(options.base) * i + digit; // might overflow, check this later i = static_cast<uint64_t>(options.base) * i +
digit; // might overflow, check this later
p++; p++;
} }
@ -575,9 +579,9 @@ parse_int_string(UC const *p, UC const *pend, T &value,
if (!std::is_same<T, uint64_t>::value) { if (!std::is_same<T, uint64_t>::value) {
if (i > uint64_t(std::numeric_limits<T>::max()) if (i > uint64_t(std::numeric_limits<T>::max())
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
+ uint64_t(negative) + uint64_t(negative)
#endif #endif
) { ) {
answer.ec = std::errc::result_out_of_range; answer.ec = std::errc::result_out_of_range;
return answer; return answer;
} }

View File

@ -369,8 +369,9 @@ positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept {
// we then need to scale by `2^(f- e)`, and then the two significant digits // we then need to scale by `2^(f- e)`, and then the two significant digits
// are of the same magnitude. // are of the same magnitude.
template <typename T> template <typename T>
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp( inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
bigint &bigmant, const adjusted_mantissa& am, const int32_t exponent) noexcept { negative_digit_comp(bigint &bigmant, const adjusted_mantissa &am,
const int32_t exponent) noexcept {
bigint &real_digits = bigmant; bigint &real_digits = bigmant;
const int32_t &real_exp = exponent; const int32_t &real_exp = exponent;
@ -383,9 +384,9 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp(
T b; T b;
to_float( to_float(
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
false, false,
#endif #endif
am_b, b); am_b, b);
adjusted_mantissa theor = to_extended_halfway(b); adjusted_mantissa theor = to_extended_halfway(b);
bigint theor_digits(theor.mantissa); bigint theor_digits(theor.mantissa);
int32_t theor_exp = theor.power2; int32_t theor_exp = theor.power2;
@ -437,8 +438,8 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp(
// the actual digits. we then compare the big integer representations // the actual digits. we then compare the big integer representations
// of both, and use that to direct rounding. // of both, and use that to direct rounding.
template <typename T, typename UC> template <typename T, typename UC>
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa digit_comp(
digit_comp(const parsed_number_string_t<UC> &num, adjusted_mantissa& am) noexcept { const parsed_number_string_t<UC> &num, adjusted_mantissa &am) noexcept {
// remove the invalid exponent bias // remove the invalid exponent bias
am.power2 -= invalid_am_bias; am.power2 -= invalid_am_bias;

View File

@ -51,7 +51,8 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
template <typename T, typename UC = char, template <typename T, typename UC = char,
typename = FASTFLOAT_ENABLE_IF(is_supported_integer_type<T>::value)> typename = FASTFLOAT_ENABLE_IF(is_supported_integer_type<T>::value)>
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC> FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars(UC const *first, UC const *last, T &value, int const base = 10) noexcept; from_chars(UC const *first, UC const *last, T &value,
int const base = 10) noexcept;
} // namespace fast_float } // namespace fast_float