Skip to content

Commit d07362c

Browse files
committed
Final review for a more simple merge.
Feature FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED is removed because hex and bin parsing isn't working properly. Properly use FASTFLOAT_SIMD_DISABLE_WARNINGS and FASTFLOAT_SIMD_RESTORE_WARNINGS only for instructions that allow unaligned loads.
1 parent cdabfe4 commit d07362c

File tree

8 files changed

+67
-57
lines changed

8 files changed

+67
-57
lines changed

include/fast_float/ascii_number.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ fastfloat_really_inline uint64_t simd_read8_to_u64(__m128i const &data) {
8484
}
8585

8686
fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
87-
return simd_read8_to_u64(_mm_loadu_si128(reinterpret_cast<__m128i const *>(
88-
chars))); // TODO: V1032 https://pvs-studio.com/en/docs/warnings/v1032/
89-
// The pointer 'chars' is cast to a more strictly aligned
90-
// pointer type.
87+
FASTFLOAT_SIMD_DISABLE_WARNINGS
88+
return simd_read8_to_u64(
89+
_mm_loadu_si128(reinterpret_cast<__m128i const *>(chars)));
90+
FASTFLOAT_SIMD_RESTORE_WARNINGS
9191
}
9292

9393
#elif defined(FASTFLOAT_NEON)
@@ -98,8 +98,10 @@ fastfloat_really_inline uint64_t simd_read8_to_u64(uint16x8_t const &data) {
9898
}
9999

100100
fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
101+
FASTFLOAT_SIMD_DISABLE_WARNINGS
101102
return simd_read8_to_u64(
102103
vld1q_u16(reinterpret_cast<uint16_t const *>(chars)));
104+
FASTFLOAT_SIMD_RESTORE_WARNINGS
103105
}
104106

105107
#endif
@@ -118,9 +120,9 @@ uint64_t simd_read8_to_u64(UC const *) {
118120
// credit @aqrit
119121
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint32_t
120122
parse_eight_digits_unrolled(uint64_t val) noexcept {
121-
constexpr uint64_t mask = 0x000000FF000000FF;
122-
constexpr uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
123-
constexpr uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
123+
uint64_t const mask = 0x000000FF000000FF;
124+
uint64_t const mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
125+
uint64_t const mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
124126
val -= 0x3030303030303030;
125127
val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8;
126128
val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32;
@@ -156,11 +158,11 @@ simd_parse_if_eight_digits_unrolled(char16_t const *chars,
156158
return false;
157159
}
158160
#ifdef FASTFLOAT_SSE2
161+
FASTFLOAT_SIMD_DISABLE_WARNINGS
159162
// Load 8 UTF-16 characters (16 bytes)
160-
__m128i const data = _mm_loadu_si128(reinterpret_cast<__m128i const *>(
161-
chars)); // TODO: V1032 https://pvs-studio.com/en/docs/warnings/v1032/ The
162-
// pointer 'chars' is cast to a more strictly aligned pointer
163-
// type.
163+
__m128i const data =
164+
_mm_loadu_si128(reinterpret_cast<__m128i const *>(chars));
165+
FASTFLOAT_SIMD_RESTORE_WARNINGS
164166

165167
// Branchless "are all digits?" trick from Lemire:
166168
// (x - '0') <= 9 <=> (x + 32720) <= 32729
@@ -175,7 +177,9 @@ simd_parse_if_eight_digits_unrolled(char16_t const *chars,
175177
return true;
176178
}
177179
#elif defined(FASTFLOAT_NEON)
180+
FASTFLOAT_SIMD_DISABLE_WARNINGS
178181
uint16x8_t const data = vld1q_u16(reinterpret_cast<uint16_t const *>(chars));
182+
FASTFLOAT_SIMD_RESTORE_WARNINGS
179183

180184
// (x - '0') <= 9
181185
// http://0x80.pl/articles/simd-parsing-int-sequences.html
@@ -286,7 +290,7 @@ report_parse_error(UC const *p, parse_error error) noexcept {
286290
template <bool basic_json_fmt, typename UC>
287291
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
288292
parse_number_string(UC const *p, UC const *pend,
289-
parse_options_t<UC> const &options) noexcept {
293+
parse_options_t<UC> const options) noexcept {
290294
// Cyclomatic complexity https://en.wikipedia.org/wiki/Cyclomatic_complexity
291295
// Consider refactoring the 'parse_number_string' function.
292296
// FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN fix this.
@@ -295,8 +299,8 @@ parse_number_string(UC const *p, UC const *pend,
295299
FASTFLOAT_ASSUME(p < pend);
296300
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
297301
answer.negative = (*p == UC('-'));
302+
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
298303
if (answer.negative ||
299-
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
300304
((chars_format_t(options.format & chars_format::allow_leading_plus)) &&
301305
(!basic_json_fmt && *p == UC('+')))) {
302306
++p;
@@ -400,8 +404,11 @@ parse_number_string(UC const *p, UC const *pend,
400404
#ifdef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
401405
++p;
402406
#else
403-
if ((UC('e') == *p) || (UC('E') == *p) || (UC('d') == *p) ||
404-
(UC('D') == *p)) {
407+
if ((UC('e') == *p) || (UC('E') == *p)
408+
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
409+
|| (UC('d') == *p) || (UC('D') == *p)
410+
#endif
411+
) {
405412
++p;
406413
}
407414
#endif
@@ -483,8 +490,8 @@ parse_number_string(UC const *p, UC const *pend,
483490
p = answer.integer.ptr;
484491
UC const *int_end = p + answer.integer.len();
485492
constexpr am_mant_t minimal_nineteen_digit_integer{1000000000000000000};
486-
while ((answer.mantissa < minimal_nineteen_digit_integer) &&
487-
(p != int_end)) {
493+
while ((p != int_end) &&
494+
(answer.mantissa < minimal_nineteen_digit_integer)) {
488495
answer.mantissa = static_cast<am_mant_t>(
489496
answer.mantissa * 10 + static_cast<am_mant_t>(*p - UC('0')));
490497
++p;
@@ -496,8 +503,8 @@ parse_number_string(UC const *p, UC const *pend,
496503
// We have a value with a significant fractional component.
497504
p = answer.fraction.ptr;
498505
UC const *const frac_end = p + answer.fraction.len();
499-
while ((answer.mantissa < minimal_nineteen_digit_integer) &&
500-
(p != frac_end)) {
506+
while ((p != frac_end) &&
507+
(answer.mantissa < minimal_nineteen_digit_integer)) {
501508
answer.mantissa = static_cast<am_mant_t>(
502509
answer.mantissa * 10 + static_cast<am_mant_t>(*p - UC('0')));
503510
++p;
@@ -514,7 +521,7 @@ parse_number_string(UC const *p, UC const *pend,
514521
template <typename T, typename UC>
515522
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
516523
parse_int_string(UC const *p, UC const *pend, T &value,
517-
parse_options_t<UC> const &options) noexcept {
524+
parse_options_t<UC> const options) noexcept {
518525

519526
from_chars_result_t<UC> answer;
520527

@@ -645,14 +652,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
645652
loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible
646653
}
647654
while (p != pend) {
648-
#ifdef FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
649-
const auto digit = *p;
650-
if (!is_integer(digit)) {
651-
break;
652-
}
653-
#else
654655
auto const digit = ch_to_digit(*p);
655-
#endif
656656
if (digit >= options.base) {
657657
break;
658658
}

include/fast_float/bigint.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ template <limb_t size>
281281
inline FASTFLOAT_CONSTEXPR20 bool small_mul(stackvec<size> &vec,
282282
limb y) noexcept {
283283
limb carry = 0;
284-
for (limb_t index = 0; index++ != vec.len();) {
284+
for (limb_t index = 0; index != vec.len(); ++index) {
285285
vec[index] = scalar_mul(vec[index], y, carry);
286286
}
287287
if (carry != 0) {
@@ -302,7 +302,7 @@ FASTFLOAT_CONSTEXPR20 bool large_add_from(stackvec<size> &x, limb_span y,
302302
}
303303

304304
bool carry = false;
305-
for (limb_t index = 0; index++ != y.len();) {
305+
for (limb_t index = 0; index != y.len(); ++index) {
306306
limb xi = x[index + start];
307307
limb yi = y[index];
308308
bool c1 = false;
@@ -487,7 +487,7 @@ struct bigint : pow5_tables<> {
487487
} else if (vec.len() < other.vec.len()) {
488488
return -1;
489489
} else {
490-
for (limb_t index = vec.len(); index-- != 0;) {
490+
for (limb_t index = vec.len(); index != 0; --index) {
491491
limb xi = vec[index - 1];
492492
limb yi = other.vec[index - 1];
493493
if (xi > yi) {
@@ -514,7 +514,7 @@ struct bigint : pow5_tables<> {
514514
bigint_bits_t const shl = n;
515515
bigint_bits_t const shr = limb_bits - shl;
516516
limb prev = 0;
517-
for (limb_t index = 0; index++ != vec.len();) {
517+
for (limb_t index = 0; index != vec.len(); ++index) {
518518
limb xi = vec[index];
519519
vec[index] = (xi << shl) | (prev >> shr);
520520
prev = xi;

include/fast_float/decimal_to_binary.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ compute_float(int64_t q, uint64_t w) noexcept {
139139
// branchless approach: value128 product = compute_product(q, w); but in
140140
// practice, we can win big with the compute_product_approximation if its
141141
// additional branch is easily predicted. Which is best is data specific.
142-
limb_t const upperbit = limb_t(product.high >> 63);
143-
limb_t const shift =
142+
auto const upperbit = limb_t(product.high >> 63);
143+
auto const shift =
144144
limb_t(upperbit + 64 - binary::mantissa_explicit_bits() - 3);
145145

146146
answer.mantissa = product.high >> shift;

include/fast_float/digit_comparison.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,18 @@ scientific_exponent(am_mant_t mantissa, am_pow_t exponent) noexcept {
5858
// this converts a native floating-point number to an extended-precision float.
5959
template <typename T>
6060
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
61-
to_extended(T const &value) noexcept {
61+
to_extended(T const value) noexcept {
6262
using equiv_uint = equiv_uint_t<T>;
6363
constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
6464
constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
6565
constexpr equiv_uint hidden_bit_mask = binary_format<T>::hidden_bit_mask();
6666

67+
adjusted_mantissa am;
6768
constexpr am_pow_t bias = binary_format<T>::mantissa_explicit_bits() -
6869
binary_format<T>::minimum_exponent();
6970

7071
equiv_uint const bits = bit_cast<equiv_uint, T>(value);
7172

72-
adjusted_mantissa am;
7373
if ((bits & exponent_mask) == 0) {
7474
// denormal
7575
am.power2 = 1 - bias;
@@ -90,7 +90,7 @@ to_extended(T const &value) noexcept {
9090
// halfway between b and b+u.
9191
template <typename T>
9292
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
93-
to_extended_halfway(T const &value) noexcept {
93+
to_extended_halfway(T const value) noexcept {
9494
adjusted_mantissa am = to_extended(value);
9595
am.mantissa <<= 1;
9696
am.mantissa += 1;
@@ -253,7 +253,7 @@ round_up_bigint(bigint &big, am_digits &count) noexcept {
253253

254254
// parse the significant digits into a big integer
255255
template <typename T, typename UC>
256-
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 am_digits
256+
inline FASTFLOAT_CONSTEXPR20 am_digits
257257
parse_mantissa(bigint &result, const parsed_number_string_t<UC> &num) noexcept {
258258
// try to minimize the number of big integer and scalar multiplication.
259259
// therefore, try to parse 8 digits at a time, and multiply by the largest
@@ -369,8 +369,7 @@ template <typename T>
369369
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
370370
negative_digit_comp(bigint &real_digits, adjusted_mantissa am,
371371
am_pow_t const real_exp) noexcept {
372-
// get the value of `b`, rounded down, and get a bigint representation of
373-
// b+h
372+
// get the value of `b`, rounded down, and get a bigint representation of b+h
374373
adjusted_mantissa am_b = am;
375374
// gcc7 bug: use a lambda to remove the noexcept qualifier bug with
376375
// -Wnoexcept-type.

include/fast_float/fast_float.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ from_chars(UC const *first, UC const *last, T &value,
4343
template <typename T, typename UC = char>
4444
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
4545
from_chars_advanced(UC const *first, UC const *last, T &value,
46-
parse_options_t<UC> const &options) noexcept;
46+
parse_options_t<UC> const options) noexcept;
4747

4848
/**
4949
* This function multiplies an integer number by a power of 10 and returns

include/fast_float/fast_table.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#ifndef FASTFLOAT_FAST_TABLE_H
22
#define FASTFLOAT_FAST_TABLE_H
33

4-
#include <cstdint>
5-
64
namespace fast_float {
75

86
/**

include/fast_float/float_common.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,21 @@ FASTFLOAT_CONSTEXPR20 To bit_cast(const From &from) {
205205
#define FASTFLOAT_HAS_SIMD 1
206206
#endif
207207

208+
#if defined(__GNUC__)
209+
// disable -Wcast-align=strict (GCC only)
210+
#define FASTFLOAT_SIMD_DISABLE_WARNINGS \
211+
_Pragma("GCC diagnostic push") \
212+
_Pragma("GCC diagnostic ignored \"-Wcast-align\"")
213+
#else
214+
#define FASTFLOAT_SIMD_DISABLE_WARNINGS
215+
#endif
216+
217+
#if defined(__GNUC__)
218+
#define FASTFLOAT_SIMD_RESTORE_WARNINGS _Pragma("GCC diagnostic pop")
219+
#else
220+
#define FASTFLOAT_SIMD_RESTORE_WARNINGS
221+
#endif
222+
208223
#ifdef FASTFLOAT_VISUAL_STUDIO
209224
#define fastfloat_really_inline __forceinline
210225
#else
@@ -288,7 +303,7 @@ template <typename UC>
288303
inline FASTFLOAT_CONSTEXPR14 bool
289304
fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase,
290305
uint_fast8_t const length) noexcept {
291-
for (uint_fast8_t i = 0; i++ != length;) {
306+
for (uint_fast8_t i = 0; i != length; ++i) {
292307
UC const actual = actual_mixedcase[i];
293308
if ((actual < 256 ? actual | 32 : actual) != expected_lowercase[i]) {
294309
return false;
@@ -450,8 +465,10 @@ umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) noexcept {
450465

451466
// slow emulation routine for 32-bit
452467
#if !defined(__MINGW64__)
453-
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t
454-
_umul128(uint64_t ab, uint64_t cd, uint64_t *hi) noexcept {
468+
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t_umul128(uint64_t ab,
469+
uint64_t cd,
470+
uint64_t *hi)
471+
noexcept {
455472
return umul128_generic(ab, cd, hi);
456473
}
457474
#endif // !__MINGW64__
@@ -1186,7 +1203,6 @@ template <> constexpr char8_t const *str_const_inf<char8_t>() {
11861203
#endif
11871204

11881205
template <typename = void> struct int_luts {
1189-
#ifndef FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
11901206
static constexpr uint8_t chdigit[] = {
11911207
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
11921208
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
@@ -1206,7 +1222,6 @@ template <typename = void> struct int_luts {
12061222
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
12071223
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
12081224
255};
1209-
#endif
12101225

12111226
static constexpr uint_fast8_t maxdigits_u64[] = {
12121227
64, 41, 32, 28, 25, 23, 22, 21, 20, 19, 18, 18, 17, 17, 16, 16, 16, 16,
@@ -1237,7 +1252,6 @@ template <typename T> constexpr uint64_t int_luts<T>::min_safe_u64[];
12371252

12381253
#endif
12391254

1240-
#ifndef FASTFLOAT_TABLE_HACK_CHAR_DIGIT_LUT_DISABLED
12411255
template <typename UC>
12421256
fastfloat_really_inline constexpr uint_fast8_t ch_to_digit(UC c) noexcept {
12431257
// wchar_t and char can be signed, so we need to be careful.
@@ -1247,7 +1261,6 @@ fastfloat_really_inline constexpr uint_fast8_t ch_to_digit(UC c) noexcept {
12471261
static_cast<UnsignedUC>(
12481262
-((static_cast<UnsignedUC>(c) & ~0xFFull) == 0)))];
12491263
}
1250-
#endif
12511264

12521265
fastfloat_really_inline constexpr uint_fast8_t
12531266
max_digits_u64(uint_fast8_t base) noexcept {

0 commit comments

Comments
 (0)