aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2025-02-21 09:30:59 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2025-02-21 09:48:00 +0300
commit669b571d35b21a81c584e96ef225e8decb190e8e (patch)
treead9ab84115aeb16f7209f2f471d5546e2b768758 /contrib
parent6439b5a3fc32966be75de7839c2ca04246448589 (diff)
downloadydb-669b571d35b21a81c584e96ef225e8decb190e8e.tar.gz
Update contrib/restricted/fast_float to 8.0.0
commit_hash:65d9b3d669fb4794d962c6233c5fe43eb098bb9d
Diffstat (limited to 'contrib')
-rw-r--r--contrib/restricted/fast_float/.yandex_meta/devtools.licenses.report44
-rw-r--r--contrib/restricted/fast_float/.yandex_meta/licenses.list.txt2
-rw-r--r--contrib/restricted/fast_float/.yandex_meta/override.nix4
-rw-r--r--contrib/restricted/fast_float/README.md100
-rw-r--r--contrib/restricted/fast_float/include/fast_float/ascii_number.h65
-rw-r--r--contrib/restricted/fast_float/include/fast_float/bigint.h26
-rw-r--r--contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h9
-rw-r--r--contrib/restricted/fast_float/include/fast_float/digit_comparison.h12
-rw-r--r--contrib/restricted/fast_float/include/fast_float/fast_float.h5
-rw-r--r--contrib/restricted/fast_float/include/fast_float/float_common.h473
-rw-r--r--contrib/restricted/fast_float/include/fast_float/parse_number.h39
-rw-r--r--contrib/restricted/fast_float/ya.make4
12 files changed, 609 insertions, 174 deletions
diff --git a/contrib/restricted/fast_float/.yandex_meta/devtools.licenses.report b/contrib/restricted/fast_float/.yandex_meta/devtools.licenses.report
index 8abcfe786e..2463628607 100644
--- a/contrib/restricted/fast_float/.yandex_meta/devtools.licenses.report
+++ b/contrib/restricted/fast_float/.yandex_meta/devtools.licenses.report
@@ -39,7 +39,7 @@ BELONGS ya.make
Match type : TAG
Links : http://opensource.org/licenses/mit-license.php, https://spdx.org/licenses/MIT
Files with this license:
- README.md [513:513]
+ README.md [535:535]
KEEP BSL-1.0 2c7a3fa82e66676005cd4ee2608fd7d2
BELONGS ya.make
@@ -76,7 +76,20 @@ FILE_INCLUDE AUTHORS found in files: LICENSE-MIT at line 23
Files with this license:
LICENSE-MIT [5:27]
-KEEP Apache-2.0 AND MIT 5eed35bbf652e4d32c909d95331a0c79
+KEEP Apache-2.0 79f65f9f30b137f9b03d455de6cfdac9
+BELONGS ya.make
+ License text:
+ Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+ 2.0</a> or <a href="LICENSE-MIT">MIT license</a> or <a
+ Scancode info:
+ Original SPDX id: Apache-2.0
+ Score : 100.00
+ Match type : REFERENCE
+ Links : http://www.apache.org/licenses/, http://www.apache.org/licenses/LICENSE-2.0, https://spdx.org/licenses/Apache-2.0
+ Files with this license:
+ README.md [534:535]
+
+KEEP Apache-2.0 AND MIT a76785199b4beee1ba8a8173f3d43241
BELONGS ya.make
Note: matched license text is too long. Read it in the source files.
Scancode info:
@@ -85,27 +98,14 @@ BELONGS ya.make
Match type : NOTICE
Links : http://www.apache.org/licenses/, http://www.apache.org/licenses/LICENSE-2.0, https://spdx.org/licenses/Apache-2.0
Files with this license:
- README.md [507:520]
+ README.md [529:544]
Scancode info:
Original SPDX id: MIT
Score : 49.30
Match type : NOTICE
Links : http://opensource.org/licenses/mit-license.php, https://spdx.org/licenses/MIT
Files with this license:
- README.md [507:520]
-
-KEEP Apache-2.0 79f65f9f30b137f9b03d455de6cfdac9
-BELONGS ya.make
- License text:
- Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
- 2.0</a> or <a href="LICENSE-MIT">MIT license</a> or <a
- Scancode info:
- Original SPDX id: Apache-2.0
- Score : 100.00
- Match type : REFERENCE
- Links : http://www.apache.org/licenses/, http://www.apache.org/licenses/LICENSE-2.0, https://spdx.org/licenses/Apache-2.0
- Files with this license:
- README.md [512:513]
+ README.md [529:544]
KEEP BSL-1.0 AND BSL-1.0 a8fd7a0ddc7793219e50dfdeb4742dfc
BELONGS ya.make
@@ -117,14 +117,14 @@ BELONGS ya.make
Match type : REFERENCE
Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
Files with this license:
- README.md [514:514]
+ README.md [536:536]
Scancode info:
Original SPDX id: BSL-1.0
Score : 99.00
Match type : REFERENCE
Links : http://www.boost.org/LICENSE_1_0.txt, http://www.boost.org/users/license.html, https://spdx.org/licenses/BSL-1.0
Files with this license:
- README.md [514:514]
+ README.md [536:536]
KEEP Apache-2.0 c48d93dbb5419f7a8844879928a2fda7
BELONGS ya.make
@@ -136,7 +136,7 @@ BELONGS ya.make
Match type : NOTICE
Links : http://www.apache.org/licenses/, http://www.apache.org/licenses/LICENSE-2.0, https://spdx.org/licenses/Apache-2.0
Files with this license:
- README.md [507:507]
+ README.md [529:529]
KEEP Apache-2.0 OR MIT OR BSL-1.0 dbfbb7aa50e4925e728f16d4a8adf7d9
BELONGS ya.make
@@ -148,14 +148,14 @@ BELONGS ya.make
Match type : INTRO
Links : https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.LICENSE
Files with this license:
- README.md [512:512]
+ README.md [534:534]
Scancode info:
Original SPDX id: Apache-2.0
Score : 90.00
Match type : TAG
Links : http://www.apache.org/licenses/, http://www.apache.org/licenses/LICENSE-2.0, https://spdx.org/licenses/Apache-2.0
Files with this license:
- README.md [512:512]
+ README.md [534:534]
KEEP Apache-2.0 fb21a7d67961597593aefff800484f8d
BELONGS ya.make
diff --git a/contrib/restricted/fast_float/.yandex_meta/licenses.list.txt b/contrib/restricted/fast_float/.yandex_meta/licenses.list.txt
index f59f716d84..9053f2a746 100644
--- a/contrib/restricted/fast_float/.yandex_meta/licenses.list.txt
+++ b/contrib/restricted/fast_float/.yandex_meta/licenses.list.txt
@@ -210,6 +210,8 @@ Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
href="LICENSE-BOOST">BOOST license</a>.
</sup>
+<br/>
+
<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this repository by you, as defined in the Apache-2.0 license,
diff --git a/contrib/restricted/fast_float/.yandex_meta/override.nix b/contrib/restricted/fast_float/.yandex_meta/override.nix
index c919ea16d6..7d5281172d 100644
--- a/contrib/restricted/fast_float/.yandex_meta/override.nix
+++ b/contrib/restricted/fast_float/.yandex_meta/override.nix
@@ -1,11 +1,11 @@
self: super: with self; rec {
name = "fast_float";
- version = "7.0.0";
+ version = "8.0.0";
src = fetchFromGitHub {
owner = "fastfloat";
repo = "fast_float";
rev = "v${version}";
- hash = "sha256-CG5je117WYyemTe5PTqznDP0bvY5TeXn8Vu1Xh5yUzQ=";
+ hash = "sha256-shP+me3iqTRrsPGYrvcbnJNRZouQbW62T24xfkEgGSE=";
};
}
diff --git a/contrib/restricted/fast_float/README.md b/contrib/restricted/fast_float/README.md
index bf8c3e3e59..3eb540b7b6 100644
--- a/contrib/restricted/fast_float/README.md
+++ b/contrib/restricted/fast_float/README.md
@@ -1,7 +1,6 @@
## fast_float number parsing library: 4x faster than strtod
-[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/fast_float.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:fast_float)
[![Ubuntu 22.04 CI (GCC 11)](https://github.com/fastfloat/fast_float/actions/workflows/ubuntu22.yml/badge.svg)](https://github.com/fastfloat/fast_float/actions/workflows/ubuntu22.yml)
The fast_float library provides fast header-only implementations for the C++
@@ -16,22 +15,22 @@ floating-point numbers with a C++17-like syntax (the library itself only
requires C++11):
```C++
-from_chars_result from_chars(const char* first, const char* last, float& value, ...);
-from_chars_result from_chars(const char* first, const char* last, double& value, ...);
+from_chars_result from_chars(char const *first, char const *last, float &value, ...);
+from_chars_result from_chars(char const *first, char const *last, double &value, ...);
```
You can also parse integer types:
```C++
-from_chars_result from_chars(const char* first, const char* last, int& value, ...);
-from_chars_result from_chars(const char* first, const char* last, unsigned& value, ...);
+from_chars_result from_chars(char const *first, char const *last, int &value, ...);
+from_chars_result from_chars(char const *first, char const *last, unsigned &value, ...);
```
The return type (`from_chars_result`) is defined as the struct:
```C++
struct from_chars_result {
- const char* ptr;
+ char const *ptr;
std::errc ec;
};
```
@@ -60,7 +59,7 @@ Example:
#include <iostream>
int main() {
- const std::string input = "3.1416 xyz ";
+ std::string input = "3.1416 xyz ";
double result;
auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result);
if (answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
@@ -72,7 +71,7 @@ int main() {
You can parse delimited numbers:
```C++
- const std::string input = "234532.3426362,7869234.9823,324562.645";
+ std::string input = "234532.3426362,7869234.9823,324562.645";
double result;
auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result);
if (answer.ec != std::errc()) {
@@ -108,9 +107,9 @@ The library seeks to follow the C++17 (see
[28.2.3.(6.1)](https://eel.is/c++draft/charconv.from.chars#6.1)) specification.
* The `from_chars` function does not skip leading white-space characters (unless
- `fast_float::chars_format::chars_format` is set).
+ `fast_float::chars_format::skip_white_space` is set).
* [A leading `+` sign](https://en.cppreference.com/w/cpp/utility/from_chars) is
- forbidden (unless `fast_float::chars_format::skip_white_space` is set).
+ forbidden (unless `fast_float::chars_format::allow_leading_plus` is set).
* It is generally impossible to represent a decimal value exactly as binary
floating-point number (`float` and `double` types). We seek the nearest value.
We round to an even mantissa when we are in-between two binary floating-point
@@ -119,8 +118,8 @@ The library seeks to follow the C++17 (see
Furthermore, we have the following restrictions:
* We support `float` and `double`, but not `long double`. We also support
- fixed-width floating-point types such as `std::float32_t` and
- `std::float64_t`.
+ fixed-width floating-point types such as `std::float64_t`, `std::float32_t`,
+ `std::float16_t`, and `std::bfloat16_t`.
* We only support the decimal format: we do not support hexadecimal strings.
* For values that are either very large or very small (e.g., `1e9999`), we
represent it using the infinity or negative infinity value and the returned
@@ -143,31 +142,31 @@ following code will print the number 22250738585072012 three times:
int main() {
uint64_t i;
- const char str[] = "22250738585072012";
- auto answer = fast_float::from_chars(str, str + strlen(str), i);
+ std::string str = "22250738585072012";
+ auto answer = fast_float::from_chars(str.data(), str.data() + str.size(), i);
if (answer.ec != std::errc()) {
std::cerr << "parsing failure\n";
return EXIT_FAILURE;
}
- std::cout << "parsed the number "<< i << std::endl;
+ std::cout << "parsed the number " << i << std::endl;
- const char binstr[] = "1001111000011001110110111001001010110100111000110001100";
+ std::string binstr = "1001111000011001110110111001001010110100111000110001100";
- answer = fast_float::from_chars(binstr, binstr + strlen(binstr), i, 2);
+ answer = fast_float::from_chars(binstr.data(), binstr.data() + binstr.size(), i, 2);
if (answer.ec != std::errc()) {
std::cerr << "parsing failure\n";
return EXIT_FAILURE;
}
- std::cout << "parsed the number "<< i << std::endl;
+ std::cout << "parsed the number " << i << std::endl;
- const char hexstr[] = "4f0cedc95a718c";
+ std::string hexstr = "4f0cedc95a718c";
- answer = fast_float::from_chars(hexstr, hexstr + strlen(hexstr), i, 16);
+ answer = fast_float::from_chars(hexstr.data(), hexstr.data() + hexstr.size(), i, 16);
if (answer.ec != std::errc()) {
std::cerr << "parsing failure\n";
return EXIT_FAILURE;
}
- std::cout << "parsed the number "<< i << std::endl;
+ std::cout << "parsed the number " << i << std::endl;
return EXIT_SUCCESS;
}
```
@@ -242,7 +241,8 @@ constexpr double constexptest() {
## C++23: Fixed width floating-point types
The library also supports fixed-width floating-point types such as
-`std::float32_t` and `std::float64_t`. E.g., you can write:
+`std::float64_t`, `std::float32_t`, `std::float16_t`, and `std::bfloat16_t`.
+E.g., you can write:
```C++
std::float32_t result;
@@ -259,7 +259,7 @@ following example:
#include <iostream>
int main() {
- const std::u16string input = u"3.1416 xyz ";
+ std::u16string input = u"3.1416 xyz ";
double result;
auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result);
if (answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
@@ -282,7 +282,7 @@ separator (e.g., the comma). You may use it as follows.
#include <iostream>
int main() {
- const std::string input = "3,1416 xyz ";
+ std::string input = "3,1416 xyz ";
double result;
fast_float::parse_options options{fast_float::chars_format::general, ','};
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
@@ -299,9 +299,9 @@ int main() {
#include <iostream>
int main() {
- const std::string input = "1d+4";
+ std::string input = "1d+4";
double result;
- fast_float::parse_options options{ fast_float::chars_format::fortran };
+ fast_float::parse_options options{fast_float::chars_format::fortran};
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
if ((answer.ec != std::errc()) || ((result != 10000))) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
std::cout << "parsed the number " << result << std::endl;
@@ -316,9 +316,9 @@ int main() {
#include <iostream>
int main() {
- const std::string input = "+.1"; // not valid
+ std::string input = "+.1"; // not valid
double result;
- fast_float::parse_options options{ fast_float::chars_format::json };
+ fast_float::parse_options options{fast_float::chars_format::json};
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
if (answer.ec == std::errc()) { std::cerr << "should have failed\n"; return EXIT_FAILURE; }
return EXIT_SUCCESS;
@@ -332,9 +332,9 @@ By default the JSON format does not allow `inf`:
#include <iostream>
int main() {
- const std::string input = "inf"; // not valid in JSON
+ std::string input = "inf"; // not valid in JSON
double result;
- fast_float::parse_options options{ fast_float::chars_format::json };
+ fast_float::parse_options options{fast_float::chars_format::json};
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
if (answer.ec == std::errc()) { std::cerr << "should have failed\n"; return EXIT_FAILURE; }
return EXIT_SUCCESS;
@@ -348,9 +348,9 @@ You can allow it with a non-standard `json_or_infnan` variant:
#include <iostream>
int main() {
- const std::string input = "inf"; // not valid in JSON but we allow it with json_or_infnan
+ std::string input = "inf"; // not valid in JSON but we allow it with json_or_infnan
double result;
- fast_float::parse_options options{ fast_float::chars_format::json_or_infnan };
+ fast_float::parse_options options{fast_float::chars_format::json_or_infnan};
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
if (answer.ec != std::errc() || (!std::isinf(result))) { std::cerr << "should have parsed infinity\n"; return EXIT_FAILURE; }
return EXIT_SUCCESS;
@@ -367,7 +367,7 @@ The fast_float library is part of:
* [WebKit](https://github.com/WebKit/WebKit), the engine behind Safari (Apple's
web browser),
* [DuckDB](https://duckdb.org),
-* [Redis](https://github.com/redis/redis),
+* [Redis](https://github.com/redis/redis) and [Valkey](https://github.com/valkey-io/valkey),
* [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied
the number parsing speed by two or three times,
* [Google Jsonnet](https://github.com/google/jsonnet),
@@ -429,8 +429,7 @@ abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfl
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s
```
-See <https://github.com/lemire/simple_fastfloat_benchmark> for our benchmarking
-code.
+See the [Benchmarking](#benchmarking) Section for instructions on how to run our benchmarks.
## Video
@@ -456,7 +455,7 @@ sufficiently recent version of CMake (3.11 or better at least):
FetchContent_Declare(
fast_float
GIT_REPOSITORY https://github.com/fastfloat/fast_float.git
- GIT_TAG tags/v6.1.6
+ GIT_TAG tags/v8.0.0
GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(fast_float)
@@ -472,7 +471,7 @@ 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.6)
+ GIT_TAG v8.0.0)
```
## Using as single header
@@ -484,7 +483,30 @@ if desired as described in the command line help.
You may directly download automatically generated single-header files:
-<https://github.com/fastfloat/fast_float/releases/download/v7.0.0/fast_float.h>
+<https://github.com/fastfloat/fast_float/releases/download/v8.0.0/fast_float.h>
+
+## Benchmarking
+
+The project has its own benchmarks with realistic data inputs. Under Linux or macOS,
+you can use it as follows if your system supports C++17:
+
+```
+cmake -B build -D FASTFLOAT_BENCHMARKS=ON
+cmake --build build
+./build/benchmarks/realbenchmark
+```
+
+Importantly, by default, the benchmark is built in Release mode.
+
+The instructions are similar under Windows.
+
+Under Linux and macOS, it is recommended to run the benchmarks in a privileged manner to get access
+to hardware performance counters. You may be able to do so with the `sudo` command
+in some cases:
+
+```
+sudo ./build/benchmarks/realbenchmark
+```
## Packages
@@ -514,6 +536,8 @@ Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
href="LICENSE-BOOST">BOOST license</a>.
</sup>
+<br/>
+
<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this repository by you, as defined in the Apache-2.0 license,
diff --git a/contrib/restricted/fast_float/include/fast_float/ascii_number.h b/contrib/restricted/fast_float/include/fast_float/ascii_number.h
index f2484e8486..9001016ac6 100644
--- a/contrib/restricted/fast_float/include/fast_float/ascii_number.h
+++ b/contrib/restricted/fast_float/include/fast_float/ascii_number.h
@@ -45,7 +45,7 @@ fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) {
// Read 8 UC into a u64. Truncates UC if not char.
template <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
-read8_to_u64(const UC *chars) {
+read8_to_u64(UC const *chars) {
if (cpp20_and_in_constexpr() || !std::is_same<UC, char>::value) {
uint64_t val = 0;
for (int i = 0; i < 8; ++i) {
@@ -65,9 +65,9 @@ read8_to_u64(const UC *chars) {
#ifdef FASTFLOAT_SSE2
-fastfloat_really_inline uint64_t simd_read8_to_u64(const __m128i data) {
+fastfloat_really_inline uint64_t simd_read8_to_u64(__m128i const data) {
FASTFLOAT_SIMD_DISABLE_WARNINGS
- const __m128i packed = _mm_packus_epi16(data, data);
+ __m128i const packed = _mm_packus_epi16(data, data);
#ifdef FASTFLOAT_64BIT
return uint64_t(_mm_cvtsi128_si64(packed));
#else
@@ -79,26 +79,26 @@ fastfloat_really_inline uint64_t simd_read8_to_u64(const __m128i data) {
FASTFLOAT_SIMD_RESTORE_WARNINGS
}
-fastfloat_really_inline uint64_t simd_read8_to_u64(const char16_t *chars) {
+fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
FASTFLOAT_SIMD_DISABLE_WARNINGS
return simd_read8_to_u64(
- _mm_loadu_si128(reinterpret_cast<const __m128i *>(chars)));
+ _mm_loadu_si128(reinterpret_cast<__m128i const *>(chars)));
FASTFLOAT_SIMD_RESTORE_WARNINGS
}
#elif defined(FASTFLOAT_NEON)
-fastfloat_really_inline uint64_t simd_read8_to_u64(const uint16x8_t data) {
+fastfloat_really_inline uint64_t simd_read8_to_u64(uint16x8_t const data) {
FASTFLOAT_SIMD_DISABLE_WARNINGS
uint8x8_t utf8_packed = vmovn_u16(data);
return vget_lane_u64(vreinterpret_u64_u8(utf8_packed), 0);
FASTFLOAT_SIMD_RESTORE_WARNINGS
}
-fastfloat_really_inline uint64_t simd_read8_to_u64(const char16_t *chars) {
+fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
FASTFLOAT_SIMD_DISABLE_WARNINGS
return simd_read8_to_u64(
- vld1q_u16(reinterpret_cast<const uint16_t *>(chars)));
+ vld1q_u16(reinterpret_cast<uint16_t const *>(chars)));
FASTFLOAT_SIMD_RESTORE_WARNINGS
}
@@ -118,9 +118,9 @@ uint64_t simd_read8_to_u64(UC const *) {
// credit @aqrit
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint32_t
parse_eight_digits_unrolled(uint64_t val) {
- const uint64_t mask = 0x000000FF000000FF;
- const uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
- const uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
+ uint64_t const mask = 0x000000FF000000FF;
+ uint64_t const mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
+ uint64_t const mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
val -= 0x3030303030303030;
val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8;
val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32;
@@ -150,20 +150,20 @@ is_made_of_eight_digits_fast(uint64_t val) noexcept {
// Using this style (instead of is_made_of_eight_digits_fast() then
// parse_eight_digits_unrolled()) ensures we don't load SIMD registers twice.
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
-simd_parse_if_eight_digits_unrolled(const char16_t *chars,
+simd_parse_if_eight_digits_unrolled(char16_t const *chars,
uint64_t &i) noexcept {
if (cpp20_and_in_constexpr()) {
return false;
}
#ifdef FASTFLOAT_SSE2
FASTFLOAT_SIMD_DISABLE_WARNINGS
- const __m128i data =
- _mm_loadu_si128(reinterpret_cast<const __m128i *>(chars));
+ __m128i const data =
+ _mm_loadu_si128(reinterpret_cast<__m128i const *>(chars));
// (x - '0') <= 9
// http://0x80.pl/articles/simd-parsing-int-sequences.html
- const __m128i t0 = _mm_add_epi16(data, _mm_set1_epi16(32720));
- const __m128i t1 = _mm_cmpgt_epi16(t0, _mm_set1_epi16(-32759));
+ __m128i const t0 = _mm_add_epi16(data, _mm_set1_epi16(32720));
+ __m128i const t1 = _mm_cmpgt_epi16(t0, _mm_set1_epi16(-32759));
if (_mm_movemask_epi8(t1) == 0) {
i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data));
@@ -173,12 +173,12 @@ simd_parse_if_eight_digits_unrolled(const char16_t *chars,
FASTFLOAT_SIMD_RESTORE_WARNINGS
#elif defined(FASTFLOAT_NEON)
FASTFLOAT_SIMD_DISABLE_WARNINGS
- const uint16x8_t data = vld1q_u16(reinterpret_cast<const uint16_t *>(chars));
+ uint16x8_t const data = vld1q_u16(reinterpret_cast<uint16_t const *>(chars));
// (x - '0') <= 9
// http://0x80.pl/articles/simd-parsing-int-sequences.html
- const uint16x8_t t0 = vsubq_u16(data, vmovq_n_u16('0'));
- const uint16x8_t mask = vcltq_u16(t0, vmovq_n_u16('9' - '0' + 1));
+ uint16x8_t const t0 = vsubq_u16(data, vmovq_n_u16('0'));
+ uint16x8_t const mask = vcltq_u16(t0, vmovq_n_u16('9' - '0' + 1));
if (vminvq_u16(mask) == 0xFFFF) {
i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data));
@@ -208,7 +208,7 @@ bool simd_parse_if_eight_digits_unrolled(UC const *, uint64_t &) {
template <typename UC, FASTFLOAT_ENABLE_IF(!std::is_same<UC, char>::value) = 0>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
-loop_parse_if_eight_digits(const UC *&p, const UC *const pend, uint64_t &i) {
+loop_parse_if_eight_digits(UC const *&p, UC const *const pend, uint64_t &i) {
if (!has_simd_opt<UC>()) {
return;
}
@@ -220,7 +220,7 @@ loop_parse_if_eight_digits(const UC *&p, const UC *const pend, uint64_t &i) {
}
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
-loop_parse_if_eight_digits(const char *&p, const char *const pend,
+loop_parse_if_eight_digits(char const *&p, char const *const pend,
uint64_t &i) {
// optimizes better than parse_if_eight_digits_unrolled() for UC = char.
while ((std::distance(p, pend) >= 8) &&
@@ -259,12 +259,12 @@ template <typename UC> struct parsed_number_string_t {
bool valid{false};
bool too_many_digits{false};
// contains the range of the significant digits
- span<const UC> integer{}; // non-nullable
- span<const UC> fraction{}; // nullable
+ span<UC const> integer{}; // non-nullable
+ span<UC const> fraction{}; // nullable
parse_error error{parse_error::no_error};
};
-using byte_span = span<const char>;
+using byte_span = span<char const>;
using parsed_number_string = parsed_number_string_t<char>;
template <typename UC>
@@ -328,7 +328,7 @@ parse_number_string(UC const *p, UC const *pend,
}
UC const *const end_of_integer_part = p;
int64_t digit_count = int64_t(end_of_integer_part - start_digits);
- answer.integer = span<const UC>(start_digits, size_t(digit_count));
+ answer.integer = span<UC const>(start_digits, size_t(digit_count));
if (uint64_t(fmt & detail::basic_json_fmt)) {
// at least 1 digit in integer part, without leading zeros
if (digit_count == 0) {
@@ -341,7 +341,7 @@ parse_number_string(UC const *p, UC const *pend,
}
int64_t exponent = 0;
- const bool has_decimal_point = (p != pend) && (*p == decimal_point);
+ bool const has_decimal_point = (p != pend) && (*p == decimal_point);
if (has_decimal_point) {
++p;
UC const *before = p;
@@ -355,7 +355,7 @@ parse_number_string(UC const *p, UC const *pend,
i = i * 10 + digit; // in rare cases, this will overflow, but that's ok
}
exponent = before - p;
- answer.fraction = span<const UC>(before, size_t(p - before));
+ answer.fraction = span<UC const>(before, size_t(p - before));
digit_count -= exponent;
}
if (uint64_t(fmt & detail::basic_json_fmt)) {
@@ -446,7 +446,7 @@ parse_number_string(UC const *p, UC const *pend,
i = 0;
p = answer.integer.ptr;
UC const *int_end = p + answer.integer.len();
- const uint64_t minimal_nineteen_digit_integer{1000000000000000000};
+ uint64_t const minimal_nineteen_digit_integer{1000000000000000000};
while ((i < minimal_nineteen_digit_integer) && (p != int_end)) {
i = i * 10 + uint64_t(*p - UC('0'));
++p;
@@ -482,7 +482,14 @@ parse_int_string(UC const *p, UC const *pend, T &value,
UC const *const first = p;
bool const negative = (*p == UC('-'));
+#ifdef FASTFLOAT_VISUAL_STUDIO
+#pragma warning(push)
+#pragma warning(disable : 4127)
+#endif
if (!std::is_signed<T>::value && negative) {
+#ifdef FASTFLOAT_VISUAL_STUDIO
+#pragma warning(pop)
+#endif
answer.ec = std::errc::invalid_argument;
answer.ptr = first;
return answer;
@@ -498,7 +505,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
++p;
}
- const bool has_leading_zeros = p > start_num;
+ bool const has_leading_zeros = p > start_num;
UC const *const start_digits = p;
diff --git a/contrib/restricted/fast_float/include/fast_float/bigint.h b/contrib/restricted/fast_float/include/fast_float/bigint.h
index 03a5caa4a5..74901e3956 100644
--- a/contrib/restricted/fast_float/include/fast_float/bigint.h
+++ b/contrib/restricted/fast_float/include/fast_float/bigint.h
@@ -43,8 +43,8 @@ template <uint16_t size> struct stackvec {
uint16_t length{0};
stackvec() = default;
- stackvec(const stackvec &) = delete;
- stackvec &operator=(const stackvec &) = delete;
+ stackvec(stackvec const &) = delete;
+ stackvec &operator=(stackvec const &) = delete;
stackvec(stackvec &&) = delete;
stackvec &operator=(stackvec &&other) = delete;
@@ -57,10 +57,12 @@ template <uint16_t size> struct stackvec {
FASTFLOAT_DEBUG_ASSERT(index < length);
return data[index];
}
+
FASTFLOAT_CONSTEXPR14 const limb &operator[](size_t index) const noexcept {
FASTFLOAT_DEBUG_ASSERT(index < length);
return data[index];
}
+
// index from the end of the container
FASTFLOAT_CONSTEXPR14 const limb &rindex(size_t index) const noexcept {
FASTFLOAT_DEBUG_ASSERT(index < length);
@@ -72,14 +74,19 @@ template <uint16_t size> struct stackvec {
FASTFLOAT_CONSTEXPR14 void set_len(size_t len) noexcept {
length = uint16_t(len);
}
+
constexpr size_t len() const noexcept { return length; }
+
constexpr bool is_empty() const noexcept { return length == 0; }
+
constexpr size_t capacity() const noexcept { return size; }
+
// append item to vector, without bounds checking
FASTFLOAT_CONSTEXPR14 void push_unchecked(limb value) noexcept {
data[length] = value;
length++;
}
+
// append item to vector, returning if item was added
FASTFLOAT_CONSTEXPR14 bool try_push(limb value) noexcept {
if (len() < capacity()) {
@@ -89,12 +96,14 @@ template <uint16_t size> struct stackvec {
return false;
}
}
+
// add items to the vector, from a span, without bounds checking
FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept {
limb *ptr = data + length;
std::copy_n(s.ptr, s.len(), ptr);
set_len(len() + s.len());
}
+
// try to add items to the vector, returning if items were added
FASTFLOAT_CONSTEXPR20 bool try_extend(limb_span s) noexcept {
if (len() + s.len() <= capacity()) {
@@ -104,6 +113,7 @@ template <uint16_t size> struct stackvec {
return false;
}
}
+
// resize the vector, without bounds checking
// if the new size is longer than the vector, assign value to each
// appended item.
@@ -119,6 +129,7 @@ template <uint16_t size> struct stackvec {
set_len(new_len);
}
}
+
// try to resize the vector, returning if the vector was resized.
FASTFLOAT_CONSTEXPR20 bool try_resize(size_t new_len, limb value) noexcept {
if (new_len > capacity()) {
@@ -128,6 +139,7 @@ template <uint16_t size> struct stackvec {
return true;
}
}
+
// check if any limbs are non-zero after the given index.
// this needs to be done in reverse order, since the index
// is relative to the most significant limbs.
@@ -140,6 +152,7 @@ template <uint16_t size> struct stackvec {
}
return false;
}
+
// normalize the big integer, so most-significant zero limbs are removed.
FASTFLOAT_CONSTEXPR14 void normalize() noexcept {
while (len() > 0 && rindex(0) == 0) {
@@ -423,8 +436,9 @@ struct bigint : pow5_tables<> {
stackvec<bigint_limbs> vec;
FASTFLOAT_CONSTEXPR20 bigint() : vec() {}
- bigint(const bigint &) = delete;
- bigint &operator=(const bigint &) = delete;
+
+ bigint(bigint const &) = delete;
+ bigint &operator=(bigint const &) = delete;
bigint(bigint &&) = delete;
bigint &operator=(bigint &&other) = delete;
@@ -473,7 +487,7 @@ struct bigint : pow5_tables<> {
// positive, this is larger, otherwise they are equal.
// the limbs are stored in little-endian order, so we
// must compare the limbs in ever order.
- FASTFLOAT_CONSTEXPR20 int compare(const bigint &other) const noexcept {
+ FASTFLOAT_CONSTEXPR20 int compare(bigint const &other) const noexcept {
if (vec.len() > other.vec.len()) {
return 1;
} else if (vec.len() < other.vec.len()) {
@@ -527,7 +541,7 @@ struct bigint : pow5_tables<> {
} else if (!vec.is_empty()) {
// move limbs
limb *dst = vec.data + n;
- const limb *src = vec.data;
+ limb const *src = vec.data;
std::copy_backward(src, src + vec.len(), dst + vec.len());
// fill in empty limbs
limb *first = vec.data;
diff --git a/contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h b/contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h
index 70ecf73c8e..948768265e 100644
--- a/contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h
+++ b/contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h
@@ -20,7 +20,7 @@ namespace fast_float {
template <int bit_precision>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128
compute_product_approximation(int64_t q, uint64_t w) {
- const int index = 2 * int(q - powers::smallest_power_of_five);
+ int const index = 2 * int(q - powers::smallest_power_of_five);
// For small values of q, e.g., q in [0,27], the answer is always exact
// because The line value128 firstproduct = full_multiplication(w,
// power_of_five_128[index]); gives the exact answer.
@@ -93,8 +93,8 @@ compute_error(int64_t q, uint64_t w) noexcept {
return compute_error_scaled<binary>(q, product.high, lz);
}
-// w * 10 ** q
-// The returned value should be a valid ieee64 number that simply need to be
+// Computers w * 10 ** q.
+// The returned value should be a valid number that simply needs to be
// packed. However, in some very rare cases, the computation will fail. In such
// cases, we return an adjusted_mantissa with a negative power of 2: the caller
// should recompute in such cases.
@@ -158,7 +158,8 @@ compute_float(int64_t q, uint64_t w) noexcept {
// next line is safe because -answer.power2 + 1 < 64
answer.mantissa >>= -answer.power2 + 1;
// Thankfully, we can't have both "round-to-even" and subnormals because
- // "round-to-even" only occurs for powers close to 0.
+ // "round-to-even" only occurs for powers close to 0 in the 32-bit and
+ // and 64-bit case (with no more than 19 digits).
answer.mantissa += (answer.mantissa & 1); // round up
answer.mantissa >>= 1;
// There is a weird scenario where we don't have a subnormal but just.
diff --git a/contrib/restricted/fast_float/include/fast_float/digit_comparison.h b/contrib/restricted/fast_float/include/fast_float/digit_comparison.h
index 303fff91eb..d7ef3d9acc 100644
--- a/contrib/restricted/fast_float/include/fast_float/digit_comparison.h
+++ b/contrib/restricted/fast_float/include/fast_float/digit_comparison.h
@@ -62,7 +62,7 @@ scientific_exponent(parsed_number_string_t<UC> &num) noexcept {
template <typename T>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
to_extended(T value) noexcept {
- using equiv_uint = typename binary_format<T>::equiv_uint;
+ using equiv_uint = equiv_uint_t<T>;
constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
constexpr equiv_uint hidden_bit_mask = binary_format<T>::hidden_bit_mask();
@@ -143,8 +143,8 @@ template <typename callback>
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void
round_nearest_tie_even(adjusted_mantissa &am, int32_t shift,
callback cb) noexcept {
- const uint64_t mask = (shift == 64) ? UINT64_MAX : (uint64_t(1) << shift) - 1;
- const uint64_t halfway = (shift == 0) ? 0 : uint64_t(1) << (shift - 1);
+ uint64_t const mask = (shift == 64) ? UINT64_MAX : (uint64_t(1) << shift) - 1;
+ uint64_t const halfway = (shift == 0) ? 0 : uint64_t(1) << (shift - 1);
uint64_t truncated_bits = am.mantissa & mask;
bool is_above = truncated_bits > halfway;
bool is_halfway = truncated_bits == halfway;
@@ -170,6 +170,7 @@ round_down(adjusted_mantissa &am, int32_t shift) noexcept {
}
am.power2 += shift;
}
+
template <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
skip_zeros(UC const *&first, UC const *last) noexcept {
@@ -213,15 +214,16 @@ is_truncated(UC const *first, UC const *last) noexcept {
}
return false;
}
+
template <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
-is_truncated(span<const UC> s) noexcept {
+is_truncated(span<UC const> s) noexcept {
return is_truncated(s.ptr, s.ptr + s.len());
}
template <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
-parse_eight_digits(const UC *&p, limb &value, size_t &counter,
+parse_eight_digits(UC const *&p, limb &value, size_t &counter,
size_t &count) noexcept {
value = value * 100000000 + parse_eight_digits_unrolled(p);
p += 8;
diff --git a/contrib/restricted/fast_float/include/fast_float/fast_float.h b/contrib/restricted/fast_float/include/fast_float/fast_float.h
index a812682b52..af65c96bde 100644
--- a/contrib/restricted/fast_float/include/fast_float/fast_float.h
+++ b/contrib/restricted/fast_float/include/fast_float/fast_float.h
@@ -31,7 +31,7 @@ namespace fast_float {
* `scientific`.
*/
template <typename T, typename UC = char,
- typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>())>
+ typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>::value)>
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars(UC const *first, UC const *last, T &value,
chars_format fmt = chars_format::general) noexcept;
@@ -49,10 +49,11 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
* from_chars for integer types.
*/
template <typename T, typename UC = char,
- typename = FASTFLOAT_ENABLE_IF(!is_supported_float_type<T>())>
+ typename = FASTFLOAT_ENABLE_IF(is_supported_integer_type<T>::value)>
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept;
} // namespace fast_float
+
#include "parse_number.h"
#endif // FASTFLOAT_FAST_FLOAT_H
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 0753904b34..be5abb44ee 100644
--- a/contrib/restricted/fast_float/include/fast_float/float_common.h
+++ b/contrib/restricted/fast_float/include/fast_float/float_common.h
@@ -5,6 +5,7 @@
#include <cstdint>
#include <cassert>
#include <cstring>
+#include <limits>
#include <type_traits>
#include <system_error>
#ifdef __has_include
@@ -14,6 +15,22 @@
#endif
#include "constexpr_feature_detect.h"
+#define FASTFLOAT_VERSION_MAJOR 8
+#define FASTFLOAT_VERSION_MINOR 0
+#define FASTFLOAT_VERSION_PATCH 0
+
+#define FASTFLOAT_STRINGIZE_IMPL(x) #x
+#define FASTFLOAT_STRINGIZE(x) FASTFLOAT_STRINGIZE_IMPL(x)
+
+#define FASTFLOAT_VERSION_STR \
+ FASTFLOAT_STRINGIZE(FASTFLOAT_VERSION_MAJOR) \
+ "." FASTFLOAT_STRINGIZE(FASTFLOAT_VERSION_MINOR) "." FASTFLOAT_STRINGIZE( \
+ FASTFLOAT_VERSION_PATCH)
+
+#define FASTFLOAT_VERSION \
+ (FASTFLOAT_VERSION_MAJOR * 10000 + FASTFLOAT_VERSION_MINOR * 100 + \
+ FASTFLOAT_VERSION_PATCH)
+
namespace fast_float {
enum class chars_format : uint64_t;
@@ -42,6 +59,7 @@ template <typename UC> struct from_chars_result_t {
UC const *ptr;
std::errc ec;
};
+
using from_chars_result = from_chars_result_t<char>;
template <typename UC> struct parse_options_t {
@@ -56,6 +74,7 @@ template <typename UC> struct parse_options_t {
/** The base used for integers */
int base;
};
+
using parse_options = parse_options_t<char>;
} // namespace fast_float
@@ -202,22 +221,45 @@ fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() {
}
template <typename T>
-fastfloat_really_inline constexpr bool is_supported_float_type() {
- return std::is_same<T, float>::value || std::is_same<T, double>::value
-#if __STDCPP_FLOAT32_T__
- || std::is_same<T, std::float32_t>::value
+struct is_supported_float_type
+ : std::integral_constant<
+ bool, std::is_same<T, double>::value || std::is_same<T, float>::value
+#ifdef __STDCPP_FLOAT64_T__
+ || std::is_same<T, std::float64_t>::value
#endif
-#if __STDCPP_FLOAT64_T__
- || std::is_same<T, std::float64_t>::value
+#ifdef __STDCPP_FLOAT32_T__
+ || std::is_same<T, std::float32_t>::value
#endif
- ;
-}
+#ifdef __STDCPP_FLOAT16_T__
+ || std::is_same<T, std::float16_t>::value
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+ || std::is_same<T, std::bfloat16_t>::value
+#endif
+ > {
+};
+
+template <typename T>
+using equiv_uint_t = typename std::conditional<
+ sizeof(T) == 1, uint8_t,
+ typename std::conditional<
+ sizeof(T) == 2, uint16_t,
+ typename std::conditional<sizeof(T) == 4, uint32_t,
+ uint64_t>::type>::type>::type;
+
+template <typename T> struct is_supported_integer_type : std::is_integral<T> {};
template <typename UC>
-fastfloat_really_inline constexpr bool is_supported_char_type() {
- return std::is_same<UC, char>::value || std::is_same<UC, wchar_t>::value ||
- std::is_same<UC, char16_t>::value || std::is_same<UC, char32_t>::value;
-}
+struct is_supported_char_type
+ : std::integral_constant<bool, std::is_same<UC, char>::value ||
+ std::is_same<UC, wchar_t>::value ||
+ std::is_same<UC, char16_t>::value ||
+ std::is_same<UC, char32_t>::value
+#ifdef __cpp_char8_t
+ || std::is_same<UC, char8_t>::value
+#endif
+ > {
+};
// Compares two ASCII strings in a case insensitive manner.
template <typename UC>
@@ -239,9 +281,11 @@ fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase,
// a pointer and a length to a contiguous block of memory
template <typename T> struct span {
- const T *ptr;
+ T const *ptr;
size_t length;
- constexpr span(const T *_ptr, size_t _length) : ptr(_ptr), length(_length) {}
+
+ constexpr span(T const *_ptr, size_t _length) : ptr(_ptr), length(_length) {}
+
constexpr span() : ptr(nullptr), length(0) {}
constexpr size_t len() const noexcept { return length; }
@@ -255,7 +299,9 @@ template <typename T> struct span {
struct value128 {
uint64_t low;
uint64_t high;
+
constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {}
+
constexpr value128() : low(0), high(0) {}
};
@@ -371,10 +417,12 @@ struct adjusted_mantissa {
uint64_t mantissa{0};
int32_t power2{0}; // a negative value indicates an invalid result
adjusted_mantissa() = default;
- constexpr bool operator==(const adjusted_mantissa &o) const {
+
+ constexpr bool operator==(adjusted_mantissa const &o) const {
return mantissa == o.mantissa && power2 == o.power2;
}
- constexpr bool operator!=(const adjusted_mantissa &o) const {
+
+ constexpr bool operator!=(adjusted_mantissa const &o) const {
return mantissa != o.mantissa || power2 != o.power2;
}
};
@@ -388,28 +436,27 @@ constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5;
template <typename T, typename U = void> struct binary_format_lookup_tables;
template <typename T> struct binary_format : binary_format_lookup_tables<T> {
- using equiv_uint =
- typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
-
- static inline constexpr int mantissa_explicit_bits();
- static inline constexpr int minimum_exponent();
- static inline constexpr int infinite_power();
- static inline constexpr int sign_index();
- static inline constexpr int
+ using equiv_uint = equiv_uint_t<T>;
+
+ static constexpr int mantissa_explicit_bits();
+ static constexpr int minimum_exponent();
+ static constexpr int infinite_power();
+ static constexpr int sign_index();
+ static constexpr int
min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
- static inline constexpr int max_exponent_fast_path();
- static inline constexpr int max_exponent_round_to_even();
- static inline constexpr int min_exponent_round_to_even();
- static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
- static inline constexpr uint64_t
+ static constexpr int max_exponent_fast_path();
+ static constexpr int max_exponent_round_to_even();
+ static constexpr int min_exponent_round_to_even();
+ static constexpr uint64_t max_mantissa_fast_path(int64_t power);
+ static constexpr uint64_t
max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
- static inline constexpr int largest_power_of_ten();
- static inline constexpr int smallest_power_of_ten();
- static inline constexpr T exact_power_of_ten(int64_t power);
- static inline constexpr size_t max_digits();
- static inline constexpr equiv_uint exponent_mask();
- static inline constexpr equiv_uint mantissa_mask();
- static inline constexpr equiv_uint hidden_bit_mask();
+ static constexpr int largest_power_of_ten();
+ static constexpr int smallest_power_of_ten();
+ static constexpr T exact_power_of_ten(int64_t power);
+ static constexpr size_t max_digits();
+ static constexpr equiv_uint exponent_mask();
+ static constexpr equiv_uint mantissa_mask();
+ static constexpr equiv_uint hidden_bit_mask();
};
template <typename U> struct binary_format_lookup_tables<double, U> {
@@ -517,6 +564,7 @@ template <>
inline constexpr int binary_format<double>::mantissa_explicit_bits() {
return 52;
}
+
template <>
inline constexpr int binary_format<float>::mantissa_explicit_bits() {
return 23;
@@ -545,6 +593,7 @@ inline constexpr int binary_format<float>::min_exponent_round_to_even() {
template <> inline constexpr int binary_format<double>::minimum_exponent() {
return -1023;
}
+
template <> inline constexpr int binary_format<float>::minimum_exponent() {
return -127;
}
@@ -552,6 +601,7 @@ template <> inline constexpr int binary_format<float>::minimum_exponent() {
template <> inline constexpr int binary_format<double>::infinite_power() {
return 0x7FF;
}
+
template <> inline constexpr int binary_format<float>::infinite_power() {
return 0xFF;
}
@@ -559,6 +609,7 @@ template <> inline constexpr int binary_format<float>::infinite_power() {
template <> inline constexpr int binary_format<double>::sign_index() {
return 63;
}
+
template <> inline constexpr int binary_format<float>::sign_index() {
return 31;
}
@@ -567,6 +618,7 @@ template <>
inline constexpr int binary_format<double>::max_exponent_fast_path() {
return 22;
}
+
template <>
inline constexpr int binary_format<float>::max_exponent_fast_path() {
return 10;
@@ -576,19 +628,271 @@ template <>
inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
return uint64_t(2) << mantissa_explicit_bits();
}
+
+template <>
+inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
+ return uint64_t(2) << mantissa_explicit_bits();
+}
+
+// credit: Jakub Jelínek
+#ifdef __STDCPP_FLOAT16_T__
+template <typename U> struct binary_format_lookup_tables<std::float16_t, U> {
+ static constexpr std::float16_t powers_of_ten[] = {1e0f16, 1e1f16, 1e2f16,
+ 1e3f16, 1e4f16};
+
+ // Largest integer value v so that (5**index * v) <= 1<<11.
+ // 0x800 == 1<<11
+ static constexpr uint64_t max_mantissa[] = {0x800,
+ 0x800 / 5,
+ 0x800 / (5 * 5),
+ 0x800 / (5 * 5 * 5),
+ 0x800 / (5 * 5 * 5 * 5),
+ 0x800 / (constant_55555)};
+};
+
+#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
+
+template <typename U>
+constexpr std::float16_t
+ binary_format_lookup_tables<std::float16_t, U>::powers_of_ten[];
+
+template <typename U>
+constexpr uint64_t
+ binary_format_lookup_tables<std::float16_t, U>::max_mantissa[];
+
+#endif
+
+template <>
+inline constexpr std::float16_t
+binary_format<std::float16_t>::exact_power_of_ten(int64_t power) {
+ // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ return (void)powers_of_ten[0], powers_of_ten[power];
+}
+
+template <>
+inline constexpr binary_format<std::float16_t>::equiv_uint
+binary_format<std::float16_t>::exponent_mask() {
+ return 0x7C00;
+}
+
+template <>
+inline constexpr binary_format<std::float16_t>::equiv_uint
+binary_format<std::float16_t>::mantissa_mask() {
+ return 0x03FF;
+}
+
+template <>
+inline constexpr binary_format<std::float16_t>::equiv_uint
+binary_format<std::float16_t>::hidden_bit_mask() {
+ return 0x0400;
+}
+
+template <>
+inline constexpr int binary_format<std::float16_t>::max_exponent_fast_path() {
+ return 4;
+}
+
+template <>
+inline constexpr int binary_format<std::float16_t>::mantissa_explicit_bits() {
+ return 10;
+}
+
template <>
inline constexpr uint64_t
-binary_format<double>::max_mantissa_fast_path(int64_t power) {
+binary_format<std::float16_t>::max_mantissa_fast_path() {
+ return uint64_t(2) << mantissa_explicit_bits();
+}
+
+template <>
+inline constexpr uint64_t
+binary_format<std::float16_t>::max_mantissa_fast_path(int64_t power) {
// caller is responsible to ensure that
- // power >= 0 && power <= 22
+ // power >= 0 && power <= 4
//
// Work around clang bug https://godbolt.org/z/zedh7rrhc
return (void)max_mantissa[0], max_mantissa[power];
}
+
template <>
-inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
+inline constexpr int binary_format<std::float16_t>::min_exponent_fast_path() {
+ return 0;
+}
+
+template <>
+inline constexpr int
+binary_format<std::float16_t>::max_exponent_round_to_even() {
+ return 5;
+}
+
+template <>
+inline constexpr int
+binary_format<std::float16_t>::min_exponent_round_to_even() {
+ return -22;
+}
+
+template <>
+inline constexpr int binary_format<std::float16_t>::minimum_exponent() {
+ return -15;
+}
+
+template <>
+inline constexpr int binary_format<std::float16_t>::infinite_power() {
+ return 0x1F;
+}
+
+template <> inline constexpr int binary_format<std::float16_t>::sign_index() {
+ return 15;
+}
+
+template <>
+inline constexpr int binary_format<std::float16_t>::largest_power_of_ten() {
+ return 4;
+}
+
+template <>
+inline constexpr int binary_format<std::float16_t>::smallest_power_of_ten() {
+ return -27;
+}
+
+template <>
+inline constexpr size_t binary_format<std::float16_t>::max_digits() {
+ return 22;
+}
+#endif // __STDCPP_FLOAT16_T__
+
+// credit: Jakub Jelínek
+#ifdef __STDCPP_BFLOAT16_T__
+template <typename U> struct binary_format_lookup_tables<std::bfloat16_t, U> {
+ static constexpr std::bfloat16_t powers_of_ten[] = {1e0bf16, 1e1bf16, 1e2bf16,
+ 1e3bf16};
+
+ // Largest integer value v so that (5**index * v) <= 1<<8.
+ // 0x100 == 1<<8
+ static constexpr uint64_t max_mantissa[] = {0x100, 0x100 / 5, 0x100 / (5 * 5),
+ 0x100 / (5 * 5 * 5),
+ 0x100 / (5 * 5 * 5 * 5)};
+};
+
+#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
+
+template <typename U>
+constexpr std::bfloat16_t
+ binary_format_lookup_tables<std::bfloat16_t, U>::powers_of_ten[];
+
+template <typename U>
+constexpr uint64_t
+ binary_format_lookup_tables<std::bfloat16_t, U>::max_mantissa[];
+
+#endif
+
+template <>
+inline constexpr std::bfloat16_t
+binary_format<std::bfloat16_t>::exact_power_of_ten(int64_t power) {
+ // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ return (void)powers_of_ten[0], powers_of_ten[power];
+}
+
+template <>
+inline constexpr int binary_format<std::bfloat16_t>::max_exponent_fast_path() {
+ return 3;
+}
+
+template <>
+inline constexpr binary_format<std::bfloat16_t>::equiv_uint
+binary_format<std::bfloat16_t>::exponent_mask() {
+ return 0x7F80;
+}
+
+template <>
+inline constexpr binary_format<std::bfloat16_t>::equiv_uint
+binary_format<std::bfloat16_t>::mantissa_mask() {
+ return 0x007F;
+}
+
+template <>
+inline constexpr binary_format<std::bfloat16_t>::equiv_uint
+binary_format<std::bfloat16_t>::hidden_bit_mask() {
+ return 0x0080;
+}
+
+template <>
+inline constexpr int binary_format<std::bfloat16_t>::mantissa_explicit_bits() {
+ return 7;
+}
+
+template <>
+inline constexpr uint64_t
+binary_format<std::bfloat16_t>::max_mantissa_fast_path() {
return uint64_t(2) << mantissa_explicit_bits();
}
+
+template <>
+inline constexpr uint64_t
+binary_format<std::bfloat16_t>::max_mantissa_fast_path(int64_t power) {
+ // caller is responsible to ensure that
+ // power >= 0 && power <= 3
+ //
+ // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ return (void)max_mantissa[0], max_mantissa[power];
+}
+
+template <>
+inline constexpr int binary_format<std::bfloat16_t>::min_exponent_fast_path() {
+ return 0;
+}
+
+template <>
+inline constexpr int
+binary_format<std::bfloat16_t>::max_exponent_round_to_even() {
+ return 3;
+}
+
+template <>
+inline constexpr int
+binary_format<std::bfloat16_t>::min_exponent_round_to_even() {
+ return -24;
+}
+
+template <>
+inline constexpr int binary_format<std::bfloat16_t>::minimum_exponent() {
+ return -127;
+}
+
+template <>
+inline constexpr int binary_format<std::bfloat16_t>::infinite_power() {
+ return 0xFF;
+}
+
+template <> inline constexpr int binary_format<std::bfloat16_t>::sign_index() {
+ return 15;
+}
+
+template <>
+inline constexpr int binary_format<std::bfloat16_t>::largest_power_of_ten() {
+ return 38;
+}
+
+template <>
+inline constexpr int binary_format<std::bfloat16_t>::smallest_power_of_ten() {
+ return -60;
+}
+
+template <>
+inline constexpr size_t binary_format<std::bfloat16_t>::max_digits() {
+ return 98;
+}
+#endif // __STDCPP_BFLOAT16_T__
+
+template <>
+inline constexpr uint64_t
+binary_format<double>::max_mantissa_fast_path(int64_t power) {
+ // caller is responsible to ensure that
+ // power >= 0 && power <= 22
+ //
+ // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ return (void)max_mantissa[0], max_mantissa[power];
+}
+
template <>
inline constexpr uint64_t
binary_format<float>::max_mantissa_fast_path(int64_t power) {
@@ -605,6 +909,7 @@ binary_format<double>::exact_power_of_ten(int64_t power) {
// Work around clang bug https://godbolt.org/z/zedh7rrhc
return (void)powers_of_ten[0], powers_of_ten[power];
}
+
template <>
inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
// Work around clang bug https://godbolt.org/z/zedh7rrhc
@@ -614,6 +919,7 @@ inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
template <> inline constexpr int binary_format<double>::largest_power_of_ten() {
return 308;
}
+
template <> inline constexpr int binary_format<float>::largest_power_of_ten() {
return 38;
}
@@ -622,6 +928,7 @@ template <>
inline constexpr int binary_format<double>::smallest_power_of_ten() {
return -342;
}
+
template <> inline constexpr int binary_format<float>::smallest_power_of_ten() {
return -64;
}
@@ -629,6 +936,7 @@ template <> inline constexpr int binary_format<float>::smallest_power_of_ten() {
template <> inline constexpr size_t binary_format<double>::max_digits() {
return 769;
}
+
template <> inline constexpr size_t binary_format<float>::max_digits() {
return 114;
}
@@ -638,6 +946,7 @@ inline constexpr binary_format<float>::equiv_uint
binary_format<float>::exponent_mask() {
return 0x7F800000;
}
+
template <>
inline constexpr binary_format<double>::equiv_uint
binary_format<double>::exponent_mask() {
@@ -649,6 +958,7 @@ inline constexpr binary_format<float>::equiv_uint
binary_format<float>::mantissa_mask() {
return 0x007FFFFF;
}
+
template <>
inline constexpr binary_format<double>::equiv_uint
binary_format<double>::mantissa_mask() {
@@ -660,6 +970,7 @@ inline constexpr binary_format<float>::equiv_uint
binary_format<float>::hidden_bit_mask() {
return 0x00800000;
}
+
template <>
inline constexpr binary_format<double>::equiv_uint
binary_format<double>::hidden_bit_mask() {
@@ -669,11 +980,12 @@ binary_format<double>::hidden_bit_mask() {
template <typename T>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
to_float(bool negative, adjusted_mantissa am, T &value) {
- using fastfloat_uint = typename binary_format<T>::equiv_uint;
- fastfloat_uint word = (fastfloat_uint)am.mantissa;
- word |= fastfloat_uint(am.power2)
- << binary_format<T>::mantissa_explicit_bits();
- word |= fastfloat_uint(negative) << binary_format<T>::sign_index();
+ using equiv_uint = equiv_uint_t<T>;
+ equiv_uint word = equiv_uint(am.mantissa);
+ word = equiv_uint(word | equiv_uint(am.power2)
+ << binary_format<T>::mantissa_explicit_bits());
+ word =
+ equiv_uint(word | equiv_uint(negative) << binary_format<T>::sign_index());
#if FASTFLOAT_HAS_BIT_CAST
value = std::bit_cast<T>(word);
#else
@@ -715,34 +1027,53 @@ template <typename UC> static constexpr uint64_t int_cmp_zeros() {
uint64_t(UC('0')) << 16 | UC('0'))
: (uint64_t(UC('0')) << 32 | UC('0'));
}
+
template <typename UC> static constexpr int int_cmp_len() {
return sizeof(uint64_t) / sizeof(UC);
}
-template <typename UC> static constexpr UC const *str_const_nan() {
- return nullptr;
-}
+
+template <typename UC> constexpr UC const *str_const_nan();
+
template <> constexpr char const *str_const_nan<char>() { return "nan"; }
+
template <> constexpr wchar_t const *str_const_nan<wchar_t>() { return L"nan"; }
+
template <> constexpr char16_t const *str_const_nan<char16_t>() {
return u"nan";
}
+
template <> constexpr char32_t const *str_const_nan<char32_t>() {
return U"nan";
}
-template <typename UC> static constexpr UC const *str_const_inf() {
- return nullptr;
+
+#ifdef __cpp_char8_t
+template <> constexpr char8_t const *str_const_nan<char8_t>() {
+ return u8"nan";
}
+#endif
+
+template <typename UC> constexpr UC const *str_const_inf();
+
template <> constexpr char const *str_const_inf<char>() { return "infinity"; }
+
template <> constexpr wchar_t const *str_const_inf<wchar_t>() {
return L"infinity";
}
+
template <> constexpr char16_t const *str_const_inf<char16_t>() {
return u"infinity";
}
+
template <> constexpr char32_t const *str_const_inf<char32_t>() {
return U"infinity";
}
+#ifdef __cpp_char8_t
+template <> constexpr char8_t const *str_const_inf<char8_t>() {
+ return u8"infinity";
+}
+#endif
+
template <typename = void> struct int_luts {
static constexpr uint8_t chdigit[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
@@ -808,6 +1139,50 @@ fastfloat_really_inline constexpr uint64_t min_safe_u64(int base) {
return int_luts<>::min_safe_u64[base - 2];
}
+static_assert(std::is_same<equiv_uint_t<double>, uint64_t>::value,
+ "equiv_uint should be uint64_t for double");
+static_assert(std::numeric_limits<double>::is_iec559,
+ "double must fulfill the requirements of IEC 559 (IEEE 754)");
+
+static_assert(std::is_same<equiv_uint_t<float>, uint32_t>::value,
+ "equiv_uint should be uint32_t for float");
+static_assert(std::numeric_limits<float>::is_iec559,
+ "float must fulfill the requirements of IEC 559 (IEEE 754)");
+
+#ifdef __STDCPP_FLOAT64_T__
+static_assert(std::is_same<equiv_uint_t<std::float64_t>, uint64_t>::value,
+ "equiv_uint should be uint64_t for std::float64_t");
+static_assert(
+ std::numeric_limits<std::float64_t>::is_iec559,
+ "std::float64_t must fulfill the requirements of IEC 559 (IEEE 754)");
+#endif // __STDCPP_FLOAT64_T__
+
+#ifdef __STDCPP_FLOAT32_T__
+static_assert(std::is_same<equiv_uint_t<std::float32_t>, uint32_t>::value,
+ "equiv_uint should be uint32_t for std::float32_t");
+static_assert(
+ std::numeric_limits<std::float32_t>::is_iec559,
+ "std::float32_t must fulfill the requirements of IEC 559 (IEEE 754)");
+#endif // __STDCPP_FLOAT32_T__
+
+#ifdef __STDCPP_FLOAT16_T__
+static_assert(
+ std::is_same<binary_format<std::float16_t>::equiv_uint, uint16_t>::value,
+ "equiv_uint should be uint16_t for std::float16_t");
+static_assert(
+ std::numeric_limits<std::float16_t>::is_iec559,
+ "std::float16_t must fulfill the requirements of IEC 559 (IEEE 754)");
+#endif // __STDCPP_FLOAT16_T__
+
+#ifdef __STDCPP_BFLOAT16_T__
+static_assert(
+ std::is_same<binary_format<std::bfloat16_t>::equiv_uint, uint16_t>::value,
+ "equiv_uint should be uint16_t for std::bfloat16_t");
+static_assert(
+ std::numeric_limits<std::bfloat16_t>::is_iec559,
+ "std::bfloat16_t must fulfill the requirements of IEC 559 (IEEE 754)");
+#endif // __STDCPP_BFLOAT16_T__
+
constexpr chars_format operator~(chars_format rhs) noexcept {
using int_type = std::underlying_type<chars_format>::type;
return static_cast<chars_format>(~static_cast<int_type>(rhs));
diff --git a/contrib/restricted/fast_float/include/fast_float/parse_number.h b/contrib/restricted/fast_float/include/fast_float/parse_number.h
index 28a23ee414..0dbb3a143a 100644
--- a/contrib/restricted/fast_float/include/fast_float/parse_number.h
+++ b/contrib/restricted/fast_float/include/fast_float/parse_number.h
@@ -10,6 +10,7 @@
#include <cstring>
#include <limits>
#include <system_error>
+
namespace fast_float {
namespace detail {
@@ -95,7 +96,7 @@ fastfloat_really_inline bool rounds_to_nearest() noexcept {
// asm). The value does not need to be std::numeric_limits<float>::min(), any
// small value so that 1 + x should round to 1 would do (after accounting for
// excess precision, as in 387 instructions).
- static volatile float fmin = std::numeric_limits<float>::min();
+ static float volatile fmin = std::numeric_limits<float>::min();
float fmini = fmin; // we copy it so that it gets loaded at most once.
//
// Explanation:
@@ -145,7 +146,7 @@ template <typename T> struct from_chars_caller {
}
};
-#if __STDCPP_FLOAT32_T__ == 1
+#ifdef __STDCPP_FLOAT32_T__
template <> struct from_chars_caller<std::float32_t> {
template <typename UC>
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
@@ -162,7 +163,7 @@ template <> struct from_chars_caller<std::float32_t> {
};
#endif
-#if __STDCPP_FLOAT64_T__ == 1
+#ifdef __STDCPP_FLOAT64_T__
template <> struct from_chars_caller<std::float64_t> {
template <typename UC>
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
@@ -196,9 +197,9 @@ 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>(),
+ static_assert(is_supported_float_type<T>::value,
"only some floating-point types are supported");
- static_assert(is_supported_char_type<UC>(),
+ 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;
@@ -285,9 +286,9 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars_float_advanced(UC const *first, UC const *last, T &value,
parse_options_t<UC> options) noexcept {
- static_assert(is_supported_float_type<T>(),
+ static_assert(is_supported_float_type<T>::value,
"only some floating-point types are supported");
- static_assert(is_supported_char_type<UC>(),
+ static_assert(is_supported_char_type<UC>::value,
"only char, wchar_t, char16_t and char32_t are supported");
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
@@ -323,8 +324,9 @@ template <typename T, typename UC, typename>
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars(UC const *first, UC const *last, T &value, int base) noexcept {
- static_assert(std::is_integral<T>::value, "only integer types are supported");
- static_assert(is_supported_char_type<UC>(),
+ static_assert(is_supported_integer_type<T>::value,
+ "only integer types are supported");
+ static_assert(is_supported_char_type<UC>::value,
"only char, wchar_t, char16_t and char32_t are supported");
parse_options_t<UC> options;
@@ -337,8 +339,9 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars_int_advanced(UC const *first, UC const *last, T &value,
parse_options_t<UC> options) noexcept {
- static_assert(std::is_integral<T>::value, "only integer types are supported");
- static_assert(is_supported_char_type<UC>(),
+ static_assert(is_supported_integer_type<T>::value,
+ "only integer types are supported");
+ static_assert(is_supported_char_type<UC>::value,
"only char, wchar_t, char16_t and char32_t are supported");
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
@@ -359,7 +362,11 @@ from_chars_int_advanced(UC const *first, UC const *last, T &value,
return parse_int_string(first, last, value, options);
}
-template <bool> struct from_chars_advanced_caller {
+template <size_t TypeIx> struct from_chars_advanced_caller {
+ static_assert(TypeIx > 0, "unsupported type");
+};
+
+template <> struct from_chars_advanced_caller<1> {
template <typename T, typename UC>
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
call(UC const *first, UC const *last, T &value,
@@ -368,7 +375,7 @@ template <bool> struct from_chars_advanced_caller {
}
};
-template <> struct from_chars_advanced_caller<false> {
+template <> struct from_chars_advanced_caller<2> {
template <typename T, typename UC>
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
call(UC const *first, UC const *last, T &value,
@@ -381,8 +388,10 @@ template <typename T, typename UC>
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
from_chars_advanced(UC const *first, UC const *last, T &value,
parse_options_t<UC> options) noexcept {
- return from_chars_advanced_caller<is_supported_float_type<T>()>::call(
- first, last, value, options);
+ return from_chars_advanced_caller<
+ size_t(is_supported_float_type<T>::value) +
+ 2 * size_t(is_supported_integer_type<T>::value)>::call(first, last, value,
+ options);
}
} // namespace fast_float
diff --git a/contrib/restricted/fast_float/ya.make b/contrib/restricted/fast_float/ya.make
index 32da568f8b..bc3dddf9f5 100644
--- a/contrib/restricted/fast_float/ya.make
+++ b/contrib/restricted/fast_float/ya.make
@@ -11,9 +11,9 @@ LICENSE(
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(7.0.0)
+VERSION(8.0.0)
-ORIGINAL_SOURCE(https://github.com/fastfloat/fast_float/archive/v7.0.0.tar.gz)
+ORIGINAL_SOURCE(https://github.com/fastfloat/fast_float/archive/v8.0.0.tar.gz)
NO_COMPILER_WARNINGS()