Skip to content

Commit 8585201

Browse files
authored
Update fast_float to 8.2.1 (axmolengine#2995)
1 parent d596e4e commit 8585201

File tree

6 files changed

+216
-24
lines changed

6 files changed

+216
-24
lines changed

3rdparty/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757

5858
## fast_float
5959
- [![Upstream](https://img.shields.io/github/v/release/fastfloat/fast_float?label=Upstream)](https://github.com/fastfloat/fast_float)
60-
- Version: 8.1.0
60+
- Version: 8.2.1
6161
- License: MIT
6262

6363
## flatbuffers

3rdparty/fast_float/ascii_number.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,100 @@ parse_int_string(UC const *p, UC const *pend, T &value,
509509

510510
UC const *const start_digits = p;
511511

512+
FASTFLOAT_IF_CONSTEXPR17((std::is_same<T, std::uint8_t>::value)) {
513+
const size_t len = (size_t)(pend - p);
514+
if (len == 0) {
515+
if (has_leading_zeros) {
516+
value = 0;
517+
answer.ec = std::errc();
518+
answer.ptr = p;
519+
} else {
520+
answer.ec = std::errc::invalid_argument;
521+
answer.ptr = first;
522+
}
523+
return answer;
524+
}
525+
526+
uint32_t digits;
527+
528+
#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST
529+
if (std::is_constant_evaluated()) {
530+
uint8_t str[4]{};
531+
for (size_t j = 0; j < 4 && j < len; ++j) {
532+
str[j] = static_cast<uint8_t>(p[j]);
533+
}
534+
digits = std::bit_cast<uint32_t>(str);
535+
#if FASTFLOAT_IS_BIG_ENDIAN
536+
digits = byteswap(digits);
537+
#endif
538+
}
539+
#else
540+
if (false) {
541+
}
542+
#endif
543+
else if (len >= 4) {
544+
::memcpy(&digits, p, 4);
545+
#if FASTFLOAT_IS_BIG_ENDIAN
546+
digits = byteswap(digits);
547+
#endif
548+
} else {
549+
uint32_t b0 = static_cast<uint8_t>(p[0]);
550+
uint32_t b1 = (len > 1) ? static_cast<uint8_t>(p[1]) : 0xFFu;
551+
uint32_t b2 = (len > 2) ? static_cast<uint8_t>(p[2]) : 0xFFu;
552+
uint32_t b3 = 0xFFu;
553+
#if FASTFLOAT_IS_BIG_ENDIAN
554+
digits = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
555+
#else
556+
digits = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
557+
#endif
558+
}
559+
560+
uint32_t magic =
561+
((digits + 0x46464646u) | (digits - 0x30303030u)) & 0x80808080u;
562+
uint32_t tz = (uint32_t)countr_zero_32(magic); // 7, 15, 23, 31, or 32
563+
uint32_t nd = (tz == 32) ? 4 : (tz >> 3);
564+
nd = (uint32_t)std::min((size_t)nd, len);
565+
if (nd == 0) {
566+
if (has_leading_zeros) {
567+
value = 0;
568+
answer.ec = std::errc();
569+
answer.ptr = p;
570+
return answer;
571+
}
572+
answer.ec = std::errc::invalid_argument;
573+
answer.ptr = first;
574+
return answer;
575+
}
576+
if (nd > 3) {
577+
const UC *q = p + nd;
578+
size_t rem = len - nd;
579+
while (rem) {
580+
if (*q < UC('0') || *q > UC('9'))
581+
break;
582+
++q;
583+
--rem;
584+
}
585+
answer.ec = std::errc::result_out_of_range;
586+
answer.ptr = q;
587+
return answer;
588+
}
589+
590+
digits ^= 0x30303030u;
591+
digits <<= ((4 - nd) * 8);
592+
593+
uint32_t check = ((digits >> 24) & 0xff) | ((digits >> 8) & 0xff00) |
594+
((digits << 8) & 0xff0000);
595+
if (check > 0x00020505) {
596+
answer.ec = std::errc::result_out_of_range;
597+
answer.ptr = p + nd;
598+
return answer;
599+
}
600+
value = (uint8_t)((0x640a01 * digits) >> 24);
601+
answer.ec = std::errc();
602+
answer.ptr = p + nd;
603+
return answer;
604+
}
605+
512606
uint64_t i = 0;
513607
if (base == 10) {
514608
loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible

3rdparty/fast_float/digit_comparison.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,8 @@ constexpr static uint64_t powers_of_ten_uint64[] = {1UL,
3838
// this algorithm is not even close to optimized, but it has no practical
3939
// effect on performance: in order to have a faster algorithm, we'd need
4040
// to slow down performance for faster algorithms, and this is still fast.
41-
template <typename UC>
4241
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int32_t
43-
scientific_exponent(parsed_number_string_t<UC> &num) noexcept {
44-
uint64_t mantissa = num.mantissa;
45-
int32_t exponent = int32_t(num.exponent);
42+
scientific_exponent(uint64_t mantissa, int32_t exponent) noexcept {
4643
while (mantissa >= 10000) {
4744
mantissa /= 10000;
4845
exponent += 4;
@@ -398,7 +395,7 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp(
398395
FASTFLOAT_ASSERT(real_digits.pow2(uint32_t(-pow2_exp)));
399396
}
400397

401-
// compare digits, and use it to director rounding
398+
// compare digits, and use it to direct rounding
402399
int ord = real_digits.compare(theor_digits);
403400
adjusted_mantissa answer = am;
404401
round<T>(answer, [ord](adjusted_mantissa &a, int32_t shift) {
@@ -419,7 +416,7 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp(
419416
return answer;
420417
}
421418

422-
// parse the significant digits as a big integer to unambiguously round the
419+
// parse the significant digits as a big integer to unambiguously round
423420
// the significant digits. here, we are trying to determine how to round
424421
// an extended float representation close to `b+h`, halfway between `b`
425422
// (the float rounded-down) and `b+u`, the next positive float. this
@@ -438,7 +435,8 @@ digit_comp(parsed_number_string_t<UC> &num, adjusted_mantissa am) noexcept {
438435
// remove the invalid exponent bias
439436
am.power2 -= invalid_am_bias;
440437

441-
int32_t sci_exp = scientific_exponent(num);
438+
int32_t sci_exp =
439+
scientific_exponent(num.mantissa, static_cast<int32_t>(num.exponent));
442440
size_t max_digits = binary_format<T>::max_digits();
443441
size_t digits = 0;
444442
bigint bigmant;

3rdparty/fast_float/fast_float.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,20 @@ integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept;
6363
FASTFLOAT_CONSTEXPR20 inline double
6464
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept;
6565

66+
/**
67+
* This function is a template overload of `integer_times_pow10()`
68+
* that returns a floating-point value of type `T` that is one of
69+
* supported floating-point types (e.g. `double`, `float`).
70+
*/
71+
template <typename T>
72+
FASTFLOAT_CONSTEXPR20
73+
typename std::enable_if<is_supported_float_type<T>::value, T>::type
74+
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept;
75+
template <typename T>
76+
FASTFLOAT_CONSTEXPR20
77+
typename std::enable_if<is_supported_float_type<T>::value, T>::type
78+
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept;
79+
6680
/**
6781
* from_chars for integer types.
6882
*/

3rdparty/fast_float/float_common.h

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
#include "constexpr_feature_detect.h"
1717

1818
#define FASTFLOAT_VERSION_MAJOR 8
19-
#define FASTFLOAT_VERSION_MINOR 1
20-
#define FASTFLOAT_VERSION_PATCH 0
19+
#define FASTFLOAT_VERSION_MINOR 2
20+
#define FASTFLOAT_VERSION_PATCH 1
2121

2222
#define FASTFLOAT_STRINGIZE_IMPL(x) #x
2323
#define FASTFLOAT_STRINGIZE(x) FASTFLOAT_STRINGIZE_IMPL(x)
@@ -362,6 +362,52 @@ leading_zeroes(uint64_t input_num) {
362362
#endif
363363
}
364364

365+
/* Helper C++14 constexpr generic implementation of countr_zero for 32-bit */
366+
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int
367+
countr_zero_generic_32(uint32_t input_num) {
368+
if (input_num == 0) {
369+
return 32;
370+
}
371+
int last_bit = 0;
372+
if (!(input_num & 0x0000FFFF)) {
373+
input_num >>= 16;
374+
last_bit |= 16;
375+
}
376+
if (!(input_num & 0x00FF)) {
377+
input_num >>= 8;
378+
last_bit |= 8;
379+
}
380+
if (!(input_num & 0x0F)) {
381+
input_num >>= 4;
382+
last_bit |= 4;
383+
}
384+
if (!(input_num & 0x3)) {
385+
input_num >>= 2;
386+
last_bit |= 2;
387+
}
388+
if (!(input_num & 0x1)) {
389+
last_bit |= 1;
390+
}
391+
return last_bit;
392+
}
393+
394+
/* count trailing zeroes for 32-bit integers */
395+
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 int
396+
countr_zero_32(uint32_t input_num) {
397+
if (cpp20_and_in_constexpr()) {
398+
return countr_zero_generic_32(input_num);
399+
}
400+
#ifdef FASTFLOAT_VISUAL_STUDIO
401+
unsigned long trailing_zero = 0;
402+
if (_BitScanForward(&trailing_zero, input_num)) {
403+
return (int)trailing_zero;
404+
}
405+
return 32;
406+
#else
407+
return input_num == 0 ? 32 : __builtin_ctz(input_num);
408+
#endif
409+
}
410+
365411
// slow emulation routine for 32-bit
366412
fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) {
367413
return x * (uint64_t)y;
@@ -406,8 +452,8 @@ full_multiplication(uint64_t a, uint64_t b) {
406452
// But MinGW on ARM64 doesn't have native support for 64-bit multiplications
407453
answer.high = __umulh(a, b);
408454
answer.low = a * b;
409-
#elif defined(FASTFLOAT_32BIT) || \
410-
(defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64))
455+
#elif defined(FASTFLOAT_32BIT) || (defined(_WIN64) && !defined(__clang__) && \
456+
!defined(_M_ARM64) && !defined(__GNUC__))
411457
answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64
412458
#elif defined(FASTFLOAT_64BIT) && defined(__SIZEOF_INT128__)
413459
__uint128_t r = ((__uint128_t)a) * b;
@@ -1166,6 +1212,9 @@ static_assert(std::is_same<equiv_uint_t<std::float64_t>, uint64_t>::value,
11661212
static_assert(
11671213
std::numeric_limits<std::float64_t>::is_iec559,
11681214
"std::float64_t must fulfill the requirements of IEC 559 (IEEE 754)");
1215+
1216+
template <>
1217+
struct binary_format<std::float64_t> : public binary_format<double> {};
11691218
#endif // __STDCPP_FLOAT64_T__
11701219

11711220
#ifdef __STDCPP_FLOAT32_T__
@@ -1174,6 +1223,9 @@ static_assert(std::is_same<equiv_uint_t<std::float32_t>, uint32_t>::value,
11741223
static_assert(
11751224
std::numeric_limits<std::float32_t>::is_iec559,
11761225
"std::float32_t must fulfill the requirements of IEC 559 (IEEE 754)");
1226+
1227+
template <>
1228+
struct binary_format<std::float32_t> : public binary_format<float> {};
11771229
#endif // __STDCPP_FLOAT32_T__
11781230

11791231
#ifdef __STDCPP_FLOAT16_T__
@@ -1245,7 +1297,6 @@ constexpr chars_format adjust_for_feature_macros(chars_format fmt) {
12451297
;
12461298
}
12471299
} // namespace detail
1248-
12491300
} // namespace fast_float
12501301

12511302
#endif

3rdparty/fast_float/parse_number.h

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -344,44 +344,79 @@ from_chars(UC const *first, UC const *last, T &value, int base) noexcept {
344344
return from_chars_advanced(first, last, value, options);
345345
}
346346

347-
FASTFLOAT_CONSTEXPR20 inline double
348-
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
349-
double value;
347+
template <typename T>
348+
FASTFLOAT_CONSTEXPR20
349+
typename std::enable_if<is_supported_float_type<T>::value, T>::type
350+
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
351+
T value;
350352
if (clinger_fast_path_impl(mantissa, decimal_exponent, false, value))
351353
return value;
352354

353355
adjusted_mantissa am =
354-
compute_float<binary_format<double>>(decimal_exponent, mantissa);
356+
compute_float<binary_format<T>>(decimal_exponent, mantissa);
355357
to_float(false, am, value);
356358
return value;
357359
}
358360

359-
FASTFLOAT_CONSTEXPR20 inline double
360-
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
361+
template <typename T>
362+
FASTFLOAT_CONSTEXPR20
363+
typename std::enable_if<is_supported_float_type<T>::value, T>::type
364+
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
361365
const bool is_negative = mantissa < 0;
362366
const uint64_t m = static_cast<uint64_t>(is_negative ? -mantissa : mantissa);
363367

364-
double value;
368+
T value;
365369
if (clinger_fast_path_impl(m, decimal_exponent, is_negative, value))
366370
return value;
367371

368-
adjusted_mantissa am =
369-
compute_float<binary_format<double>>(decimal_exponent, m);
372+
adjusted_mantissa am = compute_float<binary_format<T>>(decimal_exponent, m);
370373
to_float(is_negative, am, value);
371374
return value;
372375
}
373376

377+
FASTFLOAT_CONSTEXPR20 inline double
378+
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
379+
return integer_times_pow10<double>(mantissa, decimal_exponent);
380+
}
381+
382+
FASTFLOAT_CONSTEXPR20 inline double
383+
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
384+
return integer_times_pow10<double>(mantissa, decimal_exponent);
385+
}
386+
374387
// the following overloads are here to avoid surprising ambiguity for int,
375388
// unsigned, etc.
389+
template <typename T, typename Int>
390+
FASTFLOAT_CONSTEXPR20
391+
typename std::enable_if<is_supported_float_type<T>::value &&
392+
std::is_integral<Int>::value &&
393+
!std::is_signed<Int>::value,
394+
T>::type
395+
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
396+
return integer_times_pow10<T>(static_cast<uint64_t>(mantissa),
397+
decimal_exponent);
398+
}
399+
400+
template <typename T, typename Int>
401+
FASTFLOAT_CONSTEXPR20
402+
typename std::enable_if<is_supported_float_type<T>::value &&
403+
std::is_integral<Int>::value &&
404+
std::is_signed<Int>::value,
405+
T>::type
406+
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
407+
return integer_times_pow10<T>(static_cast<int64_t>(mantissa),
408+
decimal_exponent);
409+
}
410+
376411
template <typename Int>
377-
FASTFLOAT_CONSTEXPR20 inline typename std::enable_if<
412+
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
378413
std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type
379414
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
380415
return integer_times_pow10(static_cast<uint64_t>(mantissa), decimal_exponent);
381416
}
382417

383418
template <typename Int>
384-
FASTFLOAT_CONSTEXPR20 inline typename std::enable_if<
419+
FASTFLOAT_CONSTEXPR20 typename std::enable_if<
385420
std::is_integral<Int>::value && std::is_signed<Int>::value, double>::type
386421
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
387422
return integer_times_pow10(static_cast<int64_t>(mantissa), decimal_exponent);

0 commit comments

Comments
 (0)