diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2024-09-21 19:44:14 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2024-09-21 19:53:21 +0300 |
commit | 0ab563a49d7c2ec6b6de6503db4acef97cd7f450 (patch) | |
tree | 6958499f670f726556d350dc174581f5fd2368ec /contrib/restricted | |
parent | 960109135f799dd493e08bef5574187434b993b5 (diff) | |
download | ydb-0ab563a49d7c2ec6b6de6503db4acef97cd7f450.tar.gz |
Update contrib/restricted/fast_float to 6.1.5
commit_hash:97b92af9bc7e72bb1debc2ea05dec7e918830462
Diffstat (limited to 'contrib/restricted')
6 files changed, 97 insertions, 4 deletions
diff --git a/contrib/restricted/fast_float/README.md b/contrib/restricted/fast_float/README.md index 9c2e188fa9..316f813e3a 100644 --- a/contrib/restricted/fast_float/README.md +++ b/contrib/restricted/fast_float/README.md @@ -144,6 +144,51 @@ print the number 22250738585072012 three times: std::cout << "parsed the number "<< i << std::endl; ``` +## Behavior of result_out_of_range + +When parsing floating-point values, the numbers can sometimes be too small (e.g., `1e-1000`) or +too large (e.g., `1e1000`). The C language established the precedent that these small values are out of range. +In such cases, it is customary to parse small values to zero and large +values to infinity. That is the behaviour of the C language (e.g., `stdtod`). That is the behaviour followed by the fast_float library. + + + +Specifically, we follow Jonathan Wakely's interpretation of the standard: + +> In any case, the resulting value is one of at most two floating-point values closest to the value of the string matching the pattern. + +It is also the approach taken by the [Microsoft C++ library](https://github.com/microsoft/STL/blob/62205ab155d093e71dd9588a78f02c5396c3c14b/tests/std/tests/P0067R5_charconv/test.cpp#L943-L946). + +Hence, we have the following examples: + +```cpp + double result = -1; + std::string str = "3e-1000"; + auto r = fast_float::from_chars(str.data(), str.data() + str.size(), result); + // r.ec == std::errc::result_out_of_range + // r.ptr == str.data() + 7 + // result == 0 +``` + + +```cpp + double result = -1; + std::string str = "3e1000"; + auto r = fast_float::from_chars(str.data(), str.data() + str.size(), result); + // r.ec == std::errc::result_out_of_range + // r.ptr == str.data() + 6 + // result == std::numeric_limits<double>::infinity() +``` + +Users who wish for the value to be left unmodified given `std::errc::result_out_of_range` may do so by adding two lines of code: + +```cpp + double old_result = result; // make copy + auto r = fast_float::from_chars(start, end, result); + if(r.ec == std::errc::result_out_of_range) { result = old_result; } +``` + + ## C++20: compile-time evaluation (constexpr) In C++20, you may use `fast_float::from_chars` to parse strings @@ -290,6 +335,7 @@ int main() { The fast_float library is part of: - 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 and Microsoft Edge, - [WebKit](https://github.com/WebKit/WebKit), the engine behind Safari (Apple's web browser) - [DuckDB](https://duckdb.org) - [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied the number parsing speed by two or three times @@ -369,6 +415,16 @@ target_link_libraries(myprogram PUBLIC fast_float) You should change the `GIT_TAG` line so that you recover the version you wish to use. +You may also use [CPM](https://github.com/cpm-cmake/CPM.cmake), like so: + +``` +CPMAddPackage( + NAME fast_float + GITHUB_REPOSITORY "fastfloat/fast_float" + GIT_TAG v6.1.4) +``` + + ## Using as single header The script `script/amalgamate.py` may be used to generate a single header @@ -379,7 +435,13 @@ the command line help. You may directly download automatically generated single-header files: -https://github.com/fastfloat/fast_float/releases/download/v6.1.4/fast_float.h +https://github.com/fastfloat/fast_float/releases/download/v6.1.5/fast_float.h + +## 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). +- Some Linux distribution like Fedora include fast_float (e.g., as `fast_float-devel`). ## RFC 7159 diff --git a/contrib/restricted/fast_float/include/fast_float/bigint.h b/contrib/restricted/fast_float/include/fast_float/bigint.h index 92c3d5b192..03a5caa4a5 100644 --- a/contrib/restricted/fast_float/include/fast_float/bigint.h +++ b/contrib/restricted/fast_float/include/fast_float/bigint.h @@ -404,12 +404,16 @@ template <typename = void> struct pow5_tables { #endif }; +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + template <typename T> constexpr uint32_t pow5_tables<T>::large_step; template <typename T> constexpr uint64_t pow5_tables<T>::small_power_of_5[]; template <typename T> constexpr limb pow5_tables<T>::large_power_of_5[]; +#endif + // big integer type. implements a small subset of big integer // arithmetic, using simple algorithms since asymptotically // faster algorithms are slower for a small number of limbs. diff --git a/contrib/restricted/fast_float/include/fast_float/constexpr_feature_detect.h b/contrib/restricted/fast_float/include/fast_float/constexpr_feature_detect.h index 18daf40941..7624beafca 100644 --- a/contrib/restricted/fast_float/include/fast_float/constexpr_feature_detect.h +++ b/contrib/restricted/fast_float/include/fast_float/constexpr_feature_detect.h @@ -37,4 +37,10 @@ #define FASTFLOAT_IS_CONSTEXPR 0 #endif +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 0 +#else +#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 1 +#endif + #endif // FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H diff --git a/contrib/restricted/fast_float/include/fast_float/fast_table.h b/contrib/restricted/fast_float/include/fast_float/fast_table.h index 097e27b14b..69f9b2c924 100644 --- a/contrib/restricted/fast_float/include/fast_float/fast_table.h +++ b/contrib/restricted/fast_float/include/fast_float/fast_table.h @@ -693,10 +693,14 @@ template <class unused = void> struct powers_template { }; }; +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + template <class unused> constexpr uint64_t powers_template<unused>::power_of_five_128[number_of_entries]; +#endif + using powers = powers_template<>; } // namespace fast_float diff --git a/contrib/restricted/fast_float/include/fast_float/float_common.h b/contrib/restricted/fast_float/include/fast_float/float_common.h index 909765450d..82ab7b0c6b 100644 --- a/contrib/restricted/fast_float/include/fast_float/float_common.h +++ b/contrib/restricted/fast_float/include/fast_float/float_common.h @@ -343,7 +343,8 @@ full_multiplication(uint64_t a, uint64_t b) { // But MinGW on ARM64 doesn't have native support for 64-bit multiplications answer.high = __umulh(a, b); answer.low = a * b; -#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__)) +#elif defined(FASTFLOAT_32BIT) || \ + (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64)) answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64 #elif defined(FASTFLOAT_64BIT) && defined(__SIZEOF_INT128__) __uint128_t r = ((__uint128_t)a) * b; @@ -442,12 +443,16 @@ template <typename U> struct binary_format_lookup_tables<double, U> { constant_55555 * 5 * 5 * 5 * 5)}; }; +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + template <typename U> constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[]; template <typename U> constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[]; +#endif + template <typename U> struct binary_format_lookup_tables<float, U> { static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; @@ -469,12 +474,16 @@ template <typename U> struct binary_format_lookup_tables<float, U> { 0x1000000 / (constant_55555 * constant_55555 * 5)}; }; +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + template <typename U> constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[]; template <typename U> constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[]; +#endif + template <> inline constexpr int binary_format<double>::min_exponent_fast_path() { #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) @@ -677,8 +686,12 @@ template <typename = void> struct space_lut { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; }; +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + template <typename T> constexpr bool space_lut<T>::value[]; +#endif + inline constexpr bool is_space(uint8_t c) { return space_lut<>::value[c]; } #endif @@ -759,12 +772,16 @@ template <typename = void> struct int_luts { 3379220508056640625, 4738381338321616896}; }; +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + template <typename T> constexpr uint8_t int_luts<T>::chdigit[]; template <typename T> constexpr size_t int_luts<T>::maxdigits_u64[]; template <typename T> constexpr uint64_t int_luts<T>::min_safe_u64[]; +#endif + template <typename UC> fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) { return int_luts<>::chdigit[static_cast<unsigned char>(c)]; diff --git a/contrib/restricted/fast_float/ya.make b/contrib/restricted/fast_float/ya.make index 2149e7dfee..92f9329ca0 100644 --- a/contrib/restricted/fast_float/ya.make +++ b/contrib/restricted/fast_float/ya.make @@ -10,9 +10,9 @@ LICENSE( LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -VERSION(6.1.4) +VERSION(6.1.5) -ORIGINAL_SOURCE(https://github.com/fastfloat/fast_float/archive/v6.1.4.tar.gz) +ORIGINAL_SOURCE(https://github.com/fastfloat/fast_float/archive/v6.1.5.tar.gz) NO_COMPILER_WARNINGS() |