aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2023-04-12 11:27:50 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2023-04-12 11:27:50 +0300
commit0e71846f867fa1d8474388f5e93235b90e2067a6 (patch)
tree3597de74837e9b7a4f6dd8ea9049ec581a0cdc6d
parent0852703272901c85d685ffd8a53633e0fd50c04b (diff)
downloadydb-0e71846f867fa1d8474388f5e93235b90e2067a6.tar.gz
Update contrib/restricted/fast_float to 3.11.0
-rw-r--r--contrib/restricted/fast_float/README.md21
-rw-r--r--contrib/restricted/fast_float/include/fast_float/ascii_number.h30
-rw-r--r--contrib/restricted/fast_float/include/fast_float/bigint.h9
-rw-r--r--contrib/restricted/fast_float/include/fast_float/constexpr_feature_detect.h40
-rw-r--r--contrib/restricted/fast_float/include/fast_float/decimal_to_binary.h6
-rw-r--r--contrib/restricted/fast_float/include/fast_float/digit_comparison.h42
-rw-r--r--contrib/restricted/fast_float/include/fast_float/fast_float.h4
-rw-r--r--contrib/restricted/fast_float/include/fast_float/float_common.h33
-rw-r--r--contrib/restricted/fast_float/include/fast_float/parse_number.h11
9 files changed, 136 insertions, 60 deletions
diff --git a/contrib/restricted/fast_float/README.md b/contrib/restricted/fast_float/README.md
index 3e538712fd..63c2c8caae 100644
--- a/contrib/restricted/fast_float/README.md
+++ b/contrib/restricted/fast_float/README.md
@@ -72,6 +72,27 @@ 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`).
+## C++20: compile-time evaluation (constexpr)
+
+In C++20, you may use `fast_float::from_chars` to parse strings
+at compile-time, as in the following example:
+
+```C++
+// consteval forces compile-time evaluation of the function in C++20.
+consteval double parse(std::string_view input) {
+ double result;
+ auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
+ if(answer.ec != std::errc()) { return -1.0; }
+ return result;
+}
+
+// This function should compile to a function which
+// merely returns 3.1415.
+constexpr double constexptest() {
+ return parse("3.1415 input");
+}
+```
+
## Using commas as decimal separator
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 6f3e69dfc1..72b8098eda 100644
--- a/contrib/restricted/fast_float/include/fast_float/ascii_number.h
+++ b/contrib/restricted/fast_float/include/fast_float/ascii_number.h
@@ -27,7 +27,16 @@ fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) {
| (val & 0x00000000000000FF) << 56;
}
-fastfloat_really_inline uint64_t read_u64(const char *chars) {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+uint64_t read_u64(const char *chars) {
+ if (cpp20_and_in_constexpr()) {
+ uint64_t val = 0;
+ for(int i = 0; i < 8; ++i) {
+ val |= uint64_t(*chars) << (i*8);
+ ++chars;
+ }
+ return val;
+ }
uint64_t val;
::memcpy(&val, chars, sizeof(uint64_t));
#if FASTFLOAT_IS_BIG_ENDIAN == 1
@@ -37,7 +46,16 @@ fastfloat_really_inline uint64_t read_u64(const char *chars) {
return val;
}
-fastfloat_really_inline void write_u64(uint8_t *chars, uint64_t val) {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+void write_u64(uint8_t *chars, uint64_t val) {
+ if (cpp20_and_in_constexpr()) {
+ for(int i = 0; i < 8; ++i) {
+ *chars = uint8_t(val);
+ val >>= 8;
+ ++chars;
+ }
+ return;
+ }
#if FASTFLOAT_IS_BIG_ENDIAN == 1
// Need to read as-if the number was in little-endian order.
val = byteswap(val);
@@ -57,7 +75,8 @@ uint32_t parse_eight_digits_unrolled(uint64_t val) {
return uint32_t(val);
}
-fastfloat_really_inline uint32_t parse_eight_digits_unrolled(const char *chars) noexcept {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+uint32_t parse_eight_digits_unrolled(const char *chars) noexcept {
return parse_eight_digits_unrolled(read_u64(chars));
}
@@ -67,7 +86,8 @@ fastfloat_really_inline constexpr bool is_made_of_eight_digits_fast(uint64_t val
0x8080808080808080));
}
-fastfloat_really_inline bool is_made_of_eight_digits_fast(const char *chars) noexcept {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+bool is_made_of_eight_digits_fast(const char *chars) noexcept {
return is_made_of_eight_digits_fast(read_u64(chars));
}
@@ -87,7 +107,7 @@ struct parsed_number_string {
// Assuming that you use no more than 19 digits, this will
// parse an ASCII string.
-fastfloat_really_inline
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
parsed_number_string parse_number_string(const char *p, const char *pend, parse_options options) noexcept {
const chars_format fmt = options.format;
const char decimal_point = options.decimal_point;
diff --git a/contrib/restricted/fast_float/include/fast_float/bigint.h b/contrib/restricted/fast_float/include/fast_float/bigint.h
index 5a72caa8d0..5076b47cc5 100644
--- a/contrib/restricted/fast_float/include/fast_float/bigint.h
+++ b/contrib/restricted/fast_float/include/fast_float/bigint.h
@@ -514,7 +514,7 @@ struct bigint : pow5_tables<> {
// move limbs
limb* dst = vec.data + n;
const limb* src = vec.data;
- ::memmove(dst, src, sizeof(limb) * vec.len());
+ std::copy_backward(src, src + vec.len(), dst + vec.len());
// fill in empty limbs
limb* first = vec.data;
limb* last = first + n;
@@ -594,7 +594,12 @@ struct bigint : pow5_tables<> {
exp -= small_step;
}
if (exp != 0) {
- FASTFLOAT_TRY(small_mul(vec, limb(small_power_of_5[exp])));
+ // Work around clang bug https://godbolt.org/z/zedh7rrhc
+ // This is similar to https://github.com/llvm/llvm-project/issues/47746,
+ // except the workaround described there don't work here
+ FASTFLOAT_TRY(
+ small_mul(vec, limb(((void)small_power_of_5[0], small_power_of_5[exp])))
+ );
}
return true;
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
new file mode 100644
index 0000000000..9ec8611fd9
--- /dev/null
+++ b/contrib/restricted/fast_float/include/fast_float/constexpr_feature_detect.h
@@ -0,0 +1,40 @@
+#ifndef FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H
+#define FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H
+
+#ifdef __has_include
+#if __has_include(<version>)
+#include <version>
+#endif
+#endif
+
+// Testing for https://wg21.link/N3652, adopted in C++14
+#if __cpp_constexpr >= 201304
+#define FASTFLOAT_CONSTEXPR14 constexpr
+#else
+#define FASTFLOAT_CONSTEXPR14
+#endif
+
+#if __cpp_lib_bit_cast >= 201806L
+#define FASTFLOAT_HAS_BIT_CAST 1
+#else
+#define FASTFLOAT_HAS_BIT_CAST 0
+#endif
+
+#if __cpp_lib_is_constant_evaluated >= 201811L
+#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 1
+#else
+#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0
+#endif
+
+// Testing for relevant C++20 constexpr library features
+#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED \
+ && FASTFLOAT_HAS_BIT_CAST \
+ && __cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/
+#define FASTFLOAT_CONSTEXPR20 constexpr
+#define FASTFLOAT_IS_CONSTEXPR 1
+#else
+#define FASTFLOAT_CONSTEXPR20
+#define FASTFLOAT_IS_CONSTEXPR 0
+#endif
+
+#endif // FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H
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 64f3f5a4c9..6d0f73040f 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
@@ -17,7 +17,7 @@ namespace fast_float {
// low part corresponding to the least significant bits.
//
template <int bit_precision>
-fastfloat_really_inline
+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);
// For small values of q, e.g., q in [0,27], the answer is always exact because
@@ -76,7 +76,7 @@ adjusted_mantissa compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept
// w * 10 ** q, without rounding the representation up.
// the power2 in the exponent will be adjusted by invalid_am_bias.
template <typename binary>
-fastfloat_really_inline
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
adjusted_mantissa compute_error(int64_t q, uint64_t w) noexcept {
int lz = leading_zeroes(w);
w <<= lz;
@@ -90,7 +90,7 @@ adjusted_mantissa compute_error(int64_t q, uint64_t w) noexcept {
// return an adjusted_mantissa with a negative power of 2: the caller should recompute
// in such cases.
template <typename binary>
-fastfloat_really_inline
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
adjusted_mantissa answer;
if ((w == 0) || (q < binary::smallest_power_of_ten())) {
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 4e0e6a8b81..3959ba0ebd 100644
--- a/contrib/restricted/fast_float/include/fast_float/digit_comparison.h
+++ b/contrib/restricted/fast_float/include/fast_float/digit_comparison.h
@@ -44,7 +44,8 @@ int32_t scientific_exponent(parsed_number_string& num) noexcept {
// this converts a native floating-point number to an extended-precision float.
template <typename T>
-fastfloat_really_inline adjusted_mantissa to_extended(T value) noexcept {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+adjusted_mantissa to_extended(T value) noexcept {
using equiv_uint = typename binary_format<T>::equiv_uint;
constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
@@ -53,7 +54,11 @@ fastfloat_really_inline adjusted_mantissa to_extended(T value) noexcept {
adjusted_mantissa am;
int32_t bias = binary_format<T>::mantissa_explicit_bits() - binary_format<T>::minimum_exponent();
equiv_uint bits;
+#if FASTFLOAT_HAS_BIT_CAST
+ bits = std::bit_cast<equiv_uint>(value);
+#else
::memcpy(&bits, &value, sizeof(T));
+#endif
if ((bits & exponent_mask) == 0) {
// denormal
am.power2 = 1 - bias;
@@ -72,7 +77,8 @@ fastfloat_really_inline adjusted_mantissa to_extended(T value) noexcept {
// we are given a native float that represents b, so we need to adjust it
// halfway between b and b+u.
template <typename T>
-fastfloat_really_inline adjusted_mantissa to_extended_halfway(T value) noexcept {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+adjusted_mantissa to_extended_halfway(T value) noexcept {
adjusted_mantissa am = to_extended(value);
am.mantissa <<= 1;
am.mantissa += 1;
@@ -148,9 +154,10 @@ void round_down(adjusted_mantissa& am, int32_t shift) noexcept {
am.power2 += shift;
}
-fastfloat_really_inline void skip_zeros(const char*& first, const char* last) noexcept {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+void skip_zeros(const char*& first, const char* last) noexcept {
uint64_t val;
- while (std::distance(first, last) >= 8) {
+ while (!cpp20_and_in_constexpr() && std::distance(first, last) >= 8) {
::memcpy(&val, first, sizeof(uint64_t));
if (val != 0x3030303030303030) {
break;
@@ -167,10 +174,11 @@ fastfloat_really_inline void skip_zeros(const char*& first, const char* last) no
// determine if any non-zero digits were truncated.
// all characters must be valid digits.
-fastfloat_really_inline bool is_truncated(const char* first, const char* last) noexcept {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+bool is_truncated(const char* first, const char* last) noexcept {
// do 8-bit optimizations, can just compare to 8 literal 0s.
uint64_t val;
- while (std::distance(first, last) >= 8) {
+ while (!cpp20_and_in_constexpr() && std::distance(first, last) >= 8) {
::memcpy(&val, first, sizeof(uint64_t));
if (val != 0x3030303030303030) {
return true;
@@ -186,11 +194,12 @@ fastfloat_really_inline bool is_truncated(const char* first, const char* last) n
return false;
}
-fastfloat_really_inline bool is_truncated(byte_span s) noexcept {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+bool is_truncated(byte_span s) noexcept {
return is_truncated(s.ptr, s.ptr + s.len());
}
-fastfloat_really_inline
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
void parse_eight_digits(const char*& p, limb& value, size_t& counter, size_t& count) noexcept {
value = value * 100000000 + parse_eight_digits_unrolled(p);
p += 8;
@@ -206,13 +215,14 @@ void parse_one_digit(const char*& p, limb& value, size_t& counter, size_t& count
count++;
}
-fastfloat_really_inline
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
void add_native(bigint& big, limb power, limb value) noexcept {
big.mul(power);
big.add(value);
}
-fastfloat_really_inline void round_up_bigint(bigint& big, size_t& count) noexcept {
+fastfloat_really_inline FASTFLOAT_CONSTEXPR20
+void round_up_bigint(bigint& big, size_t& count) noexcept {
// need to round-up the digits, but need to avoid rounding
// ....9999 to ...10000, which could cause a false halfway point.
add_native(big, 10, 1);
@@ -220,7 +230,8 @@ fastfloat_really_inline void round_up_bigint(bigint& big, size_t& count) noexcep
}
// parse the significant digits into a big integer
-inline void parse_mantissa(bigint& result, parsed_number_string& num, size_t max_digits, size_t& digits) noexcept {
+inline FASTFLOAT_CONSTEXPR20
+void parse_mantissa(bigint& result, parsed_number_string& num, size_t max_digits, size_t& digits) noexcept {
// try to minimize the number of big integer and scalar multiplication.
// therefore, try to parse 8 digits at a time, and multiply by the largest
// scalar value (9 or 19 digits) for each step.
@@ -300,7 +311,8 @@ inline void parse_mantissa(bigint& result, parsed_number_string& num, size_t max
}
template <typename T>
-inline adjusted_mantissa positive_digit_comp(bigint& bigmant, int32_t exponent) noexcept {
+inline FASTFLOAT_CONSTEXPR20
+adjusted_mantissa positive_digit_comp(bigint& bigmant, int32_t exponent) noexcept {
FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent)));
adjusted_mantissa answer;
bool truncated;
@@ -323,7 +335,8 @@ inline adjusted_mantissa positive_digit_comp(bigint& bigmant, int32_t exponent)
// we then need to scale by `2^(f- e)`, and then the two significant digits
// are of the same magnitude.
template <typename T>
-inline adjusted_mantissa negative_digit_comp(bigint& bigmant, adjusted_mantissa am, int32_t exponent) noexcept {
+inline FASTFLOAT_CONSTEXPR20
+adjusted_mantissa negative_digit_comp(bigint& bigmant, adjusted_mantissa am, int32_t exponent) noexcept {
bigint& real_digits = bigmant;
int32_t real_exp = exponent;
@@ -383,7 +396,8 @@ inline adjusted_mantissa negative_digit_comp(bigint& bigmant, adjusted_mantissa
// the actual digits. we then compare the big integer representations
// of both, and use that to direct rounding.
template <typename T>
-inline adjusted_mantissa digit_comp(parsed_number_string& num, adjusted_mantissa am) noexcept {
+inline FASTFLOAT_CONSTEXPR20
+adjusted_mantissa digit_comp(parsed_number_string& num, adjusted_mantissa am) noexcept {
// remove the invalid exponent bias
am.power2 -= invalid_am_bias;
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 d3497fd6b6..65704da4b5 100644
--- a/contrib/restricted/fast_float/include/fast_float/fast_float.h
+++ b/contrib/restricted/fast_float/include/fast_float/fast_float.h
@@ -3,6 +3,8 @@
#include <system_error>
+#include "constexpr_feature_detect.h"
+
namespace fast_float {
enum chars_format {
scientific = 1<<0,
@@ -48,6 +50,7 @@ struct parse_options {
* The default is `fast_float::chars_format::general` which allows both `fixed` and `scientific`.
*/
template<typename T>
+FASTFLOAT_CONSTEXPR20
from_chars_result from_chars(const char *first, const char *last,
T &value, chars_format fmt = chars_format::general) noexcept;
@@ -55,6 +58,7 @@ from_chars_result from_chars(const char *first, const char *last,
* Like from_chars, but accepts an `options` argument to govern number parsing.
*/
template<typename T>
+FASTFLOAT_CONSTEXPR20
from_chars_result from_chars_advanced(const char *first, const char *last,
T &value, parse_options options) noexcept;
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 77e3e59586..c878486b9a 100644
--- a/contrib/restricted/fast_float/include/fast_float/float_common.h
+++ b/contrib/restricted/fast_float/include/fast_float/float_common.h
@@ -7,23 +7,8 @@
#include <cstring>
#include <type_traits>
-#ifdef __has_include
-#if __has_include(<version>)
-#include <version>
-#endif
-#endif
-
-#if __cpp_lib_bit_cast >= 201806L
+#if FASTFLOAT_HAS_BIT_CAST
#include <bit>
-#define FASTFLOAT_HAS_BIT_CAST 1
-#else
-#define FASTFLOAT_HAS_BIT_CAST 0
-#endif
-
-#if __cpp_lib_is_constant_evaluated >= 201811L
-#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 1
-#else
-#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0
#endif
#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \
@@ -110,22 +95,6 @@
// rust style `try!()` macro, or `?` operator
#define FASTFLOAT_TRY(x) { if (!(x)) return false; }
-// Testing for https://wg21.link/N3652, adopted in C++14
-#if __cpp_constexpr >= 201304
-#define FASTFLOAT_CONSTEXPR14 constexpr
-#else
-#define FASTFLOAT_CONSTEXPR14
-#endif
-
-// Testing for relevant C++20 constexpr library features
-#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED \
- && FASTFLOAT_HAS_BIT_CAST \
- && __cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/
-#define FASTFLOAT_CONSTEXPR20 constexpr
-#else
-#define FASTFLOAT_CONSTEXPR20
-#endif
-
namespace fast_float {
fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() {
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 5f5c26490c..d16a25d709 100644
--- a/contrib/restricted/fast_float/include/fast_float/parse_number.h
+++ b/contrib/restricted/fast_float/include/fast_float/parse_number.h
@@ -20,8 +20,9 @@ namespace detail {
* strings a null-free and fixed.
**/
template <typename T>
-from_chars_result parse_infnan(const char *first, const char *last, T &value) noexcept {
- from_chars_result answer;
+from_chars_result FASTFLOAT_CONSTEXPR14
+parse_infnan(const char *first, const char *last, T &value) noexcept {
+ from_chars_result answer{};
answer.ptr = first;
answer.ec = std::errc(); // be optimistic
bool minusSign = false;
@@ -132,12 +133,14 @@ fastfloat_really_inline bool rounds_to_nearest() noexcept {
} // namespace detail
template<typename T>
+FASTFLOAT_CONSTEXPR20
from_chars_result from_chars(const char *first, const char *last,
T &value, chars_format fmt /*= chars_format::general*/) noexcept {
return from_chars_advanced(first, last, value, parse_options{fmt});
}
template<typename T>
+FASTFLOAT_CONSTEXPR20
from_chars_result from_chars_advanced(const char *first, const char *last,
T &value, parse_options options) noexcept {
@@ -174,7 +177,7 @@ from_chars_result from_chars_advanced(const char *first, const char *last,
// We could check it first (before the previous branch), but
// there might be performance advantages at having the check
// be last.
- if(detail::rounds_to_nearest()) {
+ if(!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
// We have that fegetround() == FE_TONEAREST.
// Next is Clinger's fast path.
if (pns.mantissa <=binary_format<T>::max_mantissa_fast_path()) {
@@ -191,7 +194,7 @@ from_chars_result from_chars_advanced(const char *first, const char *last,
#if defined(__clang__)
// Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD
if(pns.mantissa == 0) {
- value = 0;
+ value = pns.negative ? -0. : 0.;
return answer;
}
#endif