@@ -41,51 +41,32 @@ fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) noexcept {
4141 (val & 0x000000000000FF00 ) << 40 | (val & 0x00000000000000FF ) << 56 ;
4242}
4343
44- fastfloat_really_inline constexpr uint32_t byteswap_32 (uint32_t val) {
44+ fastfloat_really_inline constexpr uint32_t byteswap (uint32_t val) noexcept {
4545 return (val >> 24 ) | ((val >> 8 ) & 0x0000FF00u ) | ((val << 8 ) & 0x00FF0000u ) |
4646 (val << 24 );
4747}
4848
49- // Read 8 UC into a u64 . Truncates UC if not char.
50- template <typename UC>
51- fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
52- read8_to_u64 (UC const *chars) noexcept {
49+ // Read UCs into an unsigned integer . Truncates UC if not char.
50+ template <typename T, typename UC>
51+ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 T
52+ read_chars_to_unsigned (UC const *chars) noexcept {
5353 if (cpp20_and_in_constexpr () || !std::is_same<UC, char >::value) {
54- uint64_t val = 0 ;
55- for (uint_fast8_t i = 0 ; i != 8 ; ++i) {
56- val |= uint64_t (uint8_t (*chars)) << (i * 8 );
54+ T val = 0 ;
55+ for (uint_fast8_t i = 0 ; i != sizeof (T) ; ++i) {
56+ val |= T (uint8_t (*chars)) << (i * 8 );
5757 ++chars;
5858 }
5959 return val;
6060 }
61- uint64_t val;
62- ::memcpy (&val, chars, sizeof (uint64_t ));
61+ T val;
62+ ::memcpy (&val, chars, sizeof (T ));
6363#if FASTFLOAT_IS_BIG_ENDIAN == 1
6464 // Need to read as-if the number was in little-endian order.
6565 val = byteswap (val);
6666#endif
6767 return val;
6868}
6969
70- // Read 4 UC into a u32. Truncates UC if not char.
71- template <typename UC>
72- fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint32_t
73- read4_to_u32 (UC const *chars) {
74- if (cpp20_and_in_constexpr () || !std::is_same<UC, char >::value) {
75- uint32_t val = 0 ;
76- for (int i = 0 ; i < 4 ; ++i) {
77- val |= uint32_t (uint8_t (*chars)) << (i * 8 );
78- ++chars;
79- }
80- return val;
81- }
82- uint32_t val;
83- ::memcpy (&val, chars, sizeof (uint32_t ));
84- #if FASTFLOAT_IS_BIG_ENDIAN == 1
85- val = byteswap_32 (val);
86- #endif
87- return val;
88- }
8970#ifdef FASTFLOAT_SSE2
9071
9172fastfloat_really_inline uint64_t simd_read8_to_u64 (__m128i const &data) {
@@ -122,7 +103,7 @@ fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
122103 FASTFLOAT_SIMD_RESTORE_WARNINGS
123104}
124105
125- #endif
106+ #endif // FASTFLOAT_SSE2
126107
127108// MSVC SFINAE is broken pre-VS2017
128109#if defined(_MSC_VER) && _MSC_VER <= 1900
@@ -152,7 +133,8 @@ template <typename UC>
152133fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint32_t
153134parse_eight_digits_unrolled (UC const *chars) noexcept {
154135 if (cpp20_and_in_constexpr () || !has_simd_opt<UC>()) {
155- return parse_eight_digits_unrolled (read8_to_u64 (chars)); // truncation okay
136+ return parse_eight_digits_unrolled (
137+ read_chars_to_unsigned<uint64_t >(chars)); // truncation okay
156138 }
157139 return parse_eight_digits_unrolled (simd_read8_to_u64 (chars));
158140}
@@ -223,11 +205,11 @@ simd_parse_if_eight_digits_unrolled(char16_t const *chars,
223205#else
224206 (void )chars;
225207 (void )i;
226- #endif
208+ #endif // FASTFLOAT_SSE2
227209 return false ;
228210}
229211
230- #endif
212+ #endif // FASTFLOAT_HAS_SIMD
231213
232214// MSVC SFINAE is broken pre-VS2017
233215#if defined(_MSC_VER) && _MSC_VER <= 1900
@@ -258,9 +240,9 @@ loop_parse_if_eight_digits(char const *&p, char const *const pend,
258240 uint64_t &i) {
259241 // optimizes better than parse_if_eight_digits_unrolled() for UC = char.
260242 while ((std::distance (p, pend) >= 8 ) &&
261- is_made_of_eight_digits_fast (read8_to_u64 (p))) {
243+ is_made_of_eight_digits_fast (read_chars_to_unsigned< uint64_t > (p))) {
262244 i = i * 100000000 +
263- parse_eight_digits_unrolled (read8_to_u64 (
245+ parse_eight_digits_unrolled (read_chars_to_unsigned< uint64_t > (
264246 p)); // in rare cases, this will overflow, but that's ok
265247 p += 8 ;
266248 }
@@ -612,13 +594,13 @@ parse_int_string(UC const *p, UC const *pend, T &value,
612594
613595#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST
614596 if (std::is_constant_evaluated ()) {
615- uint8_t str[4 ];
616- for (uint_fast8_t j = 0 ; j != 4 && j != len; ++j) {
597+ uint8_t str[sizeof ( uint32_t ) ];
598+ for (uint_fast8_t j = 0 ; j != sizeof ( uint32_t ) && j != len; ++j) {
617599 str[j] = static_cast <uint8_t >(p[j]);
618600 }
619601 digits = bit_cast<uint32_t >(str);
620602#if FASTFLOAT_IS_BIG_ENDIAN
621- digits = byteswap_32 (digits);
603+ digits = byteswap (digits);
622604#endif
623605 }
624606#else
@@ -628,7 +610,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
628610 else if (len >= 4 ) {
629611 ::memcpy (&digits, p, 4 );
630612#if FASTFLOAT_IS_BIG_ENDIAN
631- digits = byteswap_32 (digits);
613+ digits = byteswap (digits);
632614#endif
633615 } else {
634616 uint32_t b0 = static_cast <uint8_t >(p[0 ]);
@@ -642,7 +624,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
642624 ((digits + 0x46464646u ) | (digits - 0x30303030u )) & 0x80808080u ;
643625 uint32_t tz = (uint32_t )countr_zero_32 (magic); // 7, 15, 23, 31, or 32
644626 uint32_t nd = (tz == 32 ) ? 4 : (tz >> 3 );
645- nd = ( uint32_t ) std::min (( size_t ) nd, len);
627+ nd = std::min (nd, len);
646628 if (nd == 0 ) {
647629 if (has_leading_zeros) {
648630 value = 0 ;
@@ -687,7 +669,7 @@ parse_int_string(UC const *p, UC const *pend, T &value,
687669
688670 FASTFLOAT_IF_CONSTEXPR17 ((std::is_same<T, std::uint16_t >::value)) {
689671 if (options.base == 10 ) {
690- const size_t len = size_t (pend - p);
672+ const auto len = static_cast <am_digits> (pend - p);
691673 if (len == 0 ) {
692674 if (has_leading_zeros) {
693675 value = 0 ;
@@ -700,22 +682,22 @@ parse_int_string(UC const *p, UC const *pend, T &value,
700682 return answer;
701683 }
702684
703- if (len >= 4 ) {
704- uint32_t digits = read4_to_u32 (p);
685+ if (len >= sizeof ( uint32_t ) ) {
686+ auto digits = read_chars_to_unsigned< uint32_t > (p);
705687 if (is_made_of_four_digits_fast (digits)) {
706- uint32_t v = parse_four_digits_unrolled (digits);
688+ auto v = parse_four_digits_unrolled (digits);
707689 if (len >= 5 && is_integer (p[4 ])) {
708- v = v * 10 + uint32_t (p[4 ] - ' 0' );
690+ v = v * 10 + static_cast < uint32_t > (p[4 ] - ' 0' );
709691 if (len >= 6 && is_integer (p[5 ])) {
710692 answer.ec = std::errc::result_out_of_range;
711- const UC *q = p + 5 ;
693+ const auto *q = p + 5 ;
712694 while (q != pend && is_integer (*q)) {
713695 q++;
714696 }
715697 answer.ptr = q;
716698 return answer;
717699 }
718- if (v > 65535 ) {
700+ if (v > std::numeric_limits< uint16_t >:: max () ) {
719701 answer.ec = std::errc::result_out_of_range;
720702 answer.ptr = p + 5 ;
721703 return answer;
0 commit comments