Skip to content

Commit 21d4ce1

Browse files
committed
Fixes for FASTFLOAT_IS_BIG_ENDIAN after PR fastfloat#359 is added to original.
1 parent 299c274 commit 21d4ce1

File tree

1 file changed

+21
-29
lines changed

1 file changed

+21
-29
lines changed

include/fast_float/ascii_number.h

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
544544

545545
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
546546
// Read sign
547-
bool const negative = (*p == UC('-'));
547+
auto const negative = (*p == UC('-'));
548548
#ifdef FASTFLOAT_VISUAL_STUDIO
549549
#pragma warning(push)
550550
#pragma warning(disable : 4127)
@@ -557,7 +557,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
557557
answer.ptr = first;
558558
return answer;
559559
}
560-
if ((*p == UC('-')) ||
560+
if (negative ||
561561
((chars_format_t(options.format & chars_format::allow_leading_plus)) &&
562562
(*p == UC('+')))) {
563563
++p;
@@ -571,7 +571,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
571571
++p;
572572
}
573573

574-
bool const has_leading_zeros = p > start_num;
574+
auto const has_leading_zeros = p > start_num;
575575

576576
auto const *const start_digits = p;
577577

@@ -592,53 +592,43 @@ parse_int_string(UC const *p, UC const *pend, T &value,
592592

593593
uint32_t digits;
594594

595-
#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST
596-
if (std::is_constant_evaluated()) {
595+
if (cpp20_and_in_constexpr()) {
597596
uint8_t str[sizeof(uint32_t)];
598597
for (uint_fast8_t j = 0; j != sizeof(uint32_t) && j != len; ++j) {
599598
str[j] = static_cast<uint8_t>(p[j]);
600599
}
601600
digits = bit_cast<uint32_t>(str);
602-
#if FASTFLOAT_IS_BIG_ENDIAN
603-
digits = byteswap(digits);
604-
#endif
605-
}
606-
#else
607-
if (false) {
608-
}
609-
#endif
610-
else if (len >= 4) {
611-
::memcpy(&digits, p, 4);
612-
#if FASTFLOAT_IS_BIG_ENDIAN
613-
digits = byteswap(digits);
614-
#endif
615601
} else {
616602
uint32_t b0 = static_cast<uint8_t>(p[0]);
617603
uint32_t b1 = (len > 1) ? static_cast<uint8_t>(p[1]) : 0xFFu;
618604
uint32_t b2 = (len > 2) ? static_cast<uint8_t>(p[2]) : 0xFFu;
619605
uint32_t b3 = 0xFFu;
620606
digits = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);
621607
}
608+
#if FASTFLOAT_IS_BIG_ENDIAN
609+
digits = byteswap(digits);
610+
#endif
622611

623-
uint32_t magic =
612+
uint32_t const magic =
624613
((digits + 0x46464646u) | (digits - 0x30303030u)) & 0x80808080u;
625-
uint32_t tz = (uint32_t)countr_zero_32(magic); // 7, 15, 23, 31, or 32
626-
uint32_t nd = (tz == 32) ? 4 : (tz >> 3);
614+
auto const tz = countr_zero_32(magic); // 7, 15, 23, 31, or 32
615+
auto nd = am_digits(tz >> 3);
627616
nd = std::min(nd, len);
628617
if (nd == 0) {
629618
if (has_leading_zeros) {
630619
value = 0;
631620
answer.ec = std::errc();
632621
answer.ptr = p;
633622
return answer;
623+
} else {
624+
answer.ec = std::errc::invalid_argument;
625+
answer.ptr = first;
634626
}
635-
answer.ec = std::errc::invalid_argument;
636-
answer.ptr = first;
637627
return answer;
638628
}
639629
if (nd > 3) {
640630
const UC *q = p + nd;
641-
size_t rem = len - nd;
631+
auto rem = len - nd;
642632
while (rem) {
643633
if (*q < UC('0') || *q > UC('9'))
644634
break;
@@ -653,14 +643,15 @@ parse_int_string(UC const *p, UC const *pend, T &value,
653643
digits ^= 0x30303030u;
654644
digits <<= ((4 - nd) * 8);
655645

656-
uint32_t check = ((digits >> 24) & 0xff) | ((digits >> 8) & 0xff00) |
657-
((digits << 8) & 0xff0000);
646+
uint32_t const check = ((digits >> 24) & 0xff) |
647+
((digits >> 8) & 0xff00) |
648+
((digits << 8) & 0xff0000);
658649
if (check > 0x00020505) {
659650
answer.ec = std::errc::result_out_of_range;
660651
answer.ptr = p + nd;
661652
return answer;
662653
}
663-
value = (uint8_t)((0x640a01 * digits) >> 24);
654+
value = static_cast<uint8_t>((0x640a01 * digits) >> 24);
664655
answer.ec = std::errc();
665656
answer.ptr = p + nd;
666657
return answer;
@@ -682,7 +673,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
682673
return answer;
683674
}
684675

685-
if (len >= sizeof(uint32_t)) {
676+
if (len >= std::numeric_limits<uint16_t>::digits10) {
686677
auto digits = read_chars_to_unsigned<uint32_t>(p);
687678
if (is_made_of_four_digits_fast(digits)) {
688679
auto v = parse_four_digits_unrolled(digits);
@@ -692,7 +683,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
692683
answer.ec = std::errc::result_out_of_range;
693684
const auto *q = p + 5;
694685
while (q != pend && is_integer(*q)) {
695-
q++;
686+
++q;
696687
}
697688
answer.ptr = q;
698689
return answer;
@@ -779,6 +770,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
779770
#ifdef FASTFLOAT_VISUAL_STUDIO
780771
#pragma warning(push)
781772
#pragma warning(disable : 4146)
773+
#pragma warning(disable : 4804)
782774
#endif
783775
// this weird workaround is required because:
784776
// - converting unsigned to signed when its value is greater than signed max

0 commit comments

Comments
 (0)