@@ -523,33 +523,36 @@ parse_int_string(UC const *p, UC const *pend, T &value,
523523 return answer;
524524 }
525525
526- union {
527- uint8_t as_str[4 ];
528- uint32_t as_int;
529- } digits;
526+ uint32_t digits;
530527
531- if (cpp20_and_in_constexpr ()) {
532- digits.as_int = 0 ;
528+ #if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST
529+ if (std::is_constant_evaluated ()) {
530+ uint8_t str[4 ]{};
533531 for (size_t j = 0 ; j < 4 && j < len; ++j) {
534- digits. as_str [j] = static_cast <uint8_t >(p[j]);
532+ str [j] = static_cast <uint8_t >(p[j]);
535533 }
536- } else if (len >= 4 ) {
537- memcpy (&digits.as_int , p, 4 );
534+ digits = std::bit_cast<uint32_t >(str);
535+ }
536+ #else
537+ if (false ) {
538+ }
539+ #endif
540+ else if (len >= 4 ) {
541+ ::memcpy (&digits, p, 4 );
538542 } else {
539543 uint32_t b0 = static_cast <uint8_t >(p[0 ]);
540544 uint32_t b1 = (len > 1 ) ? static_cast <uint8_t >(p[1 ]) : 0xFFu ;
541545 uint32_t b2 = (len > 2 ) ? static_cast <uint8_t >(p[2 ]) : 0xFFu ;
542546 uint32_t b3 = 0xFFu ;
543547#if FASTFLOAT_IS_BIG_ENDIAN
544- digits. as_int = (b0 << 24 ) | (b1 << 16 ) | (b2 << 8 ) | b3;
548+ digits = (b0 << 24 ) | (b1 << 16 ) | (b2 << 8 ) | b3;
545549#else
546- digits. as_int = b0 | (b1 << 8 ) | (b2 << 16 ) | (b3 << 24 );
550+ digits = b0 | (b1 << 8 ) | (b2 << 16 ) | (b3 << 24 );
547551#endif
548552 }
549553
550554 uint32_t magic =
551- ((digits.as_int + 0x46464646u ) | (digits.as_int - 0x30303030u )) &
552- 0x80808080u ;
555+ ((digits + 0x46464646u ) | (digits - 0x30303030u )) & 0x80808080u ;
553556 uint32_t tz = (uint32_t )countr_zero_32 (magic); // 7, 15, 23, 31, or 32
554557 uint32_t nd = (tz == 32 ) ? 4 : (tz >> 3 );
555558 nd = (uint32_t )std::min ((size_t )nd, len);
@@ -578,18 +581,17 @@ parse_int_string(UC const *p, UC const *pend, T &value,
578581 return answer;
579582 }
580583
581- digits. as_int ^= 0x30303030u ;
582- digits. as_int <<= ((4 - nd) * 8 );
584+ digits ^= 0x30303030u ;
585+ digits <<= ((4 - nd) * 8 );
583586
584- uint32_t check = ((digits.as_int >> 24 ) & 0xff ) |
585- ((digits.as_int >> 8 ) & 0xff00 ) |
586- ((digits.as_int << 8 ) & 0xff0000 );
587+ uint32_t check = ((digits >> 24 ) & 0xff ) | ((digits >> 8 ) & 0xff00 ) |
588+ ((digits << 8 ) & 0xff0000 );
587589 if (check > 0x00020505 ) {
588590 answer.ec = std::errc::result_out_of_range;
589591 answer.ptr = p + nd;
590592 return answer;
591593 }
592- value = (uint8_t )((0x640a01 * digits. as_int ) >> 24 );
594+ value = (uint8_t )((0x640a01 * digits) >> 24 );
593595 answer.ec = std::errc ();
594596 answer.ptr = p + nd;
595597 return answer;
0 commit comments