diff --git a/.github/workflows/amalgamate-ubuntu20.yml b/.github/workflows/amalgamate-ubuntu24.yml similarity index 85% rename from .github/workflows/amalgamate-ubuntu20.yml rename to .github/workflows/amalgamate-ubuntu24.yml index 9012e18..ca57ff6 100644 --- a/.github/workflows/amalgamate-ubuntu20.yml +++ b/.github/workflows/amalgamate-ubuntu24.yml @@ -1,10 +1,10 @@ -name: Amalgamate Ubuntu 20.04 CI (GCC 9) +name: Amalgamate Ubuntu 24.04 CI on: [push, pull_request] jobs: ubuntu-build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v5 - name: Compile with amalgamation diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml new file mode 100644 index 0000000..1b00f44 --- /dev/null +++ b/.github/workflows/emscripten.yml @@ -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 --git a/.github/workflows/risc.yml b/.github/workflows/risc.yml new file mode 100644 index 0000000..68e26cb --- /dev/null +++ b/.github/workflows/risc.yml @@ -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 --git a/.github/workflows/ubuntu20-fastmath.yml b/.github/workflows/ubuntu20-fastmath.yml deleted file mode 100644 index 5427f83..0000000 --- a/.github/workflows/ubuntu20-fastmath.yml +++ /dev/null @@ -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@v5 - - name: Use cmake - run: | - mkdir build && - cd build && - cmake -DCMAKE_CXX_FLAGS="-ffast-math" -DFASTFLOAT_TEST=ON .. && - cmake --build . && - ctest --output-on-failure diff --git a/.github/workflows/ubuntu20.yml b/.github/workflows/ubuntu20.yml deleted file mode 100644 index c3627d5..0000000 --- a/.github/workflows/ubuntu20.yml +++ /dev/null @@ -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@v5 - - 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 --git a/.github/workflows/ubuntu20-cxx20.yml b/.github/workflows/ubuntu24-cxx20.yml similarity index 88% rename from .github/workflows/ubuntu20-cxx20.yml rename to .github/workflows/ubuntu24-cxx20.yml index 953eec9..8516760 100644 --- a/.github/workflows/ubuntu20-cxx20.yml +++ b/.github/workflows/ubuntu24-cxx20.yml @@ -1,10 +1,10 @@ -name: Ubuntu 20.04 CI (C++20) +name: Ubuntu 24.04 CI on: [push, pull_request] jobs: ubuntu-build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false steps: diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a1c9a3..a86dfc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.14) + project(fast_float VERSION 8.0.2 LANGUAGES CXX) set(FASTFLOAT_CXX_STANDARD 11 CACHE STRING "the C++ standard to use for fastfloat") diff --git a/README.md b/README.md index b2e1a73..fb56985 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Example: ```C++ #include "fast_float/fast_float.h" #include +#include int main() { std::string input = "3.1416 xyz "; @@ -68,6 +69,25 @@ 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: + +```cpp +#include "fast_float/fast_float.h" +#include +#include + +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++ diff --git a/cmake/toolchains-ci/riscv64-linux-gnu.cmake b/cmake/toolchains-ci/riscv64-linux-gnu.cmake new file mode 100644 index 0000000..ed58a2d --- /dev/null +++ b/cmake/toolchains-ci/riscv64-linux-gnu.cmake @@ -0,0 +1,4 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR riscv64) + +set(CMAKE_CROSSCOMPILING_EMULATOR "qemu-riscv64-static") diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index e7e9e70..2e5a79e 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -487,7 +487,7 @@ parse_number_string(UC const *p, UC const *pend, 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. answer.mantissa = 0; p = answer.integer.ptr; diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index eae56f9..66b66ac 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -70,6 +70,11 @@ enum class chars_format : chars_format_t { template 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; @@ -102,11 +107,12 @@ using parse_options = parse_options_t; 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. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c4e43b2..36925f0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,8 +9,7 @@ option(FASTFLOAT_SUPPLEMENTAL_TESTS "Run supplemental tests" ON) 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 @@ endif() # 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() @@ -82,7 +72,7 @@ endif() 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 --git a/tests/p2497.cpp b/tests/p2497.cpp new file mode 100644 index 0000000..fec5133 --- /dev/null +++ b/tests/p2497.cpp @@ -0,0 +1,16 @@ +#include "fast_float/fast_float.h" + +#include +#include + +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; +} \ No newline at end of file