aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/fast_float
diff options
context:
space:
mode:
authorAlexSm <alex@ydb.tech>2024-01-04 15:09:05 +0100
committerGitHub <noreply@github.com>2024-01-04 15:09:05 +0100
commitdab291146f6cd7d35684e3a1150e5bb1c412982c (patch)
tree36ef35f6cacb6432845a4a33f940c95871036b32 /contrib/restricted/fast_float
parent63660ad5e7512029fd0218e7a636580695a24e1f (diff)
downloadydb-dab291146f6cd7d35684e3a1150e5bb1c412982c.tar.gz
Library import 5, delete go dependencies (#832)
* Library import 5, delete go dependencies * Fix yt client
Diffstat (limited to 'contrib/restricted/fast_float')
-rw-r--r--contrib/restricted/fast_float/README.md50
-rw-r--r--contrib/restricted/fast_float/include/fast_float/ascii_number.h107
-rw-r--r--contrib/restricted/fast_float/include/fast_float/fast_float.h8
-rw-r--r--contrib/restricted/fast_float/include/fast_float/float_common.h83
-rw-r--r--contrib/restricted/fast_float/include/fast_float/parse_number.h34
-rw-r--r--contrib/restricted/fast_float/ya.make4
6 files changed, 264 insertions, 22 deletions
diff --git a/contrib/restricted/fast_float/README.md b/contrib/restricted/fast_float/README.md
index d2ad1d874b..79ebedbd72 100644
--- a/contrib/restricted/fast_float/README.md
+++ b/contrib/restricted/fast_float/README.md
@@ -1,21 +1,24 @@
## 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)
-[![VS17-CI](https://github.com/fastfloat/fast_float/actions/workflows/vs17-ci.yml/badge.svg)](https://github.com/fastfloat/fast_float/actions/workflows/vs17-ci.yml)
[![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++ from_chars
-functions for `float` and `double` types. These functions convert ASCII strings representing
-decimal values (e.g., `1.3e10`) into binary types. We provide exact rounding (including
+functions for `float` and `double` types as well as integer types. These functions convert ASCII strings representing decimal values (e.g., `1.3e10`) into binary types. We provide exact rounding (including
round to even). In our experience, these `fast_float` functions many times faster than comparable number-parsing functions from existing C++ standard libraries.
-Specifically, `fast_float` provides the following two functions with a C++17-like syntax (the library itself only requires C++11):
+Specifically, `fast_float` provides the following two functions to parse 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, ...);
```
+You can also parse integer types:
+
+
+
+
The return type (`from_chars_result`) is defined as the struct:
```C++
struct from_chars_result {
@@ -104,6 +107,43 @@ We support Visual Studio, macOS, Linux, freeBSD. We support big and little endia
We assume that the rounding mode is set to nearest (`std::fegetround() == FE_TONEAREST`).
+
+## Integer types
+
+You can also parse integer types using different bases (e.g., 2, 10, 16). The following code will
+print the number 22250738585072012 three times:
+
+
+```C++
+ uint64_t i;
+ const char str[] = "22250738585072012";
+ auto answer = fast_float::from_chars(str, str + strlen(str), i);
+ if (answer.ec != std::errc()) {
+ std::cerr << "parsing failure\n";
+ return EXIT_FAILURE;
+ }
+ std::cout << "parsed the number "<< i << std::endl;
+
+ const char binstr[] = "1001111000011001110110111001001010110100111000110001100";
+
+ answer = fast_float::from_chars(binstr, binstr + strlen(binstr), i, 2);
+ if (answer.ec != std::errc()) {
+ std::cerr << "parsing failure\n";
+ return EXIT_FAILURE;
+ }
+ std::cout << "parsed the number "<< i << std::endl;
+
+
+ const char hexstr[] = "4f0cedc95a718c";
+
+ answer = fast_float::from_chars(hexstr, hexstr + strlen(hexstr), i, 16);
+ if (answer.ec != std::errc()) {
+ std::cerr << "parsing failure\n";
+ return EXIT_FAILURE;
+ }
+ std::cout << "parsed the number "<< i << std::endl;
+```
+
## C++20: compile-time evaluation (constexpr)
In C++20, you may use `fast_float::from_chars` to parse strings
@@ -331,7 +371,7 @@ the command line help.
You may directly download automatically generated single-header files:
-https://github.com/fastfloat/fast_float/releases/download/v5.3.0/fast_float.h
+https://github.com/fastfloat/fast_float/releases/download/v6.0.0/fast_float.h
## Credit
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 d18e3d5360..5d3eac9df5 100644
--- a/contrib/restricted/fast_float/include/fast_float/ascii_number.h
+++ b/contrib/restricted/fast_float/include/fast_float/ascii_number.h
@@ -5,6 +5,7 @@
#include <cstdint>
#include <cstring>
#include <iterator>
+#include <limits>
#include <type_traits>
#include "float_common.h"
@@ -115,7 +116,7 @@ FASTFLOAT_SIMD_RESTORE_WARNINGS
#if defined(_MSC_VER) && _MSC_VER <= 1900
template <typename UC>
#else
-template <typename UC, FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>())>
+template <typename UC, FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>()) = 0>
#endif
// dummy for compile
uint64_t simd_read8_to_u64(UC const*) {
@@ -223,7 +224,7 @@ FASTFLOAT_SIMD_RESTORE_WARNINGS
#if defined(_MSC_VER) && _MSC_VER <= 1900
template <typename UC>
#else
-template <typename UC, FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>())>
+template <typename UC, FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>()) = 0>
#endif
// dummy for compile
bool simd_parse_if_eight_digits_unrolled(UC const*, uint64_t&) {
@@ -231,7 +232,7 @@ bool simd_parse_if_eight_digits_unrolled(UC const*, uint64_t&) {
}
-template <typename UC, FASTFLOAT_ENABLE_IF(!std::is_same<UC, char>::value)>
+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) {
if (!has_simd_opt<UC>()) {
@@ -439,6 +440,106 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
return answer;
}
+template <typename T, typename UC>
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value, int base)
+{
+ from_chars_result_t<UC> answer;
+
+ UC const* const first = p;
+
+ bool negative = (*p == UC('-'));
+ if (!std::is_signed<T>::value && negative) {
+ answer.ec = std::errc::invalid_argument;
+ answer.ptr = first;
+ return answer;
+ }
+#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default
+ if ((*p == UC('-')) || (*p == UC('+'))) {
+#else
+ if (*p == UC('-')) {
+#endif
+ ++p;
+ }
+
+ UC const* const start_num = p;
+ while (*p == UC('0')) {
+ ++p;
+ }
+ const bool has_leading_zeros = p > start_num;
+
+ UC const* const start_digits = p;
+
+ uint64_t i = 0;
+ if (base == 10) {
+ loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible
+ }
+ while (p != pend) {
+ uint8_t digit = ch_to_digit(*p);
+ if (digit >= base) {
+ break;
+ }
+ i = uint64_t(base) * i + digit; // might overflow, check this later
+ p++;
+ }
+
+ size_t digit_count = size_t(p - start_digits);
+
+ if (digit_count == 0) {
+ if (has_leading_zeros) {
+ value = 0;
+ answer.ec = std::errc();
+ answer.ptr = p;
+ }
+ else {
+ answer.ec = std::errc::invalid_argument;
+ answer.ptr = first;
+ }
+ return answer;
+ }
+
+ answer.ptr = p;
+
+ // check u64 overflow
+ size_t max_digits = max_digits_u64(base);
+ if (digit_count > max_digits) {
+ answer.ec = std::errc::result_out_of_range;
+ return answer;
+ }
+ // this check can be eliminated for all other types, but they will all require a max_digits(base) equivalent
+ if (digit_count == max_digits && i < min_safe_u64(base)) {
+ answer.ec = std::errc::result_out_of_range;
+ return answer;
+ }
+
+ // check other types overflow
+ if (!std::is_same<T, uint64_t>::value) {
+ if (i > uint64_t(std::numeric_limits<T>::max()) + uint64_t(negative)) {
+ answer.ec = std::errc::result_out_of_range;
+ return answer;
+ }
+ }
+
+ if (negative) {
+#ifdef FASTFLOAT_VISUAL_STUDIO
+#pragma warning(push)
+#pragma warning(disable: 4146)
+#endif
+ // this weird workaround is required because:
+ // - converting unsigned to signed when its value is greater than signed max is UB pre-C++23.
+ // - reinterpret_casting (~i + 1) would work, but it is not constexpr
+ // this is always optimized into a neg instruction.
+ value = T(-std::numeric_limits<T>::max() - T(i - std::numeric_limits<T>::max()));
+#ifdef FASTFLOAT_VISUAL_STUDIO
+#pragma warning(pop)
+#endif
+ }
+ else { value = T(i); }
+
+ answer.ec = std::errc();
+ return answer;
+}
+
} // namespace fast_float
#endif
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 04efa877ee..9b1b9b4ff4 100644
--- a/contrib/restricted/fast_float/include/fast_float/fast_float.h
+++ b/contrib/restricted/fast_float/include/fast_float/fast_float.h
@@ -24,7 +24,7 @@ namespace fast_float {
* to determine whether we allow the fixed point and scientific notation respectively.
* The default is `fast_float::chars_format::general` which allows both `fixed` and `scientific`.
*/
-template<typename T, typename UC = char>
+template<typename T, typename UC = char, typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>())>
FASTFLOAT_CONSTEXPR20
from_chars_result_t<UC> from_chars(UC const * first, UC const * last,
T &value, chars_format fmt = chars_format::general) noexcept;
@@ -36,6 +36,12 @@ template<typename T, typename UC = char>
FASTFLOAT_CONSTEXPR20
from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
T &value, parse_options_t<UC> options) noexcept;
+/**
+* from_chars for integer types.
+*/
+template <typename T, typename UC = char, typename = FASTFLOAT_ENABLE_IF(!is_supported_float_type<T>())>
+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"
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 bee8821520..b5a357b124 100644
--- a/contrib/restricted/fast_float/include/fast_float/float_common.h
+++ b/contrib/restricted/fast_float/include/fast_float/float_common.h
@@ -134,7 +134,7 @@ using parse_options = parse_options_t<char>;
#define FASTFLOAT_NEON 1
#endif
-#if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_ARM64)
+#if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_NEON)
#define FASTFLOAT_HAS_SIMD 1
#endif
@@ -173,7 +173,7 @@ using parse_options = parse_options_t<char>;
// rust style `try!()` macro, or `?` operator
#define FASTFLOAT_TRY(x) { if (!(x)) return false; }
-#define FASTFLOAT_ENABLE_IF(...) typename std::enable_if<(__VA_ARGS__), int>::type = 0
+#define FASTFLOAT_ENABLE_IF(...) typename std::enable_if<(__VA_ARGS__), int>::type
namespace fast_float {
@@ -186,6 +186,20 @@ fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() {
#endif
}
+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;
+}
+
+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;
+}
+
// Compares two ASCII strings in a case insensitive manner.
template <typename UC>
inline FASTFLOAT_CONSTEXPR14 bool
@@ -234,7 +248,7 @@ int leading_zeroes_generic(uint64_t input_num, int last_bit = 0) {
if(input_num & uint64_t( 0xff00)) { input_num >>= 8; last_bit |= 8; }
if(input_num & uint64_t( 0xf0)) { input_num >>= 4; last_bit |= 4; }
if(input_num & uint64_t( 0xc)) { input_num >>= 2; last_bit |= 2; }
- if(input_num & uint64_t( 0x2)) { input_num >>= 1; last_bit |= 1; }
+ if(input_num & uint64_t( 0x2)) { /* input_num >>= 1; */ last_bit |= 1; }
return 63 - last_bit;
}
@@ -674,6 +688,69 @@ constexpr char32_t const * str_const_inf<char32_t>()
{
return U"infinity";
}
+
+
+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, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
+ 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 255, 255, 255, 255, 255,
+ 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+ };
+
+ static constexpr size_t maxdigits_u64[] = {
+ 64, 41, 32, 28, 25, 23, 22, 21,
+ 20, 19, 18, 18, 17, 17, 16, 16,
+ 16, 16, 15, 15, 15, 15, 14, 14,
+ 14, 14, 14, 14, 14, 13, 13, 13,
+ 13, 13, 13
+ };
+
+ static constexpr uint64_t min_safe_u64[] = {
+ 9223372036854775808ull, 12157665459056928801ull, 4611686018427387904, 7450580596923828125, 4738381338321616896,
+ 3909821048582988049, 9223372036854775808ull, 12157665459056928801ull, 10000000000000000000ull, 5559917313492231481,
+ 2218611106740436992, 8650415919381337933, 2177953337809371136, 6568408355712890625, 1152921504606846976,
+ 2862423051509815793, 6746640616477458432, 15181127029874798299ull, 1638400000000000000, 3243919932521508681,
+ 6221821273427820544, 11592836324538749809ull, 876488338465357824, 1490116119384765625, 2481152873203736576,
+ 4052555153018976267, 6502111422497947648, 10260628712958602189ull, 15943230000000000000ull, 787662783788549761,
+ 1152921504606846976, 1667889514952984961, 2386420683693101056, 3379220508056640625, 4738381338321616896
+ };
+};
+
+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[];
+
+template <typename UC>
+fastfloat_really_inline
+constexpr uint8_t ch_to_digit(UC c) { return int_luts<>::chdigit[static_cast<unsigned char>(c)]; }
+
+fastfloat_really_inline
+constexpr size_t max_digits_u64(int base) { return int_luts<>::maxdigits_u64[base - 2]; }
+
+// If a u64 is exactly max_digits_u64() in length, this is
+// the value below which it has definitely overflowed.
+fastfloat_really_inline
+constexpr uint64_t min_safe_u64(int base) { return int_luts<>::min_safe_u64[base - 2]; }
+
} // namespace fast_float
#endif
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 a011a8cbf4..1fd587bb9a 100644
--- a/contrib/restricted/fast_float/include/fast_float/parse_number.h
+++ b/contrib/restricted/fast_float/include/fast_float/parse_number.h
@@ -133,7 +133,7 @@ fastfloat_really_inline bool rounds_to_nearest() noexcept {
} // namespace detail
-template<typename T, typename UC>
+template<typename T, typename UC, typename>
FASTFLOAT_CONSTEXPR20
from_chars_result_t<UC> from_chars(UC const * first, UC const * last,
T &value, chars_format fmt /*= chars_format::general*/) noexcept {
@@ -145,11 +145,8 @@ FASTFLOAT_CONSTEXPR20
from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
T &value, parse_options_t<UC> options) noexcept {
- static_assert (std::is_same<T, double>::value || std::is_same<T, float>::value, "only float and double are supported");
- static_assert (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 , "only char, wchar_t, char16_t and char32_t are supported");
+ static_assert (is_supported_float_type<T>(), "only float and double are supported");
+ static_assert (is_supported_char_type<UC>(), "only char, wchar_t, char16_t and char32_t are supported");
from_chars_result_t<UC> answer;
#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
@@ -202,10 +199,10 @@ from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
// We do not have that fegetround() == FE_TONEAREST.
// Next is a modified Clinger's fast path, inspired by Jakub JelĂ­nek's proposal
if (pns.exponent >= 0 && pns.mantissa <=binary_format<T>::max_mantissa_fast_path(pns.exponent)) {
-#if defined(__clang__)
+#if defined(__clang__) || defined(FASTFLOAT_32BIT)
// Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD
if(pns.mantissa == 0) {
- value = pns.negative ? -0. : 0.;
+ value = pns.negative ? T(-0.) : T(0.);
return answer;
}
#endif
@@ -232,6 +229,27 @@ from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
return answer;
}
+
+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 (is_supported_char_type<UC>(), "only char, wchar_t, char16_t and char32_t are supported");
+
+ from_chars_result_t<UC> answer;
+#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
+ while ((first != last) && fast_float::is_space(uint8_t(*first))) {
+ first++;
+ }
+#endif
+ if (first == last || base < 2 || base > 36) {
+ answer.ec = std::errc::invalid_argument;
+ answer.ptr = first;
+ return answer;
+ }
+ return parse_int_string(first, last, value, base);
+}
+
} // namespace fast_float
#endif
diff --git a/contrib/restricted/fast_float/ya.make b/contrib/restricted/fast_float/ya.make
index dba751fb8a..acc85b8fc0 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(5.3.0)
+VERSION(6.0.0)
-ORIGINAL_SOURCE(https://github.com/fastfloat/fast_float/archive/v5.3.0.tar.gz)
+ORIGINAL_SOURCE(https://github.com/fastfloat/fast_float/archive/v6.0.0.tar.gz)
NO_COMPILER_WARNINGS()