mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-01-01 03:12:18 +08:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
011763f31c | ||
|
|
d5bc4e1b2e | ||
|
|
97b54ca9e7 | ||
|
|
6499e20cf9 | ||
|
|
4dc5225797 | ||
|
|
fb522b66d0 | ||
|
|
11ce67e5eb | ||
|
|
4f77642195 | ||
|
|
f4f9da1e6b | ||
|
|
fd85e52349 |
6
.github/workflows/s390x.yml
vendored
6
.github/workflows/s390x.yml
vendored
@ -3,10 +3,10 @@ name: Ubuntu s390x (GCC 11)
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- main
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- main
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@ -24,7 +24,7 @@ jobs:
|
|||||||
apt-get update -q -y
|
apt-get update -q -y
|
||||||
apt-get install -y cmake make g++
|
apt-get install -y cmake make g++
|
||||||
run: |
|
run: |
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release -B build
|
cmake -DCMAKE_BUILD_TYPE=Release -B build -DFASTFLOAT_TEST=ON
|
||||||
cmake --build build -j=2
|
cmake --build build -j=2
|
||||||
ctest --output-on-failure --test-dir build
|
ctest --output-on-failure --test-dir build
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
|
||||||
project(fast_float VERSION 8.2.0 LANGUAGES CXX)
|
project(fast_float VERSION 8.2.2 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)
|
||||||
|
|||||||
@ -533,7 +533,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.2.0
|
GIT_TAG tags/v8.2.2
|
||||||
GIT_SHALLOW TRUE)
|
GIT_SHALLOW TRUE)
|
||||||
|
|
||||||
FetchContent_MakeAvailable(fast_float)
|
FetchContent_MakeAvailable(fast_float)
|
||||||
@ -549,7 +549,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.2.0)
|
GIT_TAG v8.2.2)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using as single header
|
## Using as single header
|
||||||
@ -561,7 +561,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.2.0/fast_float.h>
|
<https://github.com/fastfloat/fast_float/releases/download/v8.2.2/fast_float.h>
|
||||||
|
|
||||||
## Benchmarking
|
## Benchmarking
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,11 @@ fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) {
|
|||||||
(val & 0x000000000000FF00) << 40 | (val & 0x00000000000000FF) << 56;
|
(val & 0x000000000000FF00) << 40 | (val & 0x00000000000000FF) << 56;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fastfloat_really_inline constexpr uint32_t byteswap_32(uint32_t val) {
|
||||||
|
return (val >> 24) | ((val >> 8) & 0x0000FF00u) | ((val << 8) & 0x00FF0000u) |
|
||||||
|
(val << 24);
|
||||||
|
}
|
||||||
|
|
||||||
// Read 8 UC into a u64. Truncates UC if not char.
|
// Read 8 UC into a u64. Truncates UC if not char.
|
||||||
template <typename UC>
|
template <typename UC>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
||||||
@ -510,91 +515,95 @@ parse_int_string(UC const *p, UC const *pend, T &value,
|
|||||||
UC const *const start_digits = p;
|
UC const *const start_digits = p;
|
||||||
|
|
||||||
FASTFLOAT_IF_CONSTEXPR17((std::is_same<T, std::uint8_t>::value)) {
|
FASTFLOAT_IF_CONSTEXPR17((std::is_same<T, std::uint8_t>::value)) {
|
||||||
const size_t len = (size_t)(pend - p);
|
if (base == 10) {
|
||||||
if (len == 0) {
|
const size_t len = (size_t)(pend - p);
|
||||||
if (has_leading_zeros) {
|
if (len == 0) {
|
||||||
value = 0;
|
if (has_leading_zeros) {
|
||||||
answer.ec = std::errc();
|
value = 0;
|
||||||
answer.ptr = p;
|
answer.ec = std::errc();
|
||||||
} else {
|
answer.ptr = p;
|
||||||
answer.ec = std::errc::invalid_argument;
|
} else {
|
||||||
answer.ptr = first;
|
answer.ec = std::errc::invalid_argument;
|
||||||
}
|
answer.ptr = first;
|
||||||
return answer;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t digits;
|
|
||||||
|
|
||||||
#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST
|
|
||||||
if (std::is_constant_evaluated()) {
|
|
||||||
uint8_t str[4]{};
|
|
||||||
for (size_t j = 0; j < 4 && j < len; ++j) {
|
|
||||||
str[j] = static_cast<uint8_t>(p[j]);
|
|
||||||
}
|
|
||||||
digits = std::bit_cast<uint32_t>(str);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (false) {
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (len >= 4) {
|
|
||||||
::memcpy(&digits, p, 4);
|
|
||||||
} else {
|
|
||||||
uint32_t b0 = static_cast<uint8_t>(p[0]);
|
|
||||||
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 b3 = 0xFFu;
|
|
||||||
#if FASTFLOAT_IS_BIG_ENDIAN
|
|
||||||
digits = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
|
||||||
#else
|
|
||||||
digits = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t magic =
|
|
||||||
((digits + 0x46464646u) | (digits - 0x30303030u)) & 0x80808080u;
|
|
||||||
uint32_t tz = (uint32_t)countr_zero_32(magic); // 7, 15, 23, 31, or 32
|
|
||||||
uint32_t nd = (tz == 32) ? 4 : (tz >> 3);
|
|
||||||
nd = (uint32_t)std::min((size_t)nd, len);
|
|
||||||
if (nd == 0) {
|
|
||||||
if (has_leading_zeros) {
|
|
||||||
value = 0;
|
|
||||||
answer.ec = std::errc();
|
|
||||||
answer.ptr = p;
|
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
answer.ec = std::errc::invalid_argument;
|
|
||||||
answer.ptr = first;
|
uint32_t digits;
|
||||||
return answer;
|
|
||||||
}
|
#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST
|
||||||
if (nd > 3) {
|
if (std::is_constant_evaluated()) {
|
||||||
const UC *q = p + nd;
|
uint8_t str[4]{};
|
||||||
size_t rem = len - nd;
|
for (size_t j = 0; j < 4 && j < len; ++j) {
|
||||||
while (rem) {
|
str[j] = static_cast<uint8_t>(p[j]);
|
||||||
if (*q < UC('0') || *q > UC('9'))
|
}
|
||||||
break;
|
digits = std::bit_cast<uint32_t>(str);
|
||||||
++q;
|
#if FASTFLOAT_IS_BIG_ENDIAN
|
||||||
--rem;
|
digits = byteswap_32(digits);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (false) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (len >= 4) {
|
||||||
|
::memcpy(&digits, p, 4);
|
||||||
|
#if FASTFLOAT_IS_BIG_ENDIAN
|
||||||
|
digits = byteswap_32(digits);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
uint32_t b0 = static_cast<uint8_t>(p[0]);
|
||||||
|
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 b3 = 0xFFu;
|
||||||
|
digits = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
|
||||||
}
|
}
|
||||||
answer.ec = std::errc::result_out_of_range;
|
|
||||||
answer.ptr = q;
|
|
||||||
return answer;
|
|
||||||
}
|
|
||||||
|
|
||||||
digits ^= 0x30303030u;
|
uint32_t magic =
|
||||||
digits <<= ((4 - nd) * 8);
|
((digits + 0x46464646u) | (digits - 0x30303030u)) & 0x80808080u;
|
||||||
|
uint32_t tz = (uint32_t)countr_zero_32(magic); // 7, 15, 23, 31, or 32
|
||||||
|
uint32_t nd = (tz == 32) ? 4 : (tz >> 3);
|
||||||
|
nd = (uint32_t)std::min((size_t)nd, len);
|
||||||
|
if (nd == 0) {
|
||||||
|
if (has_leading_zeros) {
|
||||||
|
value = 0;
|
||||||
|
answer.ec = std::errc();
|
||||||
|
answer.ptr = p;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
answer.ec = std::errc::invalid_argument;
|
||||||
|
answer.ptr = first;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
if (nd > 3) {
|
||||||
|
const UC *q = p + nd;
|
||||||
|
size_t rem = len - nd;
|
||||||
|
while (rem) {
|
||||||
|
if (*q < UC('0') || *q > UC('9'))
|
||||||
|
break;
|
||||||
|
++q;
|
||||||
|
--rem;
|
||||||
|
}
|
||||||
|
answer.ec = std::errc::result_out_of_range;
|
||||||
|
answer.ptr = q;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t check = ((digits >> 24) & 0xff) | ((digits >> 8) & 0xff00) |
|
digits ^= 0x30303030u;
|
||||||
((digits << 8) & 0xff0000);
|
digits <<= ((4 - nd) * 8);
|
||||||
if (check > 0x00020505) {
|
|
||||||
answer.ec = std::errc::result_out_of_range;
|
uint32_t check = ((digits >> 24) & 0xff) | ((digits >> 8) & 0xff00) |
|
||||||
|
((digits << 8) & 0xff0000);
|
||||||
|
if (check > 0x00020505) {
|
||||||
|
answer.ec = std::errc::result_out_of_range;
|
||||||
|
answer.ptr = p + nd;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
value = (uint8_t)((0x640a01 * digits) >> 24);
|
||||||
|
answer.ec = std::errc();
|
||||||
answer.ptr = p + nd;
|
answer.ptr = p + nd;
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
value = (uint8_t)((0x640a01 * digits) >> 24);
|
|
||||||
answer.ec = std::errc();
|
|
||||||
answer.ptr = p + nd;
|
|
||||||
return answer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#define FASTFLOAT_VERSION_MAJOR 8
|
#define FASTFLOAT_VERSION_MAJOR 8
|
||||||
#define FASTFLOAT_VERSION_MINOR 2
|
#define FASTFLOAT_VERSION_MINOR 2
|
||||||
#define FASTFLOAT_VERSION_PATCH 0
|
#define FASTFLOAT_VERSION_PATCH 2
|
||||||
|
|
||||||
#define FASTFLOAT_STRINGIZE_IMPL(x) #x
|
#define FASTFLOAT_STRINGIZE_IMPL(x) #x
|
||||||
#define FASTFLOAT_STRINGIZE(x) FASTFLOAT_STRINGIZE_IMPL(x)
|
#define FASTFLOAT_STRINGIZE(x) FASTFLOAT_STRINGIZE_IMPL(x)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user