From 63eb578d527536eb63336e7b11d9274bba1c7623 Mon Sep 17 00:00:00 2001 From: IRainman Date: Sun, 9 Mar 2025 22:55:04 +0300 Subject: [PATCH] Add FASTFLOAT_HAS_BYTESWAP check. Improve FASTFLOAT_CONSTEVAL20 usage for older standards. --- include/fast_float/ascii_number.h | 35 ++++++++++++------- include/fast_float/constexpr_feature_detect.h | 8 ++++- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index ca47afd..7c2f5fd 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -35,12 +35,14 @@ fastfloat_really_inline constexpr bool is_integer(UC c) noexcept { return !(c > UC('9') || c < UC('0')); } +#if FASTFLOAT_HAS_BYTESWAP == 0 fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) { return (val & 0xFF00000000000000) >> 56 | (val & 0x00FF000000000000) >> 40 | (val & 0x0000FF0000000000) >> 24 | (val & 0x000000FF00000000) >> 8 | (val & 0x00000000FF000000) << 8 | (val & 0x0000000000FF0000) << 24 | (val & 0x000000000000FF00) << 40 | (val & 0x00000000000000FF) << 56; } +#endif // Read 8 UC into a u64. Truncates UC if not char. template @@ -58,7 +60,11 @@ read8_to_u64(UC const *chars) { ::memcpy(&val, chars, sizeof(uint64_t)); #if FASTFLOAT_IS_BIG_ENDIAN == 1 // Need to read as-if the number was in little-endian order. - val = byteswap(val); + val = +#if FASTFLOAT_HAS_BYTESWAP == 1 + std:: +#endif + byteswap(val); #endif return val; } @@ -382,24 +388,27 @@ parse_number_string(UC const *p, UC const *pend, if ((uint64_t(options.format & chars_format::scientific) && (p != pend) && ((UC('e') == *p) || (UC('E') == *p))) #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN - || (uint64_t(options.format & detail::basic_fortran_fmt) && (p != pend) && - ((UC('+') == *p) || (UC('-') == *p) || (UC('d') == *p) || - (UC('D') == *p))) + || (uint64_t(options.format & detail::basic_fortran_fmt) && + ((UC('+') == *p) || (UC('-') == *p) || + (UC('d') == *p) || (UC('D') == *p))) #endif ) { UC const *location_of_e = p; - if ((UC('e') == *p) || (UC('E') == *p) || (UC('d') == *p) || - (UC('D') == *p)) { + if (((UC('e') == *p) || (UC('E') == *p)) +#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN + || (UC('d') == *p) || (UC('D') == *p) +#endif + ) { ++p; } bool neg_exp = false; - if ((p != pend) && (UC('-') == *p)) { - neg_exp = true; - ++p; - } else if ((p != pend) && - (UC('+') == - *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1) - ++p; + if (p != pend) { + if ( UC('-') == *p) { + neg_exp = true; + ++p; + } else if (UC('+') == *p) { // '+' on exponent is allowed by C++17 20.19.3.(7.1) + ++p; + } } if ((p == pend) || !is_integer(*p)) { if (!uint64_t(options.format & chars_format::fixed)) { diff --git a/include/fast_float/constexpr_feature_detect.h b/include/fast_float/constexpr_feature_detect.h index 6e876c5..238c850 100644 --- a/include/fast_float/constexpr_feature_detect.h +++ b/include/fast_float/constexpr_feature_detect.h @@ -27,6 +27,12 @@ #define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0 #endif +#if defined(__cpp_lib_byteswap) +#define FASTFLOAT_HAS_BYTESWAP 1 +#else +#define FASTFLOAT_HAS_BYTESWAP 0 +#endif + // Testing for relevant C++20 constexpr library features #if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST && \ defined(__cpp_lib_constexpr_algorithms) && \ @@ -36,7 +42,7 @@ #define FASTFLOAT_IS_CONSTEXPR 1 #else #define FASTFLOAT_CONSTEXPR20 -#define FASTFLOAT_CONSTEVAL20 +#define FASTFLOAT_CONSTEVAL20 FASTFLOAT_CONSTEXPR14 #define FASTFLOAT_IS_CONSTEXPR 0 #endif