From f7c84156d5db0979963658f8f07cce5679f7264c Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Mon, 11 Jan 2021 09:27:57 -0500 Subject: [PATCH 01/15] Adding further tests. --- tests/basictest.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 2df1b60..100815b 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -238,6 +238,12 @@ uint64_t get_mantissa(double f) { } +std::string append_zeros(std::string str, size_t number_of_zeros) { + std::string answer(str); + for(size_t i = 0; i < number_of_zeros; i++) { answer += "0"; } + return answer; +} + template void basic_test(std::string str, T expected) { T actual; @@ -288,6 +294,13 @@ TEST_CASE("64bit.inf") { } TEST_CASE("64bit.general") { + verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125", 0x1.2ced2f1aa2833p+0); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655), 0x1.2ced2f1aa2833p+0); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656), 0x1.2ced2f1aa2833p+0); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000), 0x1.2ced2f1aa2833p+0); + verify("10000000000000000000", 0x1.158e460913dp+63); + verify("10000000000000000000000000000001000000000000", 0x1.cb2d6f618c879p+142); + verify("10000000000000000000000000000000000000000001", 0x1.cb2d6f618c879p+142); verify("1.1920928955078125e-07", 1.1920928955078125e-07); verify("9355950000000000000.00000000000000000000000000000000001844674407370955161600000184467440737095516161844674407370955161407370955161618446744073709551616000184467440737095516166000001844674407370955161618446744073709551614073709551616184467440737095516160001844674407370955161601844674407370955674451616184467440737095516140737095516161844674407370955161600018446744073709551616018446744073709551611616000184467440737095001844674407370955161600184467440737095516160018446744073709551168164467440737095516160001844073709551616018446744073709551616184467440737095516160001844674407536910751601611616000184467440737095001844674407370955161600184467440737095516160018446744073709551616184467440737095516160001844955161618446744073709551616000184467440753691075160018446744073709",0x1.03ae05e8fca1cp+63); verify("-0",-0.0); @@ -355,6 +368,10 @@ TEST_CASE("32bit.inf") { } TEST_CASE("32bit.general") { + verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125", 0x1.2ced3p+0f); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655), 0x1.2ced3p+0f); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656), 0x1.2ced3p+0f); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000), 0x1.2ced3p+0f); verify32(1.00000006e+09f); verify32(1.4012984643e-45f); verify32(1.1754942107e-38f); From c5adf9e4a59c429e3c02a078d033d5fda4c6a3ba Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Mon, 11 Jan 2021 11:22:00 -0500 Subject: [PATCH 02/15] Fix truncate flag. --- include/fast_float/ascii_number.h | 26 +++++++++++++++++++++----- tests/basictest.cpp | 10 ++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index 75432a3..e8d12ee 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -249,6 +249,27 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n } answer.decimal_point = int32_t(first_after_period - p); } + // We want num_digits to be the number of significant digits, excluding + // leading *and* trailing zeros! Otherwise the truncated flag later is + // going to be misleading. + if(answer.num_digits > 0) { + // We potentially need the answer.num_digits > 0 guard because we + // prune leading zeros. So with answer.num_digits > 0, we know that + // we have at least one non-zero digit. + const char *preverse = p - 1; + int32_t trailing_zeros = 0; + while ((*preverse == '0') || (*preverse == '.')) { + if(*preverse == '0') { trailing_zeros++; }; + --preverse; + } + answer.decimal_point += trailing_zeros; + answer.num_digits -= uint32_t(trailing_zeros); + answer.decimal_point += int32_t(answer.num_digits); + } + if(answer.num_digits > max_digits) { + answer.truncated = true; + answer.num_digits = max_digits; + } if ((p != pend) && (('e' == *p) || ('E' == *p))) { ++p; bool neg_exp = false; @@ -268,11 +289,6 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n } answer.decimal_point += (neg_exp ? -exp_number : exp_number); } - answer.decimal_point += int32_t(answer.num_digits); - if(answer.num_digits > max_digits) { - answer.truncated = true; - answer.num_digits = max_digits; - } // In very rare cases, we may have fewer than 19 digits, we want to be able to reliably // assume that all digits up to max_digit_without_overflow have been initialized. for(uint32_t i = answer.num_digits; i < max_digit_without_overflow; i++) { answer.digits[i] = 0; } diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 100815b..66ba9c6 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -294,10 +294,8 @@ TEST_CASE("64bit.inf") { } TEST_CASE("64bit.general") { - verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125", 0x1.2ced2f1aa2833p+0); - verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655), 0x1.2ced2f1aa2833p+0); - verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656), 0x1.2ced2f1aa2833p+0); - verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000), 0x1.2ced2f1aa2833p+0); + verify("9007199254740993.0", 0x1p+53); + verify(append_zeros("9007199254740993.0",1000), 0x1p+53); verify("10000000000000000000", 0x1.158e460913dp+63); verify("10000000000000000000000000000001000000000000", 0x1.cb2d6f618c879p+142); verify("10000000000000000000000000000000000000000001", 0x1.cb2d6f618c879p+142); @@ -369,9 +367,13 @@ TEST_CASE("32bit.inf") { TEST_CASE("32bit.general") { verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125", 0x1.2ced3p+0f); + verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125e-38", 0x1.fffff8p-127f); verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655), 0x1.2ced3p+0f); verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656), 0x1.2ced3p+0f); verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000), 0x1.2ced3p+0f); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655) + "e-38", 0x1.fffff8p-127f); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656) + "e-38", 0x1.fffff8p-127f); + verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000) + "e-38", 0x1.fffff8p-127f); verify32(1.00000006e+09f); verify32(1.4012984643e-45f); verify32(1.1754942107e-38f); From 716c87067ea7ec49cba164a5458cd51c8fcf9462 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Mon, 11 Jan 2021 11:24:54 -0500 Subject: [PATCH 03/15] Simplifying fix. --- include/fast_float/ascii_number.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index e8d12ee..1e491c7 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -262,9 +262,8 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n if(*preverse == '0') { trailing_zeros++; }; --preverse; } - answer.decimal_point += trailing_zeros; - answer.num_digits -= uint32_t(trailing_zeros); answer.decimal_point += int32_t(answer.num_digits); + answer.num_digits -= uint32_t(trailing_zeros); } if(answer.num_digits > max_digits) { answer.truncated = true; From f6ef9f30748cc163292c966cdcf1ec0ebe87f7e1 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Mon, 11 Jan 2021 11:29:39 -0500 Subject: [PATCH 04/15] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 49bea25..2f7e93a 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,11 @@ The default is `fast_float::chars_format::general` which allows both `fixed` an We support Visual Studio, macOS, Linux, freeBSD. We support big and little endian. We support 32-bit and 64-bit systems. +## Other programming languages + +- [There is a Rust port of the fast_float library](https://github.com/aldanor/fast-float-rust/) called `fast-float-rust`. + + ## Relation With Other Work The fast_float library provides a performance similar to that of the [fast_double_parser](https://github.com/lemire/fast_double_parser) library but using an updated algorithm reworked from the ground up, and while offering an API more in line with the expectations of C++ programmers. The fast_double_parser library is part of the [Microsoft LightGBM machine-learning framework](https://github.com/microsoft/LightGBM). From d59ec8f1f1e21f4dc394c4a2da1015c309b831cc Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Mon, 11 Jan 2021 12:22:43 -0500 Subject: [PATCH 05/15] Adding another test. --- tests/basictest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 66ba9c6..e29ecd4 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -295,6 +295,7 @@ TEST_CASE("64bit.inf") { TEST_CASE("64bit.general") { verify("9007199254740993.0", 0x1p+53); + verify("860228122.6654514319E+90", 0x1.92bb20990715fp+328); verify(append_zeros("9007199254740993.0",1000), 0x1p+53); verify("10000000000000000000", 0x1.158e460913dp+63); verify("10000000000000000000000000000001000000000000", 0x1.cb2d6f618c879p+142); From 541e5feef1ea3c02c0907d3f1ed5258ab13ee72c Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 27 Jan 2021 19:57:00 -0500 Subject: [PATCH 06/15] Adding supplemental tests. --- CMakeLists.txt | 6 ++- tests/CMakeLists.txt | 53 ++++++++++++++++++-------- tests/basictest.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 69c863d..99486dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.9) project(fast_float VERSION 0.7.0 LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED OFF) @@ -31,4 +31,6 @@ endif() if(FASTFLOAT_TEST) enable_testing() add_subdirectory(tests) +else(FASTFLOAT_TEST) + message(STATUS "Tests are disabled. Set FASTFLOAT_TEST to ON to run tests.") endif(FASTFLOAT_TEST) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index edba1f9..37a659e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,6 +7,11 @@ include(FetchContent) FetchContent_Declare(doctest GIT_REPOSITORY https://github.com/onqtam/doctest.git GIT_TAG 2.4.1) +FetchContent_Declare(supplemental_test_files + GIT_REPOSITORY https://github.com/fastfloat/supplemental_test_files.git + GIT_TAG origin/main) + + # FetchContent_MakeAvailable() was only introduced in 3.14 # https://cmake.org/cmake/help/v3.14/release/3.14.html#modules @@ -16,8 +21,15 @@ if(NOT doctest_POPULATED) FetchContent_Populate(doctest) add_subdirectory(${doctest_SOURCE_DIR} ${doctest_BINARY_DIR}) endif() - - +FetchContent_GetProperties(supplemental_test_files) +if(NOT supplemental_test_files_POPULATED) + message(STATUS "Tests enabled. Retrieving test files.") + FetchContent_Populate(supplemental_test_files) + message(STATUS "Test files retrieved.") + add_subdirectory(${supplemental_test_files_SOURCE_DIR} ${supplemental_test_files_BINARY_DIR}) +endif() +add_library(supplemental-data INTERFACE) +target_compile_definitions(supplemental-data INTERFACE SUPPLEMENTAL_TEST_DATA_DIR="${supplemental_test_files_BINARY_DIR}/data") function(fast_float_add_cpp_test TEST_NAME) add_executable(${TEST_NAME} ${TEST_NAME}.cpp) add_test(${TEST_NAME} ${TEST_NAME}) @@ -25,18 +37,29 @@ function(fast_float_add_cpp_test TEST_NAME) target_compile_options(${TEST_NAME} PUBLIC -Werror -Wall -Wextra -Weffc++) target_compile_options(${TEST_NAME} PUBLIC -Wsign-compare -Wshadow -Wwrite-strings -Wpointer-arith -Winit-self -Wconversion -Wsign-conversion) endif() - target_link_libraries(${TEST_NAME} PUBLIC fast_float doctest) + target_link_libraries(${TEST_NAME} PUBLIC fast_float doctest supplemental-data) + target_compile_features(${TEST_NAME} PUBLIC cxx_std_11) endfunction(fast_float_add_cpp_test) -fast_float_add_cpp_test(powersoffive_hardround) -fast_float_add_cpp_test(short_random_string) -fast_float_add_cpp_test(exhaustive32_midpoint) -fast_float_add_cpp_test(random_string) -fast_float_add_cpp_test(string_test) -fast_float_add_cpp_test(exhaustive32) -fast_float_add_cpp_test(exhaustive32_64) -fast_float_add_cpp_test(long_exhaustive32) -fast_float_add_cpp_test(long_exhaustive32_64) -fast_float_add_cpp_test(long_random64) -fast_float_add_cpp_test(random64) -fast_float_add_cpp_test(basictest) + + fast_float_add_cpp_test(example_test) +fast_float_add_cpp_test(basictest) + + + +option(FASTFLOAT_EXHAUSTIVE "Exhaustive tests" OFF) + +if (FASTFLOAT_EXHAUSTIVE) + fast_float_add_cpp_test(powersoffive_hardround) + fast_float_add_cpp_test(short_random_string) + fast_float_add_cpp_test(exhaustive32_midpoint) + fast_float_add_cpp_test(random_string) + fast_float_add_cpp_test(string_test) + fast_float_add_cpp_test(exhaustive32) + fast_float_add_cpp_test(exhaustive32_64) + fast_float_add_cpp_test(long_exhaustive32) + fast_float_add_cpp_test(long_exhaustive32_64) + fast_float_add_cpp_test(long_random64) + fast_float_add_cpp_test(random64) +endif(FASTFLOAT_EXHAUSTIVE) + diff --git a/tests/basictest.cpp b/tests/basictest.cpp index e29ecd4..59211e6 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -4,6 +4,96 @@ #include "fast_float/fast_float.h" #include +#include + +#ifndef SUPPLEMENTAL_TEST_DATA_DIR +#define SUPPLEMENTAL_TEST_DATA_DIR "data/" +#endif + +#ifndef __cplusplus +#error fastfloat requires a C++ compiler +#endif + +#ifndef FASTFLOAT_CPLUSPLUS +#if defined(_MSVC_LANG) && !defined(__clang__) +#define FASTFLOAT_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG) +#else +#define FASTFLOAT_CPLUSPLUS __cplusplus +#endif +#endif + +// C++ 17 because it is otherwise annoying to browse all files in a directory. +// We also only run these tests on little endian systems. +#if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) +#include +#include +#include + + +// return true on succcess +bool check_file(std::string file_name) { + std::cout << "Checking " << file_name << std::endl; + size_t number{0}; + std::fstream newfile(file_name, std::ios::in); + if (newfile.is_open()) { + std::string str; + while (std::getline(newfile, str)) { + if (str.size() > 0) { + // Read 32-bit hex + uint32_t float32; + auto r32 = std::from_chars(str.data() + 5, str.data() + str.size(), + float32, 16); + if(r32.ec != std::errc()) { std::cerr << "32-bit parsing failure\n"; return false; } + // Read 64-bit hex + uint64_t float64; + auto r64 = std::from_chars(str.data() + 14, str.data() + str.size(), + float64, 16); + if(r64.ec != std::errc()) { std::cerr << "64-bit parsing failure\n"; return false; } + // The string to parse: + const char *number_string = str.data() + 31; + const char *end_of_string = str.data() + str.size(); + // Parse as 32-bit float + float parsed_32; + auto fast_float_r32 = fast_float::from_chars(number_string, end_of_string, parsed_32); + if(fast_float_r32.ec != std::errc()) { std::cerr << "parsing failure\n"; return false; } + // Parse as 64-bit float + double parsed_64; + auto fast_float_r64 = fast_float::from_chars(number_string, end_of_string, parsed_64); + if(fast_float_r64.ec != std::errc()) { std::cerr << "parsing failure\n"; return false; } + // Convert the floats to unsigned ints. + uint32_t float32_parsed; + uint64_t float64_parsed; + ::memcpy(&float32_parsed, &parsed_32, sizeof(parsed_32)); + ::memcpy(&float64_parsed, &parsed_64, sizeof(parsed_64)); + // Compare with expected results + if (float32_parsed != float32) { + std::cout << "bad 32 " << str << std::endl; + return false; + } + if (float64_parsed != float64) { + std::cout << "bad 64 " << str << std::endl; + return false; + } + number++; + } + } + std::cout << "checked " << std::defaultfloat << number << " values" << std::endl; + newfile.close(); // close the file object + } else { + std::cout << "Could not read " << file_name << std::endl; + return false; + } + return true; +} + +TEST_CASE("supplemental") { + std::string path = SUPPLEMENTAL_TEST_DATA_DIR; + for (const auto & entry : std::filesystem::directory_iterator(path)) { + CHECK(check_file(entry.path())); + } +} + +#endif TEST_CASE("leading_zeroes") { From cb26cedb1c9e195dce7291da32332a995312a560 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 27 Jan 2021 20:01:45 -0500 Subject: [PATCH 07/15] Explicit conversion to string. --- tests/basictest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 59211e6..17e1f8e 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -89,7 +89,7 @@ bool check_file(std::string file_name) { TEST_CASE("supplemental") { std::string path = SUPPLEMENTAL_TEST_DATA_DIR; for (const auto & entry : std::filesystem::directory_iterator(path)) { - CHECK(check_file(entry.path())); + CHECK(check_file(entry.path().string())); } } From 10a58cd69f48f65878727e24ccee25971deafaa8 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 27 Jan 2021 20:11:55 -0500 Subject: [PATCH 08/15] Running new tests only on sane platforms. --- tests/basictest.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 17e1f8e..7abcc9e 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -22,14 +22,17 @@ #endif #endif + +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) +#define FASTFLOAT_ODDPLATFORM 1 +#endif // C++ 17 because it is otherwise annoying to browse all files in a directory. // We also only run these tests on little endian systems. -#if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) +#if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) && !defined(FASTFLOAT_ODDPLATFORM) #include #include #include - // return true on succcess bool check_file(std::string file_name) { std::cout << "Checking " << file_name << std::endl; From ab40533b27502c39e307bcb63c88d4907d7f1ff5 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 27 Jan 2021 20:20:23 -0500 Subject: [PATCH 09/15] Tweaking. --- .github/workflows/mingw-ci.yml | 2 +- .github/workflows/mingw64-ci.yml | 2 +- .github/workflows/ubuntu18.yml | 16 ++++++++-------- .github/workflows/ubuntu20.yml | 14 +++++++------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/mingw-ci.yml b/.github/workflows/mingw-ci.yml index f886c93..8067363 100644 --- a/.github/workflows/mingw-ci.yml +++ b/.github/workflows/mingw-ci.yml @@ -46,4 +46,4 @@ jobs: cd build32 cmake -DFASTFLOAT_TEST=ON .. cmake --build . --verbose - ctest -j4 --output-on-failure -R basictest \ No newline at end of file + ctest --output-on-failure -R basictest \ No newline at end of file diff --git a/.github/workflows/mingw64-ci.yml b/.github/workflows/mingw64-ci.yml index f476f2b..e8cbb0d 100644 --- a/.github/workflows/mingw64-ci.yml +++ b/.github/workflows/mingw64-ci.yml @@ -46,4 +46,4 @@ jobs: cd build64 cmake -DFASTFLOAT_TEST=ON .. cmake --build . --verbose - ctest -j4 --output-on-failure -R basictest \ No newline at end of file + ctest --verbose --output-on-failure -R basictest \ No newline at end of file diff --git a/.github/workflows/ubuntu18.yml b/.github/workflows/ubuntu18.yml index a029f30..13b7eee 100644 --- a/.github/workflows/ubuntu18.yml +++ b/.github/workflows/ubuntu18.yml @@ -9,21 +9,21 @@ jobs: fail-fast: false matrix: include: - - {cxx: -DCMAKE_CXX_COMPILER=g++-5, arch: } - - {cxx: -DCMAKE_CXX_COMPILER=g++-6, arch: } + #- {cxx: -DCMAKE_CXX_COMPILER=g++-5, arch: } + #- {cxx: -DCMAKE_CXX_COMPILER=g++-6, arch: } - {cxx: , arch: } # default=gcc7 - - {cxx: , arch: -DCMAKE_CXX_FLAGS="-m32"} # default=gcc7 + #- {cxx: , arch: -DCMAKE_CXX_FLAGS="-m32"} # default=gcc7 steps: - uses: actions/checkout@v2 - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.4 with: cmake-version: '3.11.x' - - name: Install older compilers - run: | - sudo -E dpkg --add-architecture i386 - sudo -E apt-get update - sudo -E apt-get install -y --force-yes g++-5 g++-6 g++-5-multilib g++-6-multilib g++-multilib linux-libc-dev:i386 libc6:i386 libc6-dev:i386 libc6-dbg:i386 + #- name: Install older compilers + # run: | + # sudo -E dpkg --add-architecture i386 + # sudo -E apt-get update + # sudo -E apt-get install -y --force-yes g++-5 g++-6 g++-5-multilib g++-6-multilib g++-multilib linux-libc-dev:i386 libc6:i386 libc6-dev:i386 libc6-dbg:i386 - name: Prepare build dir run: mkdir build - name: Configure diff --git a/.github/workflows/ubuntu20.yml b/.github/workflows/ubuntu20.yml index f026366..a0f519f 100644 --- a/.github/workflows/ubuntu20.yml +++ b/.github/workflows/ubuntu20.yml @@ -9,20 +9,20 @@ jobs: fail-fast: false matrix: include: - - {cxx: -DCMAKE_CXX_COMPILER=g++-8, arch: } + #- {cxx: -DCMAKE_CXX_COMPILER=g++-8, arch: } - {cxx: , arch: } # default=gcc9 - - {cxx: , arch: -DCMAKE_CXX_FLAGS="-m32"} # default=gcc9 + #- {cxx: , arch: -DCMAKE_CXX_FLAGS="-m32"} # default=gcc9 steps: - uses: actions/checkout@v2 - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.4 with: cmake-version: '3.11.x' - - name: install older compilers - run: | - sudo -E dpkg --add-architecture i386 - sudo -E apt-get update - sudo -E apt-get install -y g++-8 g++-8-multilib g++-multilib linux-libc-dev:i386 libc6:i386 libc6-dev:i386 libc6-dbg:i386 + #- name: install older compilers + # run: | + # sudo -E dpkg --add-architecture i386 + # sudo -E apt-get update + # sudo -E apt-get install -y g++-8 g++-8-multilib g++-multilib linux-libc-dev:i386 libc6:i386 libc6-dev:i386 libc6-dbg:i386 - name: Prepare build dir run: mkdir build - name: Configure From 00591a8652cbde31081b033b05834bb71f0ebb97 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 27 Jan 2021 20:24:56 -0500 Subject: [PATCH 10/15] Sane systems should have filesystem --- tests/basictest.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 7abcc9e..925b00c 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -26,6 +26,16 @@ #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) #define FASTFLOAT_ODDPLATFORM 1 #endif + +#if defined __has_include +#if __has_include () +#else +#define FASTFLOAT_ODDPLATFORM 1 +#endif +#else +#define FASTFLOAT_ODDPLATFORM 1 +#endif + // C++ 17 because it is otherwise annoying to browse all files in a directory. // We also only run these tests on little endian systems. #if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) && !defined(FASTFLOAT_ODDPLATFORM) From 36afa46f1edc09ce18286f74140072f834346d99 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 27 Jan 2021 21:01:47 -0500 Subject: [PATCH 11/15] Trying again. --- .github/workflows/ubuntu18.yml | 1 + .github/workflows/ubuntu20.yml | 1 + CMakeLists.txt | 20 +++++++++++--------- tests/CMakeLists.txt | 1 - tests/basictest.cpp | 5 +++-- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ubuntu18.yml b/.github/workflows/ubuntu18.yml index 13b7eee..dbdaa7a 100644 --- a/.github/workflows/ubuntu18.yml +++ b/.github/workflows/ubuntu18.yml @@ -9,6 +9,7 @@ jobs: fail-fast: false matrix: include: + # Legacy/x86 compilers cause CI failures. #- {cxx: -DCMAKE_CXX_COMPILER=g++-5, arch: } #- {cxx: -DCMAKE_CXX_COMPILER=g++-6, arch: } - {cxx: , arch: } # default=gcc7 diff --git a/.github/workflows/ubuntu20.yml b/.github/workflows/ubuntu20.yml index a0f519f..8fca2d9 100644 --- a/.github/workflows/ubuntu20.yml +++ b/.github/workflows/ubuntu20.yml @@ -9,6 +9,7 @@ jobs: fail-fast: false matrix: include: + # Legacy/x86 compilers cause CI failures. #- {cxx: -DCMAKE_CXX_COMPILER=g++-8, arch: } - {cxx: , arch: } # default=gcc9 #- {cxx: , arch: -DCMAKE_CXX_FLAGS="-m32"} # default=gcc9 diff --git a/CMakeLists.txt b/CMakeLists.txt index 99486dd..d53c92f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,17 @@ cmake_minimum_required(VERSION 3.9) project(fast_float VERSION 0.7.0 LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED OFF) - +if(FASTFLOAT_TEST) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED OFF) + enable_testing() + add_subdirectory(tests) +else(FASTFLOAT_TEST) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + message(STATUS "Tests are disabled. Set FASTFLOAT_TEST to ON to run tests.") +endif(FASTFLOAT_TEST) option(FASTFLOAT_SANITIZE "Sanitize addresses" OFF) @@ -28,9 +35,4 @@ if(FASTFLOAT_SANITIZE) endif() endif() -if(FASTFLOAT_TEST) - enable_testing() - add_subdirectory(tests) -else(FASTFLOAT_TEST) - message(STATUS "Tests are disabled. Set FASTFLOAT_TEST to ON to run tests.") -endif(FASTFLOAT_TEST) + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 37a659e..713c663 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -38,7 +38,6 @@ function(fast_float_add_cpp_test TEST_NAME) target_compile_options(${TEST_NAME} PUBLIC -Wsign-compare -Wshadow -Wwrite-strings -Wpointer-arith -Winit-self -Wconversion -Wsign-conversion) endif() target_link_libraries(${TEST_NAME} PUBLIC fast_float doctest supplemental-data) - target_compile_features(${TEST_NAME} PUBLIC cxx_std_11) endfunction(fast_float_add_cpp_test) diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 925b00c..73651bf 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -26,19 +26,21 @@ #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) #define FASTFLOAT_ODDPLATFORM 1 #endif - #if defined __has_include #if __has_include () #else +// filesystem is not available #define FASTFLOAT_ODDPLATFORM 1 #endif #else +// __has_include is not available #define FASTFLOAT_ODDPLATFORM 1 #endif // C++ 17 because it is otherwise annoying to browse all files in a directory. // We also only run these tests on little endian systems. #if (FASTFLOAT_CPLUSPLUS >= 201703L) && (FASTFLOAT_IS_BIG_ENDIAN == 0) && !defined(FASTFLOAT_ODDPLATFORM) + #include #include #include @@ -105,7 +107,6 @@ TEST_CASE("supplemental") { CHECK(check_file(entry.path().string())); } } - #endif From 63118e321dd2f5061171990600cabaee1f08232c Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 27 Jan 2021 21:22:08 -0500 Subject: [PATCH 12/15] Removing legacy. --- .github/workflows/mingw-ci.yml | 49 -------------------------------- .github/workflows/mingw64-ci.yml | 49 -------------------------------- 2 files changed, 98 deletions(-) delete mode 100644 .github/workflows/mingw-ci.yml delete mode 100644 .github/workflows/mingw64-ci.yml diff --git a/.github/workflows/mingw-ci.yml b/.github/workflows/mingw-ci.yml deleted file mode 100644 index 8067363..0000000 --- a/.github/workflows/mingw-ci.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: MinGW32-CI - -on: [push, pull_request] - -# Important: scoop will either install 32-bit GCC or 64-bit GCC, not both. - -# It is important to build static libraries because cmake is not smart enough under Windows/mingw to take care of the path. So -# with a dynamic library, you could get failures due to the fact that the EXE can't find its DLL. - -jobs: - ci: - name: windows-gcc - runs-on: windows-2016 - - env: - CMAKE_GENERATOR: Ninja - CC: gcc - CXX: g++ - - steps: # To reproduce what is below, start a powershell with administrative rights, using scoop *is* a good idea - - uses: actions/checkout@v2 - - - uses: actions/cache@v2 # we cache the scoop setup with 32-bit GCC - id: cache - with: - path: | - C:\ProgramData\scoop - key: scoop32 # static key: should be good forever - - name: Setup Windows # This should almost never run if the cache works. - if: steps.cache.outputs.cache-hit != 'true' - shell: powershell - run: | - Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') - scoop install sudo --global - sudo scoop install git --global - sudo scoop install ninja --global - sudo scoop install cmake --global - sudo scoop install gcc --arch 32bit --global - $env:path - Write-Host 'Everything has been installed, you are good!' - - name: Build and Test 32-bit x86 - shell: powershell - run: | - $ENV:PATH="C:\ProgramData\scoop\shims;C:\ProgramData\scoop\apps\gcc\current\bin;C:\ProgramData\scoop\apps\ninja\current;$ENV:PATH" - mkdir build32 - cd build32 - cmake -DFASTFLOAT_TEST=ON .. - cmake --build . --verbose - ctest --output-on-failure -R basictest \ No newline at end of file diff --git a/.github/workflows/mingw64-ci.yml b/.github/workflows/mingw64-ci.yml deleted file mode 100644 index e8cbb0d..0000000 --- a/.github/workflows/mingw64-ci.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: MinGW64-CI - -on: [push, pull_request] - -# Important: scoop will either install 32-bit GCC or 64-bit GCC, not both. - -# It is important to build static libraries because cmake is not smart enough under Windows/mingw to take care of the path. So -# with a dynamic library, you could get failures due to the fact that the EXE can't find its DLL. - -jobs: - ci: - name: windows-gcc - runs-on: windows-2016 - - env: - CMAKE_GENERATOR: Ninja - CC: gcc - CXX: g++ - - steps: # To reproduce what is below, start a powershell with administrative rights, using scoop *is* a good idea - - uses: actions/checkout@v2 - - - uses: actions/cache@v2 # we cache the scoop setup with 64-bit GCC - id: cache - with: - path: | - C:\ProgramData\scoop - key: scoop64 # static key: should be good forever - - name: Setup Windows # This should almost never run if the cache works. - if: steps.cache.outputs.cache-hit != 'true' - shell: powershell - run: | - Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') - scoop install sudo --global - sudo scoop install git --global - sudo scoop install ninja --global - sudo scoop install cmake --global - sudo scoop install gcc --arch 64bit --global - $env:path - Write-Host 'Everything has been installed, you are good!' - - name: Build and Test 64-bit x64 - shell: powershell - run: | - $ENV:PATH="C:\ProgramData\scoop\shims;C:\ProgramData\scoop\apps\gcc\current\bin;C:\ProgramData\scoop\apps\ninja\current;$ENV:PATH" - mkdir build64 - cd build64 - cmake -DFASTFLOAT_TEST=ON .. - cmake --build . --verbose - ctest --verbose --output-on-failure -R basictest \ No newline at end of file From c9437a2694f5ee676224ea773d61382f409c2fb2 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Wed, 27 Jan 2021 21:33:11 -0500 Subject: [PATCH 13/15] Declaring FASTFLOAT_TEST options. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d53c92f..75aebc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.9) project(fast_float VERSION 0.7.0 LANGUAGES CXX) - +option(FASTFLOAT_TEST "Enable tests" OFF) if(FASTFLOAT_TEST) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED OFF) From 7506850088857743e635d81681362367c7c8f7dd Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Fri, 29 Jan 2021 12:30:48 -0500 Subject: [PATCH 14/15] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 2f7e93a..7aa3e3d 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,11 @@ The default is `fast_float::chars_format::general` which allows both `fixed` an We support Visual Studio, macOS, Linux, freeBSD. We support big and little endian. We support 32-bit and 64-bit systems. +## Reference + +- Daniel Lemire, [Number Parsing at a Gigabyte per Second](https://arxiv.org/abs/2101.11408), arXiv:2101.11408 + + ## Other programming languages - [There is a Rust port of the fast_float library](https://github.com/aldanor/fast-float-rust/) called `fast-float-rust`. From 6c27435fbc4644757ab1a3b00df9ecb3a106c358 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Mon, 1 Feb 2021 14:47:44 -0500 Subject: [PATCH 15/15] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7aa3e3d..2e46294 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ We support Visual Studio, macOS, Linux, freeBSD. We support big and little endia ## Other programming languages +- [There is an R binding](https://github.com/eddelbuettel/rcppfastfloat) called `rcppfastfloat`. - [There is a Rust port of the fast_float library](https://github.com/aldanor/fast-float-rust/) called `fast-float-rust`.