Hi,
Am 25.10.25 um 08:08 schrieb Rene Engelhard:
Am 23.10.25 um 03:13 schrieb Jeremy Bícha:
On Sun, Sep 21, 2025 at 12:39 PM Rene Engelhard<[email protected]> wrote:
please update to current 8.1.0
[ because LibreOffice will start using this in 26.2+ I looked at this and
tried to update to 8.1.0 which is the current upstream release. I could
do this, have it prepared here. vte2.91 and transmission built fine ]
It has been a month since your proposal with no response. I think you
could go ahead and do an NMU now if you like.
Yes, probably.
A debdiff is not exactly meaningful given it includes a new upstream which
clobbers this up but...
It is attached..
Will NMU in one week I guess.
As said a week ago I now uploaded the package with the attached debdiff of the previous
mail (with "releasing" it today)
to DELAYED/14-day.
Please cancel (or tell me to cancel) if you wanted to do an upload yourself.
Final debdiff attached.
Regards,
Rene
diff -Nru fast-float-8.0.0/benchmarks/benchmark.cpp
fast-float-8.1.0/benchmarks/benchmark.cpp
--- fast-float-8.0.0/benchmarks/benchmark.cpp 2025-02-08 17:49:58.000000000
+0100
+++ fast-float-8.1.0/benchmarks/benchmark.cpp 2025-09-18 17:38:45.000000000
+0200
@@ -1,7 +1,7 @@
#if defined(__linux__) || (__APPLE__ && __aarch64__)
#define USING_COUNTERS
-#include "event_counter.h"
#endif
+#include "event_counter.h"
#include <algorithm>
#include "fast_float/fast_float.h"
#include <chrono>
@@ -236,6 +236,11 @@
<< std::endl;
#endif
}
+ if (argc > 1) {
+ fileload(argv[1]);
+ return EXIT_SUCCESS;
+ }
fileload(std::string(BENCHMARK_DATA_DIR) + "/canada.txt");
fileload(std::string(BENCHMARK_DATA_DIR) + "/mesh.txt");
+ return EXIT_SUCCESS;
}
diff -Nru fast-float-8.0.0/benchmarks/event_counter.h
fast-float-8.1.0/benchmarks/event_counter.h
--- fast-float-8.0.0/benchmarks/event_counter.h 2025-02-08 17:49:58.000000000
+0100
+++ fast-float-8.1.0/benchmarks/event_counter.h 2025-09-18 17:38:45.000000000
+0200
@@ -17,7 +17,7 @@
#include <libgen.h>
#endif
-#if __APPLE__ && __aarch64__
+#if (defined(__APPLE__) && __APPLE__) && (defined(__aarch64__) && __aarch64__)
#include "apple_arm_events.h"
#endif
diff -Nru fast-float-8.0.0/cmake/toolchains-ci/riscv64-linux-gnu.cmake
fast-float-8.1.0/cmake/toolchains-ci/riscv64-linux-gnu.cmake
--- fast-float-8.0.0/cmake/toolchains-ci/riscv64-linux-gnu.cmake
1970-01-01 01:00:00.000000000 +0100
+++ fast-float-8.1.0/cmake/toolchains-ci/riscv64-linux-gnu.cmake
2025-09-18 17:38:45.000000000 +0200
@@ -0,0 +1,4 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR riscv64)
+
+set(CMAKE_CROSSCOMPILING_EMULATOR "qemu-riscv64-static")
diff -Nru fast-float-8.0.0/CMakeLists.txt fast-float-8.1.0/CMakeLists.txt
--- fast-float-8.0.0/CMakeLists.txt 2025-02-08 17:49:58.000000000 +0100
+++ fast-float-8.1.0/CMakeLists.txt 2025-09-18 17:38:45.000000000 +0200
@@ -1,6 +1,7 @@
-cmake_minimum_required(VERSION 3.9)
+cmake_minimum_required(VERSION 3.14)
-project(fast_float VERSION 8.0.0 LANGUAGES CXX)
+
+project(fast_float VERSION 8.1.0 LANGUAGES CXX)
set(FASTFLOAT_CXX_STANDARD 11 CACHE STRING "the C++ standard to use for
fastfloat")
set(CMAKE_CXX_STANDARD ${FASTFLOAT_CXX_STANDARD})
option(FASTFLOAT_TEST "Enable tests" OFF)
@@ -55,11 +56,15 @@
target_link_libraries(fast_float INTERFACE -fuse-ld=gold)
endif()
endif()
-if(MSVC_VERSION GREATER 1910)
+
+include(CheckCXXCompilerFlag)
+unset(FASTFLOAT_COMPILER_SUPPORTS_PERMISSIVE)
+CHECK_CXX_COMPILER_FLAG(/permissive- FASTFLOAT_COMPILER_SUPPORTS_PERMISSIVE)
+
+if(FASTFLOAT_COMPILER_SUPPORTS_PERMISSIVE)
target_compile_options(fast_float INTERFACE /permissive-)
endif()
-
if(FASTFLOAT_INSTALL)
include(CMakePackageConfigHelpers)
diff -Nru fast-float-8.0.0/debian/changelog fast-float-8.1.0/debian/changelog
--- fast-float-8.0.0/debian/changelog 2025-02-12 00:01:56.000000000 +0100
+++ fast-float-8.1.0/debian/changelog 2025-11-01 08:11:17.000000000 +0100
@@ -1,3 +1,12 @@
+fast-float (8.1.0-0.1) unstable; urgency=medium
+
+ * Non-maintainer upload
+ * New upstream release (closes: #1115913)
+ * don't create fast_float_all.h in the source tree but put it directly where
+ it belongs (closes: #1045133)
+
+ -- Rene Engelhard <[email protected]> Sat, 01 Nov 2025 08:11:17 +0100
+
fast-float (8.0.0-0.1) unstable; urgency=medium
* Non-maintainer upload
diff -Nru fast-float-8.0.0/debian/gbp.conf fast-float-8.1.0/debian/gbp.conf
--- fast-float-8.0.0/debian/gbp.conf 2025-02-12 00:01:56.000000000 +0100
+++ fast-float-8.1.0/debian/gbp.conf 2025-09-21 17:02:45.000000000 +0200
@@ -10,6 +10,7 @@
multimaint-merge = True
[import-orig]
+postimport = dch -v%(version)s New upstream release; git add debian/changelog;
debcommit
upstream-vcs-tag = v%(version)s
[pq]
diff -Nru fast-float-8.0.0/debian/libfast-float-dev.install
fast-float-8.1.0/debian/libfast-float-dev.install
--- fast-float-8.0.0/debian/libfast-float-dev.install 2025-02-12
00:01:56.000000000 +0100
+++ fast-float-8.1.0/debian/libfast-float-dev.install 1970-01-01
01:00:00.000000000 +0100
@@ -1 +0,0 @@
-fast_float_all.h /usr/include/fast_float/
diff -Nru fast-float-8.0.0/debian/rules fast-float-8.1.0/debian/rules
--- fast-float-8.0.0/debian/rules 2025-02-12 00:01:56.000000000 +0100
+++ fast-float-8.1.0/debian/rules 2025-09-21 18:02:36.000000000 +0200
@@ -14,4 +14,5 @@
override_dh_auto_install:
dh_auto_install --destdir=debian/libfast-float-dev/
- python3 script/amalgamate.py > fast_float_all.h
+ python3 script/amalgamate.py > \
+ debian/libfast-float-dev/usr/include/fast_float/fast_float_all.h
diff -Nru fast-float-8.0.0/.github/pull_request_template.md
fast-float-8.1.0/.github/pull_request_template.md
--- fast-float-8.0.0/.github/pull_request_template.md 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/pull_request_template.md 2025-09-18
17:38:45.000000000 +0200
@@ -1,4 +1,5 @@
-We have benchmarks, please consider running them: see our README for details.
+We have benchmarks, please consider running them: [see our README for
details](https://github.com/fastfloat/fast_float/blob/main/README.md#benchmarking).
We expect you to run our benchmarks if you make claims with respect to the
performance.
+
Our CI tests check formatting automating. If such a test fails, please
consider running the bash script:
diff -Nru fast-float-8.0.0/.github/workflows/alpine.yml
fast-float-8.1.0/.github/workflows/alpine.yml
--- fast-float-8.0.0/.github/workflows/alpine.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/alpine.yml 2025-09-18
17:38:45.000000000 +0200
@@ -18,7 +18,7 @@
- riscv64
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: Install latest Alpine Linux for ${{ matrix.arch }}
uses: jirutka/setup-alpine@v1
diff -Nru fast-float-8.0.0/.github/workflows/amalgamate-ubuntu20.yml
fast-float-8.1.0/.github/workflows/amalgamate-ubuntu20.yml
--- fast-float-8.0.0/.github/workflows/amalgamate-ubuntu20.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/amalgamate-ubuntu20.yml 1970-01-01
01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-name: Amalgamate Ubuntu 20.04 CI (GCC 9)
-
-on: [push, pull_request]
-
-jobs:
- ubuntu-build:
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - name: Compile with amalgamation
- run: |
- mkdir build &&
- mkdir build/fast_float &&
- python3 ./script/amalgamate.py > build/fast_float/fast_float.h &&
- cp tests/string_test.cpp build/ &&
- cd build &&
- g++ string_test.cpp
diff -Nru fast-float-8.0.0/.github/workflows/amalgamate-ubuntu24.yml
fast-float-8.1.0/.github/workflows/amalgamate-ubuntu24.yml
--- fast-float-8.0.0/.github/workflows/amalgamate-ubuntu24.yml 1970-01-01
01:00:00.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/amalgamate-ubuntu24.yml 2025-09-18
17:38:45.000000000 +0200
@@ -0,0 +1,17 @@
+name: Amalgamate Ubuntu 24.04 CI
+
+on: [push, pull_request]
+
+jobs:
+ ubuntu-build:
+ runs-on: ubuntu-24.04
+ steps:
+ - uses: actions/checkout@v5
+ - name: Compile with amalgamation
+ run: |
+ mkdir build &&
+ mkdir build/fast_float &&
+ python3 ./script/amalgamate.py > build/fast_float/fast_float.h &&
+ cp tests/string_test.cpp build/ &&
+ cd build &&
+ g++ string_test.cpp
diff -Nru fast-float-8.0.0/.github/workflows/emscripten.yml
fast-float-8.1.0/.github/workflows/emscripten.yml
--- fast-float-8.0.0/.github/workflows/emscripten.yml 1970-01-01
01:00:00.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/emscripten.yml 2025-09-18
17:38:45.000000000 +0200
@@ -0,0 +1,17 @@
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 #
v4.2.2
+ - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #
v4.4.0
+ - uses: mymindstorm/setup-emsdk@6ab9eb1bda2574c4ddb79809fc9247783eaf9021
# v14
+ - name: Verify
+ run: emcc -v
+ - name: Checkout
+ uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 #
v3.6.0
+ - name: Configure
+ run: emcmake cmake -B build
+ - name: Build # We build but do not test
+ run: cmake --build build
diff -Nru fast-float-8.0.0/.github/workflows/lint_and_format_check.yml
fast-float-8.1.0/.github/workflows/lint_and_format_check.yml
--- fast-float-8.0.0/.github/workflows/lint_and_format_check.yml
2025-02-08 17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/lint_and_format_check.yml
2025-09-18 17:38:45.000000000 +0200
@@ -24,10 +24,10 @@
lint-and-format:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@9a9194f87191a7e9055e3e9b95b8cfb13023bb08 #
v4.1.7
+ - uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 #
v4.1.7
- name: Run clang-format
- uses:
jidicula/clang-format-action@d05cecd4a1a5b7e64c22f5a468456135a43f13f6 # v4.14.0
+ uses:
jidicula/clang-format-action@4726374d1aa3c6aecf132e5197e498979588ebc8 # v4.15.0
with:
clang-format-version: '17'
diff -Nru fast-float-8.0.0/.github/workflows/msys2-clang.yml
fast-float-8.1.0/.github/workflows/msys2-clang.yml
--- fast-float-8.0.0/.github/workflows/msys2-clang.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/msys2-clang.yml 2025-09-18
17:38:45.000000000 +0200
@@ -23,7 +23,7 @@
CMAKE_GENERATOR: Ninja
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- uses: msys2/setup-msys2@v2
with:
update: true
diff -Nru fast-float-8.0.0/.github/workflows/msys2.yml
fast-float-8.1.0/.github/workflows/msys2.yml
--- fast-float-8.0.0/.github/workflows/msys2.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/msys2.yml 2025-09-18
17:38:45.000000000 +0200
@@ -29,7 +29,7 @@
CMAKE_GENERATOR: Ninja
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- uses: msys2/setup-msys2@v2
with:
update: true
diff -Nru fast-float-8.0.0/.github/workflows/on-release.yml
fast-float-8.1.0/.github/workflows/on-release.yml
--- fast-float-8.0.0/.github/workflows/on-release.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/on-release.yml 2025-09-18
17:38:45.000000000 +0200
@@ -16,7 +16,7 @@
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Amalgamate fast_float.h
run: |
diff -Nru fast-float-8.0.0/.github/workflows/risc.yml
fast-float-8.1.0/.github/workflows/risc.yml
--- fast-float-8.0.0/.github/workflows/risc.yml 1970-01-01 01:00:00.000000000
+0100
+++ fast-float-8.1.0/.github/workflows/risc.yml 2025-09-18 17:38:45.000000000
+0200
@@ -0,0 +1,23 @@
+name: Ubuntu RISC-V rvv VLEN=128 (clang 17)
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-24.04
+ steps:
+ - uses: actions/checkout@v4
+ - name: Install packages
+ run: |
+ sudo apt-get update -q -y
+ sudo apt-get install -y cmake make g++-riscv64-linux-gnu
qemu-user-static clang-17
+ - name: Build
+ run: |
+ CXX=clang++-17 CXXFLAGS="--target=riscv64-linux-gnu -march=rv64gcv" \
+ cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake
-DCMAKE_BUILD_TYPE=Release -B build
+ cmake --build build/ -j$(nproc)
+ - name: Test VLEN=128
+ run: |
+ export QEMU_LD_PREFIX="/usr/riscv64-linux-gnu"
+ export QEMU_CPU="rv64,v=on,vlen=128,rvv_ta_all_1s=on,rvv_ma_all_1s=on"
+ ctest --timeout 1800 --output-on-failure --test-dir build -j $(nproc)
diff -Nru fast-float-8.0.0/.github/workflows/s390x.yml
fast-float-8.1.0/.github/workflows/s390x.yml
--- fast-float-8.0.0/.github/workflows/s390x.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/s390x.yml 2025-09-18
17:38:45.000000000 +0200
@@ -12,8 +12,8 @@
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: uraimo/run-on-arch-action@v2
+ - uses: actions/checkout@v5
+ - uses: uraimo/run-on-arch-action@v3
name: Test
id: runcmd
with:
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu20-cxx20.yml
fast-float-8.1.0/.github/workflows/ubuntu20-cxx20.yml
--- fast-float-8.0.0/.github/workflows/ubuntu20-cxx20.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu20-cxx20.yml 1970-01-01
01:00:00.000000000 +0100
@@ -1,19 +0,0 @@
-name: Ubuntu 20.04 CI (C++20)
-
-on: [push, pull_request]
-
-jobs:
- ubuntu-build:
- runs-on: ubuntu-20.04
- strategy:
- fail-fast: false
- steps:
- - uses: actions/checkout@v4
- - name: Use cmake
- run: |
- mkdir build &&
- cd build &&
- cmake -DFASTFLOAT_CXX_STANDARD=20 -DFASTFLOAT_TEST=ON
-DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
- cmake --build . &&
- ctest --output-on-failure &&
- cmake --install .
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu20-fastmath.yml
fast-float-8.1.0/.github/workflows/ubuntu20-fastmath.yml
--- fast-float-8.0.0/.github/workflows/ubuntu20-fastmath.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu20-fastmath.yml 1970-01-01
01:00:00.000000000 +0100
@@ -1,16 +0,0 @@
-name: Ubuntu 20.04 CI (GCC 9, fast-math)
-
-on: [push, pull_request]
-
-jobs:
- ubuntu-build:
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - name: Use cmake
- run: |
- mkdir build &&
- cd build &&
- cmake -DCMAKE_CXX_FLAGS="-ffast-math" -DFASTFLOAT_TEST=ON .. &&
- cmake --build . &&
- ctest --output-on-failure
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu20.yml
fast-float-8.1.0/.github/workflows/ubuntu20.yml
--- fast-float-8.0.0/.github/workflows/ubuntu20.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu20.yml 1970-01-01
01:00:00.000000000 +0100
@@ -1,21 +0,0 @@
-name: Ubuntu 20.04 CI (GCC 9)
-
-on: [push, pull_request]
-
-jobs:
- ubuntu-build:
- runs-on: ubuntu-20.04
- steps:
- - uses: actions/checkout@v4
- - name: Use cmake
- run: |
- mkdir build &&
- cd build &&
- cmake ${{matrix.cxx}} ${{matrix.arch}} -DFASTFLOAT_TEST=ON
-DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
- cmake --build . &&
- ctest --output-on-failure &&
- cmake --install . &&
- cd ../tests/installation_tests/find &&
- mkdir build && cd build && cmake
-DCMAKE_INSTALL_PREFIX:PATH=../../../build/destination .. && cmake --build . &&
- cd ../../issue72_installation &&
- mkdir build && cd build && cmake
-DCMAKE_INSTALL_PREFIX:PATH=../../../build/destination .. && cmake --build .
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu22-clang.yml
fast-float-8.1.0/.github/workflows/ubuntu22-clang.yml
--- fast-float-8.0.0/.github/workflows/ubuntu22-clang.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu22-clang.yml 2025-09-18
17:38:45.000000000 +0200
@@ -6,7 +6,7 @@
ubuntu-build:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Install clang++-14
run: sudo apt-get install -y clang++-14
- name: Use cmake
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu22-gcc12.yml
fast-float-8.1.0/.github/workflows/ubuntu22-gcc12.yml
--- fast-float-8.0.0/.github/workflows/ubuntu22-gcc12.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu22-gcc12.yml 2025-09-18
17:38:45.000000000 +0200
@@ -6,7 +6,7 @@
ubuntu-build:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Use cmake
run: |
mkdir build &&
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu22-sanitize.yml
fast-float-8.1.0/.github/workflows/ubuntu22-sanitize.yml
--- fast-float-8.0.0/.github/workflows/ubuntu22-sanitize.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu22-sanitize.yml 2025-09-18
17:38:45.000000000 +0200
@@ -6,7 +6,7 @@
ubuntu-build:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Use cmake
run: |
mkdir build &&
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu22.yml
fast-float-8.1.0/.github/workflows/ubuntu22.yml
--- fast-float-8.0.0/.github/workflows/ubuntu22.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu22.yml 2025-09-18
17:38:45.000000000 +0200
@@ -6,7 +6,7 @@
ubuntu-build:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Use cmake
run: |
mkdir build &&
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu24-cxx20.yml
fast-float-8.1.0/.github/workflows/ubuntu24-cxx20.yml
--- fast-float-8.0.0/.github/workflows/ubuntu24-cxx20.yml 1970-01-01
01:00:00.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu24-cxx20.yml 2025-09-18
17:38:45.000000000 +0200
@@ -0,0 +1,19 @@
+name: Ubuntu 24.04 CI
+
+on: [push, pull_request]
+
+jobs:
+ ubuntu-build:
+ runs-on: ubuntu-24.04
+ strategy:
+ fail-fast: false
+ steps:
+ - uses: actions/checkout@v5
+ - name: Use cmake
+ run: |
+ mkdir build &&
+ cd build &&
+ cmake -DFASTFLOAT_CXX_STANDARD=20 -DFASTFLOAT_TEST=ON
-DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
+ cmake --build . &&
+ ctest --output-on-failure &&
+ cmake --install .
diff -Nru fast-float-8.0.0/.github/workflows/ubuntu24.yml
fast-float-8.1.0/.github/workflows/ubuntu24.yml
--- fast-float-8.0.0/.github/workflows/ubuntu24.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/ubuntu24.yml 2025-09-18
17:38:45.000000000 +0200
@@ -6,18 +6,24 @@
ubuntu-build:
runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: Use cmake
run: |
- mkdir build &&
- cd build &&
- CXXFLAGS=-Werror cmake -DFASTFLOAT_TEST=ON -D
FASTFLOAT_BENCHMARKS=ON .. &&
- cmake --build . &&
- ctest --output-on-failure
+ set -xe
+ cmake -B build \
+ -DFASTFLOAT_TEST=ON \
+ -DFASTFLOAT_BENCHMARKS=ON \
+ -DCMAKE_CXX_FLAGS=' -Werror -Wundef '
+ cmake --build build --parallel
+ ( cd build ; ctest --output-on-failure )
- name: Use cmake CXX23
run: |
- mkdir build20 &&
- cd build20 &&
- CXXFLAGS=-Werror cmake -DFASTFLOAT_CONSTEXPR_TESTS=ON
-DFASTFLOAT_FIXEDWIDTH_TESTS=ON -DFASTFLOAT_CXX_STANDARD=23 -DFASTFLOAT_TEST=ON
.. &&
- cmake --build . &&
- ctest --output-on-failure
\ Kein Zeilenumbruch am Dateiende.
+ set -xe
+ cmake -B build20 \
+ -DFASTFLOAT_TEST=ON \
+ -DFASTFLOAT_CONSTEXPR_TESTS=ON \
+ -DFASTFLOAT_FIXEDWIDTH_TESTS=ON \
+ -DFASTFLOAT_CXX_STANDARD=23 \
+ -DCMAKE_CXX_FLAGS=' -Werror -Wundef '
+ cmake --build build20 --parallel
+ ( cd build20 ; ctest --output-on-failure )
diff -Nru fast-float-8.0.0/.github/workflows/vs17-arm-ci.yml
fast-float-8.1.0/.github/workflows/vs17-arm-ci.yml
--- fast-float-8.0.0/.github/workflows/vs17-arm-ci.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/vs17-arm-ci.yml 2025-09-18
17:38:45.000000000 +0200
@@ -14,7 +14,7 @@
- {gen: Visual Studio 17 2022, arch: ARM64, cfg: Debug}
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: configure
run: |
cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}}
-DCMAKE_CROSSCOMPILING=1 -DFASTFLOAT_TEST=ON
diff -Nru fast-float-8.0.0/.github/workflows/vs17-ci.yml
fast-float-8.1.0/.github/workflows/vs17-ci.yml
--- fast-float-8.0.0/.github/workflows/vs17-ci.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/vs17-ci.yml 2025-09-18
17:38:45.000000000 +0200
@@ -16,10 +16,10 @@
- {gen: Visual Studio 17 2022, arch: x64, cfg: Debug}
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: configure
run: |
- cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}}
-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
- name: build
run: |
cmake --build build --verbose --config ${{matrix.cfg}} --parallel
diff -Nru fast-float-8.0.0/.github/workflows/vs17-clang-ci.yml
fast-float-8.1.0/.github/workflows/vs17-clang-ci.yml
--- fast-float-8.0.0/.github/workflows/vs17-clang-ci.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/vs17-clang-ci.yml 2025-09-18
17:38:45.000000000 +0200
@@ -16,10 +16,10 @@
- {gen: Visual Studio 17 2022, arch: x64, cfg: Debug}
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: Configure
run: |
- cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}} -T
ClangCL -DFASTFLOAT_TEST=ON
+ cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}}
-DFASTFLOAT_BENCHMARKS=ON -T ClangCL -DFASTFLOAT_TEST=ON
- name: Build
run: cmake --build build --config ${{matrix.cfg}} --parallel --verbose
- name: Run basic tests
diff -Nru fast-float-8.0.0/.github/workflows/vs17-cxx20.yml
fast-float-8.1.0/.github/workflows/vs17-cxx20.yml
--- fast-float-8.0.0/.github/workflows/vs17-cxx20.yml 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/.github/workflows/vs17-cxx20.yml 2025-09-18
17:38:45.000000000 +0200
@@ -16,7 +16,7 @@
- {gen: Visual Studio 17 2022, arch: x64, cfg: Debug}
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: configure
run: >-
cmake -S . -B build -G "${{matrix.gen}}" -A ${{matrix.arch}}
diff -Nru fast-float-8.0.0/include/fast_float/ascii_number.h
fast-float-8.1.0/include/fast_float/ascii_number.h
--- fast-float-8.0.0/include/fast_float/ascii_number.h 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/include/fast_float/ascii_number.h 2025-09-18
17:38:45.000000000 +0200
@@ -279,7 +279,7 @@
// Assuming that you use no more than 19 digits, this will
// parse an ASCII string.
-template <typename UC>
+template <bool basic_json_fmt, typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
parse_number_string(UC const *p, UC const *pend,
parse_options_t<UC> options) noexcept {
@@ -292,20 +292,20 @@
// assume p < pend, so dereference without checks;
answer.negative = (*p == UC('-'));
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
- if ((*p == UC('-')) ||
- (uint64_t(fmt & chars_format::allow_leading_plus) &&
- !uint64_t(fmt & detail::basic_json_fmt) && *p == UC('+'))) {
+ if ((*p == UC('-')) || (uint64_t(fmt & chars_format::allow_leading_plus) &&
+ !basic_json_fmt && *p == UC('+'))) {
++p;
if (p == pend) {
return report_parse_error<UC>(
p, parse_error::missing_integer_or_dot_after_sign);
}
- if (uint64_t(fmt & detail::basic_json_fmt)) {
+ FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
if (!is_integer(*p)) { // a sign must be followed by an integer
return report_parse_error<UC>(p,
parse_error::missing_integer_after_sign);
}
- } else {
+ }
+ else {
if (!is_integer(*p) &&
(*p !=
decimal_point)) { // a sign must be followed by an integer or the
dot
@@ -329,7 +329,7 @@
UC const *const end_of_integer_part = p;
int64_t digit_count = int64_t(end_of_integer_part - start_digits);
answer.integer = span<UC const>(start_digits, size_t(digit_count));
- if (uint64_t(fmt & detail::basic_json_fmt)) {
+ FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
// at least 1 digit in integer part, without leading zeros
if (digit_count == 0) {
return report_parse_error<UC>(p, parse_error::no_digits_in_integer_part);
@@ -358,14 +358,14 @@
answer.fraction = span<UC const>(before, size_t(p - before));
digit_count -= exponent;
}
- if (uint64_t(fmt & detail::basic_json_fmt)) {
+ FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
// at least 1 digit in fractional part
if (has_decimal_point && exponent == 0) {
return report_parse_error<UC>(p,
parse_error::no_digits_in_fractional_part);
}
- } else if (digit_count ==
- 0) { // we must have encountered at least one integer!
+ }
+ else if (digit_count == 0) { // we must have encountered at least one
integer!
return report_parse_error<UC>(p, parse_error::no_digits_in_mantissa);
}
int64_t exp_number = 0; // explicit exponential part
@@ -441,7 +441,7 @@
if (digit_count > 19) {
answer.too_many_digits = true;
// Let us start again, this time, avoiding overflows.
- // We don't need to check if is_integer, since we use the
+ // We don't need to call if is_integer, since we use the
// pre-tokenized spans from above.
i = 0;
p = answer.integer.ptr;
@@ -451,7 +451,7 @@
i = i * 10 + uint64_t(*p - UC('0'));
++p;
}
- if (i >= minimal_nineteen_digit_integer) { // We have a big integers
+ if (i >= minimal_nineteen_digit_integer) { // We have a big integer
exponent = end_of_integer_part - p + exp_number;
} else { // We have a value with a fractional component.
p = answer.fraction.ptr;
diff -Nru fast-float-8.0.0/include/fast_float/constexpr_feature_detect.h
fast-float-8.1.0/include/fast_float/constexpr_feature_detect.h
--- fast-float-8.0.0/include/fast_float/constexpr_feature_detect.h
2025-02-08 17:49:58.000000000 +0100
+++ fast-float-8.1.0/include/fast_float/constexpr_feature_detect.h
2025-09-18 17:38:45.000000000 +0200
@@ -8,7 +8,7 @@
#endif
// Testing for https://wg21.link/N3652, adopted in C++14
-#if __cpp_constexpr >= 201304
+#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
#define FASTFLOAT_CONSTEXPR14 constexpr
#else
#define FASTFLOAT_CONSTEXPR14
@@ -27,8 +27,15 @@
#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0
#endif
+#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
+#define FASTFLOAT_IF_CONSTEXPR17(x) if constexpr (x)
+#else
+#define FASTFLOAT_IF_CONSTEXPR17(x) if (x)
+#endif
+
// Testing for relevant C++20 constexpr library features
#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST &&
\
+ defined(__cpp_lib_constexpr_algorithms) &&
\
__cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/
#define FASTFLOAT_CONSTEXPR20 constexpr
#define FASTFLOAT_IS_CONSTEXPR 1
diff -Nru fast-float-8.0.0/include/fast_float/fast_float.h
fast-float-8.1.0/include/fast_float/fast_float.h
--- fast-float-8.0.0/include/fast_float/fast_float.h 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/include/fast_float/fast_float.h 2025-09-18
17:38:45.000000000 +0200
@@ -46,6 +46,24 @@
parse_options_t<UC> options) noexcept;
/**
+ * This function multiplies an integer number by a power of 10 and returns
+ * the result as a double precision floating-point value that is correctly
+ * rounded. The resulting floating-point value is the closest floating-point
+ * value, using the "round to nearest, tie to even" convention for values that
+ * would otherwise fall right in-between two values. That is, we provide exact
+ * conversion according to the IEEE standard.
+ *
+ * On overflow infinity is returned, on underflow 0 is returned.
+ *
+ * The implementation does not throw and does not allocate memory (e.g., with
+ * `new` or `malloc`).
+ */
+FASTFLOAT_CONSTEXPR20 inline double
+integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept;
+FASTFLOAT_CONSTEXPR20 inline double
+integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept;
+
+/**
* from_chars for integer types.
*/
template <typename T, typename UC = char,
diff -Nru fast-float-8.0.0/include/fast_float/float_common.h
fast-float-8.1.0/include/fast_float/float_common.h
--- fast-float-8.0.0/include/fast_float/float_common.h 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/include/fast_float/float_common.h 2025-09-18
17:38:45.000000000 +0200
@@ -9,14 +9,14 @@
#include <type_traits>
#include <system_error>
#ifdef __has_include
-#if __has_include(<stdfloat>) && (__cplusplus > 202002L || _MSVC_LANG >
202002L)
+#if __has_include(<stdfloat>) && (__cplusplus > 202002L ||
(defined(_MSVC_LANG) && (_MSVC_LANG > 202002L)))
#include <stdfloat>
#endif
#endif
#include "constexpr_feature_detect.h"
#define FASTFLOAT_VERSION_MAJOR 8
-#define FASTFLOAT_VERSION_MINOR 0
+#define FASTFLOAT_VERSION_MINOR 1
#define FASTFLOAT_VERSION_PATCH 0
#define FASTFLOAT_STRINGIZE_IMPL(x) #x
@@ -58,6 +58,11 @@
template <typename UC> struct from_chars_result_t {
UC const *ptr;
std::errc ec;
+
+ // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2497r0.html
+ constexpr explicit operator bool() const noexcept {
+ return ec == std::errc();
+ }
};
using from_chars_result = from_chars_result_t<char>;
@@ -88,11 +93,12 @@
defined(__MINGW64__) || defined(__s390x__) ||
\
(defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) ||
\
defined(__PPC64LE__)) ||
\
- defined(__loongarch64))
+ defined(__loongarch64) || (defined(__riscv) && __riscv_xlen == 64))
#define FASTFLOAT_64BIT 1
#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) ||
\
defined(__arm__) || defined(_M_ARM) || defined(__ppc__) ||
\
- defined(__MINGW32__) || defined(__EMSCRIPTEN__))
+ defined(__MINGW32__) || defined(__EMSCRIPTEN__) ||
\
+ (defined(__riscv) && __riscv_xlen == 32))
#define FASTFLOAT_32BIT 1
#else
// Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow.
@@ -1126,7 +1132,12 @@
template <typename UC>
fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) {
- return int_luts<>::chdigit[static_cast<unsigned char>(c)];
+ // wchar_t and char can be signed, so we need to be careful.
+ using UnsignedUC = typename std::make_unsigned<UC>::type;
+ return int_luts<>::chdigit[static_cast<unsigned char>(
+ static_cast<UnsignedUC>(c) &
+ static_cast<UnsignedUC>(
+ -((static_cast<UnsignedUC>(c) & ~0xFFull) == 0)))];
}
fastfloat_really_inline constexpr size_t max_digits_u64(int base) {
diff -Nru fast-float-8.0.0/include/fast_float/parse_number.h
fast-float-8.1.0/include/fast_float/parse_number.h
--- fast-float-8.0.0/include/fast_float/parse_number.h 2025-02-08
17:49:58.000000000 +0100
+++ fast-float-8.1.0/include/fast_float/parse_number.h 2025-09-18
17:38:45.000000000 +0200
@@ -188,32 +188,17 @@
parse_options_t<UC>(fmt));
}
-/**
- * This function overload takes parsed_number_string_t structure that is
created
- * and populated either by from_chars_advanced function taking chars range and
- * parsing options or other parsing custom function implemented by user.
- */
-template <typename T, typename UC>
-FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
-from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
-
- static_assert(is_supported_float_type<T>::value,
- "only some floating-point types are supported");
- static_assert(is_supported_char_type<UC>::value,
- "only char, wchar_t, char16_t and char32_t are supported");
-
- from_chars_result_t<UC> answer;
-
- answer.ec = std::errc(); // be optimistic
- answer.ptr = pns.lastmatch;
+template <typename T>
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
+clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative,
+ T &value) noexcept {
// The implementation of the Clinger's fast path is convoluted because
// we want round-to-nearest in all cases, irrespective of the rounding mode
// selected on the thread.
// We proceed optimistically, assuming that detail::rounds_to_nearest()
// returns true.
- if (binary_format<T>::min_exponent_fast_path() <= pns.exponent &&
- pns.exponent <= binary_format<T>::max_exponent_fast_path() &&
- !pns.too_many_digits) {
+ if (binary_format<T>::min_exponent_fast_path() <= exponent &&
+ exponent <= binary_format<T>::max_exponent_fast_path()) {
// Unfortunately, the conventional Clinger's fast path is only possible
// when the system rounds to the nearest float.
//
@@ -224,41 +209,64 @@
if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
// We have that fegetround() == FE_TONEAREST.
// Next is Clinger's fast path.
- if (pns.mantissa <= binary_format<T>::max_mantissa_fast_path()) {
- value = T(pns.mantissa);
- if (pns.exponent < 0) {
- value = value / binary_format<T>::exact_power_of_ten(-pns.exponent);
+ if (mantissa <= binary_format<T>::max_mantissa_fast_path()) {
+ value = T(mantissa);
+ if (exponent < 0) {
+ value = value / binary_format<T>::exact_power_of_ten(-exponent);
} else {
- value = value * binary_format<T>::exact_power_of_ten(pns.exponent);
+ value = value * binary_format<T>::exact_power_of_ten(exponent);
}
- if (pns.negative) {
+ if (is_negative) {
value = -value;
}
- return answer;
+ return true;
}
} else {
// We do not have that fegetround() == FE_TONEAREST.
// Next is a modified Clinger's fast path, inspired by Jakub Jelínek's
// proposal
- if (pns.exponent >= 0 &&
- pns.mantissa <=
- binary_format<T>::max_mantissa_fast_path(pns.exponent)) {
+ if (exponent >= 0 &&
+ mantissa <= binary_format<T>::max_mantissa_fast_path(exponent)) {
#if defined(__clang__) || defined(FASTFLOAT_32BIT)
// Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD
- if (pns.mantissa == 0) {
- value = pns.negative ? T(-0.) : T(0.);
- return answer;
+ if (mantissa == 0) {
+ value = is_negative ? T(-0.) : T(0.);
+ return true;
}
#endif
- value = T(pns.mantissa) *
- binary_format<T>::exact_power_of_ten(pns.exponent);
- if (pns.negative) {
+ value = T(mantissa) * binary_format<T>::exact_power_of_ten(exponent);
+ if (is_negative) {
value = -value;
}
- return answer;
+ return true;
}
}
}
+ return false;
+}
+
+/**
+ * This function overload takes parsed_number_string_t structure that is
created
+ * and populated either by from_chars_advanced function taking chars range and
+ * parsing options or other parsing custom function implemented by user.
+ */
+template <typename T, typename UC>
+FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
+from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
+ static_assert(is_supported_float_type<T>::value,
+ "only some floating-point types are supported");
+ static_assert(is_supported_char_type<UC>::value,
+ "only char, wchar_t, char16_t and char32_t are supported");
+
+ from_chars_result_t<UC> answer;
+
+ answer.ec = std::errc(); // be optimistic
+ answer.ptr = pns.lastmatch;
+
+ if (!pns.too_many_digits &&
+ clinger_fast_path_impl(pns.mantissa, pns.exponent, pns.negative, value))
+ return answer;
+
adjusted_mantissa am =
compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
if (pns.too_many_digits && am.power2 >= 0) {
@@ -305,7 +313,9 @@
return answer;
}
parsed_number_string_t<UC> pns =
- parse_number_string<UC>(first, last, options);
+ uint64_t(fmt & detail::basic_json_fmt)
+ ? parse_number_string<true, UC>(first, last, options)
+ : parse_number_string<false, UC>(first, last, options);
if (!pns.valid) {
if (uint64_t(fmt & chars_format::no_infnan)) {
answer.ec = std::errc::invalid_argument;
@@ -334,6 +344,49 @@
return from_chars_advanced(first, last, value, options);
}
+FASTFLOAT_CONSTEXPR20 inline double
+integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
+ double value;
+ if (clinger_fast_path_impl(mantissa, decimal_exponent, false, value))
+ return value;
+
+ adjusted_mantissa am =
+ compute_float<binary_format<double>>(decimal_exponent, mantissa);
+ to_float(false, am, value);
+ return value;
+}
+
+FASTFLOAT_CONSTEXPR20 inline double
+integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
+ const bool is_negative = mantissa < 0;
+ const uint64_t m = static_cast<uint64_t>(is_negative ? -mantissa : mantissa);
+
+ double value;
+ if (clinger_fast_path_impl(m, decimal_exponent, is_negative, value))
+ return value;
+
+ adjusted_mantissa am =
+ compute_float<binary_format<double>>(decimal_exponent, m);
+ to_float(is_negative, am, value);
+ return value;
+}
+
+// the following overloads are here to avoid surprising ambiguity for int,
+// unsigned, etc.
+template <typename Int>
+FASTFLOAT_CONSTEXPR20 inline typename std::enable_if<
+ std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type
+integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
+ return integer_times_pow10(static_cast<uint64_t>(mantissa),
decimal_exponent);
+}
+
+template <typename Int>
+FASTFLOAT_CONSTEXPR20 inline typename std::enable_if<
+ std::is_integral<Int>::value && std::is_signed<Int>::value, double>::type
+integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
+ return integer_times_pow10(static_cast<int64_t>(mantissa), decimal_exponent);
+}
+
template <typename T, typename UC>
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars_int_advanced(UC const *first, UC const *last, T &value,
diff -Nru fast-float-8.0.0/README.md fast-float-8.1.0/README.md
--- fast-float-8.0.0/README.md 2025-02-08 17:49:58.000000000 +0100
+++ fast-float-8.1.0/README.md 2025-09-18 17:38:45.000000000 +0200
@@ -57,6 +57,7 @@
```C++
#include "fast_float/fast_float.h"
#include <iostream>
+#include <string>
int main() {
std::string input = "3.1416 xyz ";
@@ -68,6 +69,25 @@
}
```
+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:
+
+```cpp
+#include "fast_float/fast_float.h"
+#include <iostream>
+#include <string>
+
+int main() {
+ std::string input = "3.1416 xyz ";
+ double result;
+ if(auto answer = fast_float::from_chars(input.data(), input.data() +
input.size(), result)) {
+ std::cout << "parsed the number " << result << std::endl;
+ return EXIT_SUCCESS;
+ }
+ std::cerr << "failed to parse " << result << std::endl;
+ return EXIT_FAILURE;
+}
+```
+
You can parse delimited numbers:
```C++
@@ -357,6 +377,34 @@
}
```
+## Multiplication of an integer by a power of 10
+An integer `W` can be multiplied by a power of ten `10^Q` and
+converted to `double` with correctly rounded value
+(in "round to nearest, tie to even" fashion) using
+`fast_float::integer_times_pow10()`, e.g.:
+```C++
+const uint64_t W = 12345678901234567;
+const int Q = 23;
+const double result = fast_float::integer_times_pow10(W, Q);
+std::cout.precision(17);
+std::cout << W << " * 10^" << Q << " = " << result << " ("
+ << (result == 12345678901234567e23 ? "==" : "!=") << "expected)\n";
+```
+outputs
+```
+12345678901234567 * 10^23 = 1.2345678901234567e+39 (==expected)
+```
+`fast_float::integer_times_pow10()` gives the same result as
+using `fast_float::from_chars()` when parsing the string `"WeQ"`
+(in this example `"12345678901234567e23"`),
+except `fast_float::integer_times_pow10()` does not report out-of-range
errors, and
+underflows to zero or overflows to infinity when the resulting value is
+out of range.
+
+Overloads of `fast_float::integer_times_pow10()` are provided for
+signed and unsigned integer types: `int64_t`, `uint64_t`, etc.
+
+
## Users and Related Work
The fast_float library is part of:
@@ -364,6 +412,8 @@
* GCC (as of version 12): the `from_chars` function in GCC relies on
fast_float,
* [Chromium](https://github.com/Chromium/Chromium), the engine behind Google
Chrome, Microsoft Edge, and Opera,
+* Boost JSON, MySQL, etc.
+* Blender
* [WebKit](https://github.com/WebKit/WebKit), the engine behind Safari (Apple's
web browser),
* [DuckDB](https://duckdb.org),
@@ -376,7 +426,10 @@
The fastfloat algorithm is part of the [LLVM standard
libraries](https://github.com/llvm/llvm-project/commit/87c016078ad72c46505461e4ff8bfa04819fe7ba).
There is a [derived implementation part of
-AdaCore](https://github.com/AdaCore/VSS).
+AdaCore](https://github.com/AdaCore/VSS). The [SerenityOS operating
+system](https://github.com/SerenityOS/serenity/commit/53b7f5e6a11e663c83df8030c3171c5945cb75ec)
+has a derived implementation that is inherited by the [Ladybird
+Browser](https://github.com/LadybirdBrowser/ladybird).
The fast_float library provides a performance similar to that of the
[fast_double_parser](https://github.com/lemire/fast_double_parser) library but
@@ -385,6 +438,14 @@
fast_double_parser library is part of the [Microsoft LightGBM machine-learning
framework](https://github.com/microsoft/LightGBM).
+
+
+Packages
+------
+
+[](https://repology.org/project/fastfloat/versions)
+
+
## References
* Daniel Lemire, [Number Parsing at a Gigabyte per
@@ -429,7 +490,7 @@
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68
Mfloat/s
```
-See the [Benchmarking](#benchmarking) Section for instructions on how to run
our benchmarks.
+See the [Benchmarking](#benchmarking) section for instructions on how to run
our benchmarks.
## Video
@@ -455,7 +516,7 @@
FetchContent_Declare(
fast_float
GIT_REPOSITORY https://github.com/fastfloat/fast_float.git
- GIT_TAG tags/v8.0.0
+ GIT_TAG tags/v8.1.0
GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(fast_float)
@@ -471,7 +532,7 @@
CPMAddPackage(
NAME fast_float
GITHUB_REPOSITORY "fastfloat/fast_float"
- GIT_TAG v8.0.0)
+ GIT_TAG v8.1.0)
```
## Using as single header
@@ -483,7 +544,7 @@
You may directly download automatically generated single-header files:
-<https://github.com/fastfloat/fast_float/releases/download/v8.0.0/fast_float.h>
+<https://github.com/fastfloat/fast_float/releases/download/v8.1.0/fast_float.h>
## Benchmarking
@@ -508,12 +569,21 @@
sudo ./build/benchmarks/realbenchmark
```
+If you have a text file containing one number per line (`myfile.txt`), you can
run a benchmark over it like so:
+```
+cmake -B build -D FASTFLOAT_BENCHMARKS=ON
+cmake --build build
+./build/benchmarks/realbenchmark myfile.txt
+```
+
+
## Packages
* The fast_float library is part of the [Conan package
manager](https://conan.io/center/recipes/fast_float).
* It is part of the [brew package
manager](https://formulae.brew.sh/formula/fast_float).
+* fast_float is available on [xmake](https://xmake.io) repository.
* Some Linux distribution like Fedora include fast_float (e.g., as
`fast_float-devel`).
diff -Nru fast-float-8.0.0/tests/basictest.cpp
fast-float-8.1.0/tests/basictest.cpp
--- fast-float-8.0.0/tests/basictest.cpp 2025-02-08 17:49:58.000000000
+0100
+++ fast-float-8.1.0/tests/basictest.cpp 2025-09-18 17:38:45.000000000
+0200
@@ -1134,6 +1134,14 @@
std::errc::result_out_of_range);
verify("1.9e308", std::numeric_limits<double>::infinity(),
std::errc::result_out_of_range);
+
+ // DBL_MAX + 0.00000000000000001e308
+ verify("1.79769313486231581e308", std::numeric_limits<double>::infinity(),
+ std::errc::result_out_of_range);
+
+ // DBL_MAX + 0.0000000000000001e308
+ verify("1.7976931348623159e308", std::numeric_limits<double>::infinity(),
+ std::errc::result_out_of_range);
}
TEST_CASE("double.general") {
@@ -1143,6 +1151,13 @@
verify("-22250738585072012e-324",
-0x1p-1022); /* limit between normal and subnormal*/
verify("-1e-999", -0.0, std::errc::result_out_of_range);
+
+ // DBL_TRUE_MIN / 2
+ verify("2.4703282292062327e-324", 0.0, std::errc::result_out_of_range);
+
+ // DBL_TRUE_MIN / 2 + 0.0000000000000001e-324
+ verify("2.4703282292062328e-324", 0x0.0000000000001p-1022);
+
verify("-2.2222222222223e-322", -0x1.68p-1069);
verify("9007199254740993.0", 0x1p+53);
verify("860228122.6654514319E+90", 0x1.92bb20990715fp+328);
@@ -2070,3 +2085,155 @@
//
0.00000000000000000000000000000000000001175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875bf16);
}
#endif
+
+template <typename Int>
+void verify_integer_multiplication_by_power_of_10(Int mantissa,
+ int decimal_exponent,
+ double expected) {
+ const double actual =
+ fast_float::integer_times_pow10(mantissa, decimal_exponent);
+
+ INFO("m * 10^e=" << mantissa << " * 10^" << decimal_exponent
+ << "\n"
+ " expected="
+ << fHexAndDec(expected) << "\n"
+ << " ..actual=" << fHexAndDec(actual) << "\n"
+ << " expected mantissa="
+ << iHexAndDec(get_mantissa(expected)) << "\n"
+ << " ..actual mantissa=" <<
iHexAndDec(get_mantissa(actual))
+ << "\n");
+ CHECK_EQ(actual, expected);
+}
+
+template <typename Int>
+void verify_integer_multiplication_by_power_of_10(Int mantissa,
+ int decimal_exponent) {
+ std::string constructed_string =
+ std::to_string(mantissa) + "e" + std::to_string(decimal_exponent);
+ double expected_result;
+ const auto result = fast_float::from_chars(
+ constructed_string.data(),
+ constructed_string.data() + constructed_string.size(), expected_result);
+ if (result.ec != std::errc())
+ INFO("Failed to parse: " << constructed_string);
+ verify_integer_multiplication_by_power_of_10(mantissa, decimal_exponent,
+ expected_result);
+}
+
+TEST_CASE("integer_times_pow10") {
+ // explicitly verifying API with different types of integers
+ verify_integer_multiplication_by_power_of_10<int8_t>(31, -1, 3.1);
+ verify_integer_multiplication_by_power_of_10<int8_t>(-31, -1, -3.1);
+ verify_integer_multiplication_by_power_of_10<uint8_t>(31, -1, 3.1);
+ verify_integer_multiplication_by_power_of_10<int16_t>(31415, -4, 3.1415);
+ verify_integer_multiplication_by_power_of_10<int16_t>(-31415, -4, -3.1415);
+ verify_integer_multiplication_by_power_of_10<uint16_t>(31415, -4, 3.1415);
+ verify_integer_multiplication_by_power_of_10<int32_t>(314159265, -8,
+ 3.14159265);
+ verify_integer_multiplication_by_power_of_10<int32_t>(-314159265, -8,
+ -3.14159265);
+ verify_integer_multiplication_by_power_of_10<uint32_t>(3141592653, -9,
+ 3.141592653);
+ verify_integer_multiplication_by_power_of_10<int64_t>(
+ 3141592653589793238, -18, 3.141592653589793238);
+ verify_integer_multiplication_by_power_of_10<int64_t>(
+ -3141592653589793238, -18, -3.141592653589793238);
+ verify_integer_multiplication_by_power_of_10<uint64_t>(
+ 3141592653589793238, -18, 3.141592653589793238);
+ verify_integer_multiplication_by_power_of_10<long long>(
+ -3141592653589793238, -18, -3.141592653589793238);
+ verify_integer_multiplication_by_power_of_10<unsigned long long>(
+ 3141592653589793238, -18, 3.141592653589793238);
+
+ for (int mode : {FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO, FE_TONEAREST}) {
+ fesetround(mode);
+ INFO("fesetround(): " << std::string{round_name(mode)});
+
+ struct Guard {
+ ~Guard() { fesetround(FE_TONEAREST); }
+ } guard;
+
+ verify_integer_multiplication_by_power_of_10(0, 0);
+ verify_integer_multiplication_by_power_of_10(1, 0);
+ verify_integer_multiplication_by_power_of_10(0, 1);
+ verify_integer_multiplication_by_power_of_10(1, 1);
+ verify_integer_multiplication_by_power_of_10(-1, 0);
+ verify_integer_multiplication_by_power_of_10(0, -1);
+ verify_integer_multiplication_by_power_of_10(-1, -1);
+ verify_integer_multiplication_by_power_of_10(-1, 1);
+ verify_integer_multiplication_by_power_of_10(1, -1);
+
+ verify_integer_multiplication_by_power_of_10(
+ 49406564584124654, -340, std::numeric_limits<double>::denorm_min());
+ verify_integer_multiplication_by_power_of_10(
+ 22250738585072014, -324, std::numeric_limits<double>::min());
+ verify_integer_multiplication_by_power_of_10(
+ 17976931348623158, 292, std::numeric_limits<double>::max());
+
+ // DBL_TRUE_MIN / 2 underflows to 0
+ verify_integer_multiplication_by_power_of_10(49406564584124654 / 2, -340,
+ 0.);
+
+ // DBL_TRUE_MIN / 2 + 0.0000000000000001e-324 rounds to DBL_TRUE_MIN
+ verify_integer_multiplication_by_power_of_10(
+ 49406564584124654 / 2 + 1, -340,
+ std::numeric_limits<double>::denorm_min());
+
+ // DBL_MAX + 0.0000000000000001e308 overflows to infinity
+ verify_integer_multiplication_by_power_of_10(
+ 17976931348623158 + 1, 292, std::numeric_limits<double>::infinity());
+ // DBL_MAX + 0.00000000000000001e308 overflows to infinity
+ verify_integer_multiplication_by_power_of_10(
+ 179769313486231580 + 1, 291, std::numeric_limits<double>::infinity());
+
+ // loosely verifying correct rounding of 1 to 64 bits
+ // worth of significant digits
+ verify_integer_multiplication_by_power_of_10(1, 42);
+ verify_integer_multiplication_by_power_of_10(1, -42);
+ verify_integer_multiplication_by_power_of_10(12, 42);
+ verify_integer_multiplication_by_power_of_10(12, -42);
+ verify_integer_multiplication_by_power_of_10(123, 42);
+ verify_integer_multiplication_by_power_of_10(123, -42);
+ verify_integer_multiplication_by_power_of_10(1234, 42);
+ verify_integer_multiplication_by_power_of_10(1234, -42);
+ verify_integer_multiplication_by_power_of_10(12345, 42);
+ verify_integer_multiplication_by_power_of_10(12345, -42);
+ verify_integer_multiplication_by_power_of_10(123456, 42);
+ verify_integer_multiplication_by_power_of_10(123456, -42);
+ verify_integer_multiplication_by_power_of_10(1234567, 42);
+ verify_integer_multiplication_by_power_of_10(1234567, -42);
+ verify_integer_multiplication_by_power_of_10(12345678, 42);
+ verify_integer_multiplication_by_power_of_10(12345678, -42);
+ verify_integer_multiplication_by_power_of_10(123456789, 42);
+ verify_integer_multiplication_by_power_of_10(1234567890, 42);
+ verify_integer_multiplication_by_power_of_10(1234567890, -42);
+ verify_integer_multiplication_by_power_of_10(12345678901, 42);
+ verify_integer_multiplication_by_power_of_10(12345678901, -42);
+ verify_integer_multiplication_by_power_of_10(123456789012, 42);
+ verify_integer_multiplication_by_power_of_10(123456789012, -42);
+ verify_integer_multiplication_by_power_of_10(1234567890123, 42);
+ verify_integer_multiplication_by_power_of_10(1234567890123, -42);
+ verify_integer_multiplication_by_power_of_10(12345678901234, 42);
+ verify_integer_multiplication_by_power_of_10(12345678901234, -42);
+ verify_integer_multiplication_by_power_of_10(123456789012345, 42);
+ verify_integer_multiplication_by_power_of_10(123456789012345, -42);
+ verify_integer_multiplication_by_power_of_10(1234567890123456, 42);
+ verify_integer_multiplication_by_power_of_10(1234567890123456, -42);
+ verify_integer_multiplication_by_power_of_10(12345678901234567, 42);
+ verify_integer_multiplication_by_power_of_10(12345678901234567, -42);
+ verify_integer_multiplication_by_power_of_10(123456789012345678, 42);
+ verify_integer_multiplication_by_power_of_10(123456789012345678, -42);
+ verify_integer_multiplication_by_power_of_10(1234567890123456789, 42);
+ verify_integer_multiplication_by_power_of_10(1234567890123456789, -42);
+ verify_integer_multiplication_by_power_of_10(12345678901234567890ull, 42);
+ verify_integer_multiplication_by_power_of_10(12345678901234567890ull, -42);
+ verify_integer_multiplication_by_power_of_10(
+ std::numeric_limits<int64_t>::max(), 42);
+ verify_integer_multiplication_by_power_of_10(
+ std::numeric_limits<int64_t>::max(), -42);
+ verify_integer_multiplication_by_power_of_10(
+ std::numeric_limits<uint64_t>::max(), 42);
+ verify_integer_multiplication_by_power_of_10(
+ std::numeric_limits<uint64_t>::max(), -42);
+ }
+}
\ Kein Zeilenumbruch am Dateiende.
diff -Nru fast-float-8.0.0/tests/CMakeLists.txt
fast-float-8.1.0/tests/CMakeLists.txt
--- fast-float-8.0.0/tests/CMakeLists.txt 2025-02-08 17:49:58.000000000
+0100
+++ fast-float-8.1.0/tests/CMakeLists.txt 2025-09-18 17:38:45.000000000
+0200
@@ -9,8 +9,7 @@
if (NOT SYSTEM_DOCTEST)
FetchContent_Declare(doctest
- GIT_REPOSITORY https://github.com/onqtam/doctest.git
- GIT_TAG v2.4.11)
+ GIT_REPOSITORY https://github.com/lemire/doctest.git)
else ()
find_package(doctest REQUIRED)
endif()
@@ -23,24 +22,15 @@
# FetchContent_MakeAvailable() was only introduced in 3.14
# https://cmake.org/cmake/help/v3.14/release/3.14.html#modules
-# FetchContent_MakeAvailable(doctest)
if (NOT SYSTEM_DOCTEST)
- FetchContent_GetProperties(doctest)
- if(NOT doctest_POPULATED)
- FetchContent_Populate(doctest)
- add_subdirectory(${doctest_SOURCE_DIR} ${doctest_BINARY_DIR})
- endif()
+ FetchContent_MakeAvailable(doctest)
endif()
add_library(supplemental-data INTERFACE)
if (FASTFLOAT_SUPPLEMENTAL_TESTS)
- FetchContent_GetProperties(supplemental_test_files)
- if(NOT supplemental_test_files_POPULATED)
- message(STATUS "Supplemental tests enabled. Retrieving test files.")
- FetchContent_Populate(supplemental_test_files)
- message(STATUS "Supplemental test files retrieved.")
- add_subdirectory(${supplemental_test_files_SOURCE_DIR}
${supplemental_test_files_BINARY_DIR})
- endif()
+ message(STATUS "Supplemental tests enabled. Retrieving test files.")
+ FetchContent_MakeAvailable(supplemental_test_files)
+ message(STATUS "Supplemental test files retrieved.")
target_compile_definitions(supplemental-data INTERFACE
SUPPLEMENTAL_TEST_DATA_DIR="${supplemental_test_files_BINARY_DIR}/data")
endif()
@@ -71,6 +61,7 @@
fast_float_add_cpp_test(supported_chars_test)
fast_float_add_cpp_test(example_test)
fast_float_add_cpp_test(example_comma_test)
+fast_float_add_cpp_test(example_integer_times_pow10)
fast_float_add_cpp_test(basictest)
option(FASTFLOAT_CONSTEXPR_TESTS "Require constexpr tests (build will fail if
the compiler won't support it)" OFF)
if (FASTFLOAT_CONSTEXPR_TESTS)
@@ -82,7 +73,7 @@
if (FASTFLOAT_SUPPLEMENTAL_TESTS)
target_compile_definitions(basictest PRIVATE FASTFLOAT_SUPPLEMENTAL_TESTS)
endif()
-
+fast_float_add_cpp_test(p2497)
fast_float_add_cpp_test(long_test)
fast_float_add_cpp_test(powersoffive_hardround)
fast_float_add_cpp_test(string_test)
diff -Nru fast-float-8.0.0/tests/example_integer_times_pow10.cpp
fast-float-8.1.0/tests/example_integer_times_pow10.cpp
--- fast-float-8.0.0/tests/example_integer_times_pow10.cpp 1970-01-01
01:00:00.000000000 +0100
+++ fast-float-8.1.0/tests/example_integer_times_pow10.cpp 2025-09-18
17:38:45.000000000 +0200
@@ -0,0 +1,12 @@
+#include "fast_float/fast_float.h"
+
+#include <iostream>
+
+int main() {
+ const uint64_t W = 12345678901234567;
+ const int Q = 23;
+ const double result = fast_float::integer_times_pow10(W, Q);
+ std::cout.precision(17);
+ std::cout << W << " * 10^" << Q << " = " << result << " ("
+ << (result == 12345678901234567e23 ? "==" : "!=") << "expected)\n";
+}
diff -Nru fast-float-8.0.0/tests/fast_int.cpp
fast-float-8.1.0/tests/fast_int.cpp
--- fast-float-8.0.0/tests/fast_int.cpp 2025-02-08 17:49:58.000000000 +0100
+++ fast-float-8.1.0/tests/fast_int.cpp 2025-09-18 17:38:45.000000000 +0200
@@ -831,6 +831,275 @@
return EXIT_FAILURE;
}
}
+ // dont parse UTF-16 code units of emojis as int if low byte is ascii digit
+ {
+ const std::u16string emojis[] = {
+ u"ℹ", u"ℹ️", u"☸", u"☸️", u"☹", u"☹️", u"✳", u"✳️",
+ u"✴", u"✴️", u"⤴", u"⤴️", u"⤵", u"⤵️", u"〰", u"〰️",
+ };
+ bool failed = false;
+ auto array_size = sizeof(emojis) / sizeof(emojis[0]);
+ for (size_t i = 0; i < array_size; i++) {
+ auto e = emojis[i];
+ int foo;
+ auto answer = fast_float::from_chars(e.data(), e.data() + e.size(), foo);
+ if (answer.ec == std::errc()) {
+ failed = true;
+ std::cerr << "Incorrectly parsed emoji #" << i << " as integer " << foo
+ << "." << std::endl;
+ }
+ }
+
+ if (failed) {
+ return EXIT_FAILURE;
+ }
+ }
+ // dont parse UTF-32 code points of emojis as int if low byte is ascii digit
+ {
+ const std::u32string emojis[] = {
+ U"ℹ",
+ U"ℹ️",
+ U"☸",
+ U"☸️",
+ U"☹",
+ U"☹️",
+ U"✳",
+ U"✳️",
+ U"✴",
+ U"✴️",
+ U"⤴",
+ U"⤴️",
+ U"⤵",
+ U"⤵️",
+ U"〰",
+ U"〰️",
+ U"🈲",
+ U"🈳",
+ U"🈴",
+ U"🈵",
+ U"🈶",
+ U"🈷",
+ U"🈷️",
+ U"🈸",
+ U"🈹",
+ U"🌰",
+ U"🌱",
+ U"🌲",
+ U"🌳",
+ U"🌴",
+ U"🌵",
+ U"🌶",
+ U"🌶️",
+ U"🌷",
+ U"🌸",
+ U"🌹",
+ U"🐰",
+ U"🐱",
+ U"🐲",
+ U"🐳",
+ U"🐴",
+ U"🐵",
+ U"🐶",
+ U"🐷",
+ U"🐸",
+ U"🐹",
+ U"🔰",
+ U"🔱",
+ U"🔲",
+ U"🔳",
+ U"🔴",
+ U"🔵",
+ U"🔶",
+ U"🔷",
+ U"🔸",
+ U"🔹",
+ U"😰",
+ U"😱",
+ U"😲",
+ U"😳",
+ U"😴",
+ U"😵",
+ U"😵💫",
+ U"😶",
+ U"😶🌫",
+ U"😶🌫️",
+ U"😷",
+ U"😸",
+ U"😹",
+ U"🤰",
+ U"🤰🏻",
+ U"🤰🏼",
+ U"🤰🏽",
+ U"🤰🏾",
+ U"🤰🏿",
+ U"🤱",
+ U"🤱🏻",
+ U"🤱🏼",
+ U"🤱🏽",
+ U"🤱🏾",
+ U"🤱🏿",
+ U"🤲",
+ U"🤲🏻",
+ U"🤲🏼",
+ U"🤲🏽",
+ U"🤲🏾",
+ U"🤲🏿",
+ U"🤳",
+ U"🤳🏻",
+ U"🤳🏼",
+ U"🤳🏽",
+ U"🤳🏾",
+ U"🤳🏿",
+ U"🤴",
+ U"🤴🏻",
+ U"🤴🏼",
+ U"🤴🏽",
+ U"🤴🏾",
+ U"🤴🏿",
+ U"🤵",
+ U"🤵♀",
+ U"🤵♀️",
+ U"🤵♂",
+ U"🤵♂️",
+ U"🤵🏻",
+ U"🤵🏻♀",
+ U"🤵🏻♀️",
+ U"🤵🏻♂",
+ U"🤵🏻♂️",
+ U"🤵🏼",
+ U"🤵🏼♀",
+ U"🤵🏼♀️",
+ U"🤵🏼♂",
+ U"🤵🏼♂️",
+ U"🤵🏽",
+ U"🤵🏽♀",
+ U"🤵🏽♀️",
+ U"🤵🏽♂",
+ U"🤵🏽♂️",
+ U"🤵🏾",
+ U"🤵🏾♀",
+ U"🤵🏾♀️",
+ U"🤵🏾♂",
+ U"🤵🏾♂️",
+ U"🤵🏿",
+ U"🤵🏿♀",
+ U"🤵🏿♀️",
+ U"🤵🏿♂",
+ U"🤵🏿♂️",
+ U"🤶",
+ U"🤶🏻",
+ U"🤶🏼",
+ U"🤶🏽",
+ U"🤶🏾",
+ U"🤶🏿",
+ U"🤷",
+ U"🤷♀",
+ U"🤷♀️",
+ U"🤷♂",
+ U"🤷♂️",
+ U"🤷🏻",
+ U"🤷🏻♀",
+ U"🤷🏻♀️",
+ U"🤷🏻♂",
+ U"🤷🏻♂️",
+ U"🤷🏼",
+ U"🤷🏼♀",
+ U"🤷🏼♀️",
+ U"🤷🏼♂",
+ U"🤷🏼♂️",
+ U"🤷🏽",
+ U"🤷🏽♀",
+ U"🤷🏽♀️",
+ U"🤷🏽♂",
+ U"🤷🏽♂️",
+ U"🤷🏾",
+ U"🤷🏾♀",
+ U"🤷🏾♀️",
+ U"🤷🏾♂",
+ U"🤷🏾♂️",
+ U"🤷🏿",
+ U"🤷🏿♀",
+ U"🤷🏿♀️",
+ U"🤷🏿♂",
+ U"🤷🏿♂️",
+ U"🤸",
+ U"🤸♀",
+ U"🤸♀️",
+ U"🤸♂",
+ U"🤸♂️",
+ U"🤸🏻",
+ U"🤸🏻♀",
+ U"🤸🏻♀️",
+ U"🤸🏻♂",
+ U"🤸🏻♂️",
+ U"🤸🏼",
+ U"🤸🏼♀",
+ U"🤸🏼♀️",
+ U"🤸🏼♂",
+ U"🤸🏼♂️",
+ U"🤸🏽",
+ U"🤸🏽♀",
+ U"🤸🏽♀️",
+ U"🤸🏽♂",
+ U"🤸🏽♂️",
+ U"🤸🏾",
+ U"🤸🏾♀",
+ U"🤸🏾♀️",
+ U"🤸🏾♂",
+ U"🤸🏾♂️",
+ U"🤸🏿",
+ U"🤸🏿♀",
+ U"🤸🏿♀️",
+ U"🤸🏿♂",
+ U"🤸🏿♂️",
+ U"🤹",
+ U"🤹♀",
+ U"🤹♀️",
+ U"🤹♂",
+ U"🤹♂️",
+ U"🤹🏻",
+ U"🤹🏻♀",
+ U"🤹🏻♀️",
+ U"🤹🏻♂",
+ U"🤹🏻♂️",
+ U"🤹🏼",
+ U"🤹🏼♀",
+ U"🤹🏼♀️",
+ U"🤹🏼♂",
+ U"🤹🏼♂️",
+ U"🤹🏽",
+ U"🤹🏽♀",
+ U"🤹🏽♀️",
+ U"🤹🏽♂",
+ U"🤹🏽♂️",
+ U"🤹🏾",
+ U"🤹🏾♀",
+ U"🤹🏾♀️",
+ U"🤹🏾♂",
+ U"🤹🏾♂️",
+ U"🤹🏿",
+ U"🤹🏿♀",
+ U"🤹🏿♀️",
+ U"🤹🏿♂",
+ U"🤹🏿♂️",
+ };
+ bool failed = false;
+ auto array_size = sizeof(emojis) / sizeof(emojis[0]);
+ for (size_t i = 0; i < array_size; i++) {
+ auto e = emojis[i];
+ int foo;
+ auto answer = fast_float::from_chars(e.data(), e.data() + e.size(), foo);
+ if (answer.ec == std::errc()) {
+ failed = true;
+ std::cerr << "Incorrectly parsed emoji #" << i << " as integer " << foo
+ << "." << std::endl;
+ }
+ }
+
+ if (failed) {
+ return EXIT_FAILURE;
+ }
+ }
return EXIT_SUCCESS;
}
@@ -842,4 +1111,4 @@
std::cerr << "The test requires C++17." << std::endl;
return EXIT_SUCCESS;
}
-#endif
\ Kein Zeilenumbruch am Dateiende.
+#endif
diff -Nru fast-float-8.0.0/tests/json_fmt.cpp
fast-float-8.1.0/tests/json_fmt.cpp
--- fast-float-8.0.0/tests/json_fmt.cpp 2025-02-08 17:49:58.000000000 +0100
+++ fast-float-8.1.0/tests/json_fmt.cpp 2025-09-18 17:38:45.000000000 +0200
@@ -131,7 +131,7 @@
for (std::size_t i = 0; i < reject.size(); ++i) {
auto const &f = reject[i].input;
auto const &expected_reason = reject[i].reason;
- auto answer = fast_float::parse_number_string(
+ auto answer = fast_float::parse_number_string<true>(
f.data(), f.data() + f.size(),
fast_float::parse_options(
fast_float::chars_format::json |
diff -Nru fast-float-8.0.0/tests/p2497.cpp fast-float-8.1.0/tests/p2497.cpp
--- fast-float-8.0.0/tests/p2497.cpp 1970-01-01 01:00:00.000000000 +0100
+++ fast-float-8.1.0/tests/p2497.cpp 2025-09-18 17:38:45.000000000 +0200
@@ -0,0 +1,16 @@
+#include "fast_float/fast_float.h"
+
+#include <iostream>
+#include <string>
+
+int main() {
+ std::string input = "3.1416 xyz ";
+ double result;
+ if (auto answer = fast_float::from_chars(
+ input.data(), input.data() + input.size(), result)) {
+ std::cout << "parsed the number " << result << std::endl;
+ return EXIT_SUCCESS;
+ }
+ std::cerr << "failed to parse " << result << std::endl;
+ return EXIT_FAILURE;
+}
\ Kein Zeilenumbruch am Dateiende.