@@ -574,33 +574,36 @@ parse_int_string(UC const *p, UC const *pend, T &value,
574574 return answer;
575575 }
576576
577- union {
578- uint8_t as_str[4 ];
579- uint32_t as_int;
580- } digits;
577+ uint32_t digits;
581578
582- if (cpp20_and_in_constexpr ()) {
583- digits.as_int = 0 ;
579+ #if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST
580+ if (std::is_constant_evaluated ()) {
581+ uint8_t str[4 ];
584582 for (uint_fast8_t j = 0 ; j < 4 && j < len; ++j) {
585- digits. as_str [j] = static_cast <uint8_t >(p[j]);
583+ str [j] = static_cast <uint8_t >(p[j]);
586584 }
587- } else if (len >= 4 ) {
588- memcpy (&digits.as_int , p, 4 );
585+ digits = bit_cast<uint32_t >(str);
586+ }
587+ #else
588+ if (false ) {
589+ }
590+ #endif
591+ else if (len >= 4 ) {
592+ std::memcpy (&digits, p, 4 );
589593 } else {
590594 uint32_t b0 = static_cast <uint8_t >(p[0 ]);
591595 uint32_t b1 = (len > 1 ) ? static_cast <uint8_t >(p[1 ]) : 0xFFu ;
592596 uint32_t b2 = (len > 2 ) ? static_cast <uint8_t >(p[2 ]) : 0xFFu ;
593597 uint32_t b3 = 0xFFu ;
594598#if FASTFLOAT_IS_BIG_ENDIAN
595- digits. as_int = (b0 << 24 ) | (b1 << 16 ) | (b2 << 8 ) | b3;
599+ digits = (b0 << 24 ) | (b1 << 16 ) | (b2 << 8 ) | b3;
596600#else
597- digits. as_int = b0 | (b1 << 8 ) | (b2 << 16 ) | (b3 << 24 );
601+ digits = b0 | (b1 << 8 ) | (b2 << 16 ) | (b3 << 24 );
598602#endif
599603 }
600604
601605 const uint32_t magic =
602- ((digits.as_int + 0x46464646u ) | (digits.as_int - 0x30303030u )) &
603- 0x80808080u ;
606+ ((digits + 0x46464646u ) | (digits - 0x30303030u )) & 0x80808080u ;
604607 const auto tz =
605608 static_cast <limb_t >(countr_zero_32 (magic)); // 7, 15, 23, 31, or 32
606609 limb_t nd = (tz == 32 ) ? 4 : (tz >> 3 );
@@ -630,18 +633,17 @@ parse_int_string(UC const *p, UC const *pend, T &value,
630633 return answer;
631634 }
632635
633- digits. as_int ^= 0x30303030u ;
634- digits. as_int <<= ((4 - nd) * 8 );
636+ digits ^= 0x30303030u ;
637+ digits <<= ((4 - nd) * 8 );
635638
636- const uint32_t check = ((digits.as_int >> 24 ) & 0xff ) |
637- ((digits.as_int >> 8 ) & 0xff00 ) |
638- ((digits.as_int << 8 ) & 0xff0000 );
639+ const uint32_t check = ((digits >> 24 ) & 0xff ) | ((digits >> 8 ) & 0xff00 ) |
640+ ((digits << 8 ) & 0xff0000 );
639641 if (check > 0x00020505 ) {
640642 answer.ec = std::errc::result_out_of_range;
641643 answer.ptr = p + nd;
642644 return answer;
643645 }
644- value = static_cast <uint8_t >((0x640a01 * digits. as_int ) >> 24 );
646+ value = static_cast <uint8_t >((0x640a01 * digits) >> 24 );
645647 answer.ec = std::errc ();
646648 answer.ptr = p + nd;
647649 return answer;
0 commit comments