This commit is contained in:
IRainman 2026-01-20 21:35:39 +03:00
commit e3cf45fc64
23 changed files with 173 additions and 36 deletions

View File

@ -18,7 +18,7 @@ jobs:
- riscv64 - riscv64
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v6
- name: Install latest Alpine Linux for ${{ matrix.arch }} - name: Install latest Alpine Linux for ${{ matrix.arch }}
uses: jirutka/setup-alpine@v1 uses: jirutka/setup-alpine@v1

View File

@ -6,7 +6,7 @@ jobs:
ubuntu-build: ubuntu-build:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Compile with amalgamation - name: Compile with amalgamation
run: | run: |
mkdir build && mkdir build &&

View File

@ -20,7 +20,7 @@ jobs:
fuzz-seconds: 300 fuzz-seconds: 300
output-sarif: true output-sarif: true
- name: Upload Crash - name: Upload Crash
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v6
if: failure() && steps.build.outcome == 'success' if: failure() && steps.build.outcome == 'success'
with: with:
name: artifacts name: artifacts

View File

@ -4,13 +4,13 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v4.2.2 - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v4.2.2
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
- uses: mymindstorm/setup-emsdk@6ab9eb1bda2574c4ddb79809fc9247783eaf9021 # v14 - uses: mymindstorm/setup-emsdk@6ab9eb1bda2574c4ddb79809fc9247783eaf9021 # v14
- name: Verify - name: Verify
run: emcc -v run: emcc -v
- name: Checkout - name: Checkout
uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v3.6.0 uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v3.6.0
- name: Configure - name: Configure
run: emcmake cmake -B build run: emcmake cmake -B build
- name: Build # We build but do not test - name: Build # We build but do not test

View File

@ -24,10 +24,10 @@ jobs:
lint-and-format: lint-and-format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v4.1.7 - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v4.1.7
- name: Run clang-format - name: Run clang-format
uses: jidicula/clang-format-action@4726374d1aa3c6aecf132e5197e498979588ebc8 # v4.15.0 uses: jidicula/clang-format-action@6cd220de46c89139a0365edae93eee8eb30ca8fe # v4.16.0
with: with:
clang-format-version: '17' clang-format-version: '17'

View File

@ -23,7 +23,7 @@ jobs:
CMAKE_GENERATOR: Ninja CMAKE_GENERATOR: Ninja
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- uses: msys2/setup-msys2@v2 - uses: msys2/setup-msys2@v2
with: with:
update: true update: true

View File

@ -29,7 +29,7 @@ jobs:
CMAKE_GENERATOR: Ninja CMAKE_GENERATOR: Ninja
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- uses: msys2/setup-msys2@v2 - uses: msys2/setup-msys2@v2
with: with:
update: true update: true

View File

@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Amalgamate fast_float.h - name: Amalgamate fast_float.h
run: | run: |

View File

@ -6,7 +6,7 @@ jobs:
build: build:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Install packages - name: Install packages
run: | run: |
sudo apt-get update -q -y sudo apt-get update -q -y

View File

@ -12,7 +12,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- uses: uraimo/run-on-arch-action@v3 - uses: uraimo/run-on-arch-action@v3
name: Test name: Test
id: runcmd id: runcmd

View File

@ -6,7 +6,7 @@ jobs:
ubuntu-build: ubuntu-build:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Install clang++-14 - name: Install clang++-14
run: sudo apt-get install -y clang++-14 run: sudo apt-get install -y clang++-14
- name: Use cmake - name: Use cmake

View File

@ -6,7 +6,7 @@ jobs:
ubuntu-build: ubuntu-build:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Use cmake - name: Use cmake
run: | run: |
mkdir build && mkdir build &&

View File

@ -6,7 +6,7 @@ jobs:
ubuntu-build: ubuntu-build:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Use cmake - name: Use cmake
run: | run: |
mkdir build && mkdir build &&

View File

@ -6,7 +6,7 @@ jobs:
ubuntu-build: ubuntu-build:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Use cmake - name: Use cmake
run: | run: |
mkdir build && mkdir build &&

View File

@ -8,7 +8,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Use cmake - name: Use cmake
run: | run: |
mkdir build && mkdir build &&

View File

@ -6,7 +6,7 @@ jobs:
ubuntu-build: ubuntu-build:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v6
- name: Use cmake - name: Use cmake
run: | run: |
set -xe set -xe

View File

@ -14,7 +14,7 @@ jobs:
- {gen: Visual Studio 17 2022, arch: ARM64, cfg: Debug} - {gen: Visual Studio 17 2022, arch: ARM64, cfg: Debug}
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v5 uses: actions/checkout@v6
- name: configure - name: configure
run: | run: |
cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}} -DCMAKE_CROSSCOMPILING=1 -DFASTFLOAT_TEST=ON cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}} -DCMAKE_CROSSCOMPILING=1 -DFASTFLOAT_TEST=ON

View File

@ -16,7 +16,7 @@ jobs:
- {gen: Visual Studio 17 2022, arch: x64, cfg: Debug} - {gen: Visual Studio 17 2022, arch: x64, cfg: Debug}
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v5 uses: actions/checkout@v6
- name: configure - name: configure
run: | run: |
cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}} -DFASTFLOAT_BENCHMARKS=ON -DFASTFLOAT_TEST=ON -DCMAKE_INSTALL_PREFIX:PATH=destination cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}} -DFASTFLOAT_BENCHMARKS=ON -DFASTFLOAT_TEST=ON -DCMAKE_INSTALL_PREFIX:PATH=destination

View File

@ -16,7 +16,7 @@ jobs:
- {gen: Visual Studio 17 2022, arch: x64, cfg: Debug} - {gen: Visual Studio 17 2022, arch: x64, cfg: Debug}
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v5 uses: actions/checkout@v6
- name: Configure - name: Configure
run: | run: |
cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}} -DFASTFLOAT_BENCHMARKS=ON -T ClangCL -DFASTFLOAT_TEST=ON cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}} -DFASTFLOAT_BENCHMARKS=ON -T ClangCL -DFASTFLOAT_TEST=ON

View File

@ -16,7 +16,7 @@ jobs:
- {gen: Visual Studio 17 2022, arch: x64, cfg: Debug} - {gen: Visual Studio 17 2022, arch: x64, cfg: Debug}
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v5 uses: actions/checkout@v6
- name: configure - name: configure
run: >- run: >-
cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}} cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}}

View File

@ -71,7 +71,7 @@ int main() {
} }
``` ```
Though the C++17 standard has you do a comparison with `std::errc()` to check whether the conversion worked, you can avoid it by casting the result to a `bool` like so: Prior to C++26, checking for a successful `std::from_chars` conversion requires comparing the `from_chars_result::ec` member to `std::errc()`. As an extension `fast_float::from_chars` supports the improved C++26 API that allows checking the result by converting it to `bool`, like so:
```cpp ```cpp
#include "fast_float/fast_float.h" #include "fast_float/fast_float.h"
@ -85,7 +85,7 @@ int main() {
std::cout << "parsed the number " << result << std::endl; std::cout << "parsed the number " << result << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
std::cerr << "failed to parse " << result << std::endl; std::cerr << "failed to parse " << input << std::endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
``` ```

View File

@ -2,6 +2,7 @@
#define FASTFLOAT_FLOAT_COMMON_H #define FASTFLOAT_FLOAT_COMMON_H
#include <cfloat> #include <cfloat>
#include <cstddef>
#include <cstdint> #include <cstdint>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
@ -228,12 +229,16 @@ using parse_options = parse_options_t<char>;
#ifndef FASTFLOAT_ASSERT #ifndef FASTFLOAT_ASSERT
#define FASTFLOAT_ASSERT(x) \ #define FASTFLOAT_ASSERT(x) \
{ ((void)(x)); } { \
((void)(x)); \
}
#endif #endif
#ifndef FASTFLOAT_DEBUG_ASSERT #ifndef FASTFLOAT_DEBUG_ASSERT
#define FASTFLOAT_DEBUG_ASSERT(x) \ #define FASTFLOAT_DEBUG_ASSERT(x) \
{ ((void)(x)); } { \
((void)(x)); \
}
#endif #endif
// rust style `try!()` macro, or `?` operator // rust style `try!()` macro, or `?` operator
@ -322,19 +327,151 @@ struct is_supported_char_type
// TODO? use SSE4.2 there when SSE2 compiler switch in MSVC // TODO? use SSE4.2 there when SSE2 compiler switch in MSVC
// or in other compiler SSE4.2 available? // or in other compiler SSE4.2 available?
template <typename UC>
inline FASTFLOAT_CONSTEXPR14 bool
fastfloat_strncasecmp3(UC const *actual_mixedcase,
UC const *expected_lowercase) {
uint64_t mask{0};
FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 1) { mask = 0x2020202020202020; }
else FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 2) {
mask = 0x0020002000200020;
}
else FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 4) {
mask = 0x0000002000000020;
}
else {
return false;
}
uint64_t val1{0}, val2{0};
if (cpp20_and_in_constexpr()) {
for (size_t i = 0; i < 3; i++) {
if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
return false;
}
return true;
}
} else {
FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 1 || sizeof(UC) == 2) {
::memcpy(&val1, actual_mixedcase, 3 * sizeof(UC));
::memcpy(&val2, expected_lowercase, 3 * sizeof(UC));
val1 |= mask;
val2 |= mask;
return val1 == val2;
}
else FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 4) {
::memcpy(&val1, actual_mixedcase, 2 * sizeof(UC));
::memcpy(&val2, expected_lowercase, 2 * sizeof(UC));
val1 |= mask;
if (val1 != val2) {
return false;
}
return (actual_mixedcase[2] | 32) == (expected_lowercase[2]);
}
else {
return false;
}
}
return true;
}
template <typename UC>
inline FASTFLOAT_CONSTEXPR14 bool
fastfloat_strncasecmp5(UC const *actual_mixedcase,
UC const *expected_lowercase) {
uint64_t mask{0};
uint64_t val1{0}, val2{0};
if (cpp20_and_in_constexpr()) {
for (size_t i = 0; i < 5; i++) {
if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
return false;
}
return true;
}
} else {
FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 1) {
mask = 0x2020202020202020;
::memcpy(&val1, actual_mixedcase, 5 * sizeof(UC));
::memcpy(&val2, expected_lowercase, 5 * sizeof(UC));
val1 |= mask;
val2 |= mask;
return val1 == val2;
}
else FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 2) {
mask = 0x0020002000200020;
::memcpy(&val1, actual_mixedcase, 4 * sizeof(UC));
::memcpy(&val2, expected_lowercase, 4 * sizeof(UC));
val1 |= mask;
if (val1 != val2) {
return false;
}
return (actual_mixedcase[4] | 32) == (expected_lowercase[4]);
}
else FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 4) {
mask = 0x0000002000000020;
::memcpy(&val1, actual_mixedcase, 2 * sizeof(UC));
::memcpy(&val2, expected_lowercase, 2 * sizeof(UC));
val1 |= mask;
if (val1 != val2) {
return false;
}
::memcpy(&val1, actual_mixedcase + 2, 2 * sizeof(UC));
::memcpy(&val2, expected_lowercase + 2, 2 * sizeof(UC));
val1 |= mask;
if (val1 != val2) {
return false;
}
return (actual_mixedcase[4] | 32) == (expected_lowercase[4]);
}
else {
return false;
}
}
return true;
}
// Compares two ASCII strings in a case insensitive manner. // Compares two ASCII strings in a case insensitive manner.
template <typename UC> template <typename UC>
inline FASTFLOAT_CONSTEXPR14 bool inline FASTFLOAT_CONSTEXPR14 bool
fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase, fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase,
uint_fast8_t const length) noexcept { uint_fast8_t const length) noexcept {
for (uint_fast8_t i = 0; i != length; ++i) { uint64_t mask{0};
UC const actual = actual_mixedcase[i]; FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 1) { mask = 0x2020202020202020; }
if ((actual < 256 ? actual | 32 : actual) != expected_lowercase[i]) { else FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 2) {
return false; mask = 0x0020002000200020;
} }
else FASTFLOAT_IF_CONSTEXPR17(sizeof(UC) == 4) {
mask = 0x0000002000000020;
}
else {
return false;
}
if (cpp20_and_in_constexpr()) {
for (size_t i = 0; i < length; i++) {
if ((actual_mixedcase[i] | 32) != expected_lowercase[i]) {
return false;
}
return true;
}
} else {
uint64_t val1{0}, val2{0};
size_t sz{8 / (sizeof(UC))};
for (size_t i = 0; i < length; i += sz) {
val1 = val2 = 0;
sz = std::min(sz, length - i);
::memcpy(&val1, actual_mixedcase + i, sz * sizeof(UC));
::memcpy(&val2, expected_lowercase + i, sz * sizeof(UC));
val1 |= mask;
val2 |= mask;
if (val1 != val2) {
return false;
}
}
return true;
} }
return true;
} }
#endif #endif

View File

@ -39,7 +39,7 @@ from_chars_result_t<UC>
} }
if (last - first >= 3) { if (last - first >= 3) {
if (fastfloat_strncasecmp(first, str_const_nan<UC>(), 3)) { if (fastfloat_strncasecmp3(first, str_const_nan<UC>())) {
answer.ptr = (first += 3); answer.ptr = (first += 3);
value = minusSign ? -std::numeric_limits<T>::quiet_NaN() value = minusSign ? -std::numeric_limits<T>::quiet_NaN()
: std::numeric_limits<T>::quiet_NaN(); : std::numeric_limits<T>::quiet_NaN();
@ -58,9 +58,9 @@ from_chars_result_t<UC>
} }
return answer; return answer;
} }
if (fastfloat_strncasecmp(first, str_const_inf<UC>(), 3)) { if (fastfloat_strncasecmp3(first, str_const_inf<UC>())) {
if ((last - first >= 8) && if ((last - first >= 8) &&
fastfloat_strncasecmp(first + 3, str_const_inf<UC>() + 3, 5)) { fastfloat_strncasecmp5(first + 3, str_const_inf<UC>() + 3)) {
answer.ptr = first + 8; answer.ptr = first + 8;
} else { } else {
answer.ptr = first + 3; answer.ptr = first + 3;