This commit is contained in:
IRainman 2025-12-28 14:08:05 +03:00
commit c1265cf9ed
4 changed files with 26 additions and 24 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.14)
project(fast_float VERSION 8.1.0 LANGUAGES CXX) project(fast_float VERSION 8.2.0 LANGUAGES CXX)
set(FASTFLOAT_CXX_STANDARD 11 CACHE STRING "the C++ standard to use for fastfloat") set(FASTFLOAT_CXX_STANDARD 11 CACHE STRING "the C++ standard to use for fastfloat")
set(CMAKE_CXX_STANDARD ${FASTFLOAT_CXX_STANDARD}) set(CMAKE_CXX_STANDARD ${FASTFLOAT_CXX_STANDARD})
option(FASTFLOAT_TEST "Enable tests" OFF) option(FASTFLOAT_TEST "Enable tests" OFF)

View File

@ -569,7 +569,7 @@ sufficiently recent version of CMake (3.11 or better at least):
FetchContent_Declare( FetchContent_Declare(
fast_float fast_float
GIT_REPOSITORY https://github.com/fastfloat/fast_float.git GIT_REPOSITORY https://github.com/fastfloat/fast_float.git
GIT_TAG tags/v8.1.0 GIT_TAG tags/v8.2.0
GIT_SHALLOW TRUE) GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(fast_float) FetchContent_MakeAvailable(fast_float)
@ -585,7 +585,7 @@ You may also use [CPM](https://github.com/cpm-cmake/CPM.cmake), like so:
CPMAddPackage( CPMAddPackage(
NAME fast_float NAME fast_float
GITHUB_REPOSITORY "fastfloat/fast_float" GITHUB_REPOSITORY "fastfloat/fast_float"
GIT_TAG v8.1.0) GIT_TAG v8.2.0)
``` ```
## Using as single header ## Using as single header
@ -597,7 +597,7 @@ if desired as described in the command line help.
You may directly download automatically generated single-header files: You may directly download automatically generated single-header files:
<https://github.com/fastfloat/fast_float/releases/download/v8.1.0/fast_float.h> <https://github.com/fastfloat/fast_float/releases/download/v8.2.0/fast_float.h>
## Benchmarking ## Benchmarking

View File

@ -574,33 +574,36 @@ parse_int_string(UC const *p, UC const *pend, T &value,
return answer; return answer;
} }
union { uint32_t digits;
uint8_t as_str[4];
uint32_t as_int;
} digits;
if (cpp20_and_in_constexpr()) { #if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST
digits.as_int = 0; if (std::is_constant_evaluated()) {
uint8_t str[4];
for (uint_fast8_t j = 0; j < 4 && j < len; ++j) { for (uint_fast8_t j = 0; j < 4 && j < len; ++j) {
digits.as_str[j] = static_cast<uint8_t>(p[j]); str[j] = static_cast<uint8_t>(p[j]);
} }
} else if (len >= 4) { digits = bit_cast<uint32_t>(str);
memcpy(&digits.as_int, p, 4); }
#else
if (false) {
}
#endif
else if (len >= 4) {
std::memcpy(&digits, p, 4);
} else { } else {
uint32_t b0 = static_cast<uint8_t>(p[0]); uint32_t b0 = static_cast<uint8_t>(p[0]);
uint32_t b1 = (len > 1) ? static_cast<uint8_t>(p[1]) : 0xFFu; uint32_t b1 = (len > 1) ? static_cast<uint8_t>(p[1]) : 0xFFu;
uint32_t b2 = (len > 2) ? static_cast<uint8_t>(p[2]) : 0xFFu; uint32_t b2 = (len > 2) ? static_cast<uint8_t>(p[2]) : 0xFFu;
uint32_t b3 = 0xFFu; uint32_t b3 = 0xFFu;
#if FASTFLOAT_IS_BIG_ENDIAN #if FASTFLOAT_IS_BIG_ENDIAN
digits.as_int = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; digits = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
#else #else
digits.as_int = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); digits = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
#endif #endif
} }
const uint32_t magic = const uint32_t magic =
((digits.as_int + 0x46464646u) | (digits.as_int - 0x30303030u)) & ((digits + 0x46464646u) | (digits - 0x30303030u)) & 0x80808080u;
0x80808080u;
const auto tz = const auto tz =
static_cast<limb_t>(countr_zero_32(magic)); // 7, 15, 23, 31, or 32 static_cast<limb_t>(countr_zero_32(magic)); // 7, 15, 23, 31, or 32
limb_t nd = (tz == 32) ? 4 : (tz >> 3); limb_t nd = (tz == 32) ? 4 : (tz >> 3);
@ -630,18 +633,17 @@ parse_int_string(UC const *p, UC const *pend, T &value,
return answer; return answer;
} }
digits.as_int ^= 0x30303030u; digits ^= 0x30303030u;
digits.as_int <<= ((4 - nd) * 8); digits <<= ((4 - nd) * 8);
const uint32_t check = ((digits.as_int >> 24) & 0xff) | const uint32_t check = ((digits >> 24) & 0xff) | ((digits >> 8) & 0xff00) |
((digits.as_int >> 8) & 0xff00) | ((digits << 8) & 0xff0000);
((digits.as_int << 8) & 0xff0000);
if (check > 0x00020505) { if (check > 0x00020505) {
answer.ec = std::errc::result_out_of_range; answer.ec = std::errc::result_out_of_range;
answer.ptr = p + nd; answer.ptr = p + nd;
return answer; return answer;
} }
value = static_cast<uint8_t>((0x640a01 * digits.as_int) >> 24); value = static_cast<uint8_t>((0x640a01 * digits) >> 24);
answer.ec = std::errc(); answer.ec = std::errc();
answer.ptr = p + nd; answer.ptr = p + nd;
return answer; return answer;

View File

@ -16,7 +16,7 @@
#include "constexpr_feature_detect.h" #include "constexpr_feature_detect.h"
#define FASTFLOAT_VERSION_MAJOR 8 #define FASTFLOAT_VERSION_MAJOR 8
#define FASTFLOAT_VERSION_MINOR 1 #define FASTFLOAT_VERSION_MINOR 2
#define FASTFLOAT_VERSION_PATCH 0 #define FASTFLOAT_VERSION_PATCH 0
#define FASTFLOAT_STRINGIZE_IMPL(x) #x #define FASTFLOAT_STRINGIZE_IMPL(x) #x