#![allow(non_snake_case)] use crate::mem::*; #[inline] pub fn ZSTD_isPower2(u: usize) -> bool { (u & (u.wrapping_sub(1))) == 0 } #[inline] pub fn ZSTD_countTrailingZeros32(val: U32) -> u32 { assert!(val != 0); val.trailing_zeros() } #[inline] pub fn ZSTD_countLeadingZeros32(val: U32) -> u32 { assert!(val != 0); val.leading_zeros() } #[inline] pub fn ZSTD_countTrailingZeros64(val: U64) -> u32 { assert!(val != 0); val.trailing_zeros() } #[inline] pub fn ZSTD_countLeadingZeros64(val: U64) -> u32 { assert!(val != 0); val.leading_zeros() } #[inline] pub fn ZSTD_NbCommonBytes(val: usize) -> u32 { if MEM_isLittleEndian() { if MEM_64bits() { ZSTD_countTrailingZeros64(val as U64) >> 3 } else { ZSTD_countTrailingZeros32(val as U32) >> 3 } } else { if MEM_64bits() { ZSTD_countLeadingZeros64(val as U64) >> 3 } else { ZSTD_countLeadingZeros32(val as U32) >> 3 } } } #[inline] pub fn ZSTD_highbit32(val: U32) -> u32 { assert!(val != 0); 31 - ZSTD_countLeadingZeros32(val) } #[inline] pub fn ZSTD_rotateRight_U64(value: U64, count: U32) -> U64 { assert!(count < 64); value.rotate_right(count) } #[inline] pub fn ZSTD_rotateRight_U32(value: U32, count: U32) -> U32 { assert!(count < 32); value.rotate_right(count) } #[inline] pub fn ZSTD_rotateRight_U16(value: U16, count: U32) -> U16 { assert!(count < 16); value.rotate_right(count) } #[cfg(test)] mod tests { use super::*; #[test] fn power_of_two_matches_the_c_helper() { assert!(ZSTD_isPower2(0)); assert!(ZSTD_isPower2(1)); assert!(ZSTD_isPower2(1 << 20)); assert!(!ZSTD_isPower2(3)); assert!(!ZSTD_isPower2((1 << 20) + 1)); } #[test] fn bit_counts_cover_both_ends() { assert_eq!(ZSTD_countTrailingZeros32(1), 0); assert_eq!(ZSTD_countTrailingZeros32(1 << 31), 31); assert_eq!(ZSTD_countLeadingZeros32(1), 31); assert_eq!(ZSTD_countLeadingZeros32(1 << 31), 0); assert_eq!(ZSTD_countTrailingZeros64(1), 0); assert_eq!(ZSTD_countTrailingZeros64(1 << 63), 63); assert_eq!(ZSTD_countLeadingZeros64(1), 63); assert_eq!(ZSTD_countLeadingZeros64(1 << 63), 0); assert_eq!(ZSTD_highbit32(1), 0); assert_eq!(ZSTD_highbit32(1 << 31), 31); } #[test] fn common_bytes_are_counted_in_memory_order() { if MEM_isLittleEndian() { assert_eq!(ZSTD_NbCommonBytes(0x0000_0000_0001_0000), 2); } else if MEM_64bits() { assert_eq!(ZSTD_NbCommonBytes(0x0001_0000_0000_0000u64 as usize), 2); } else { assert_eq!(ZSTD_NbCommonBytes(0x0001_0000), 2); } } #[test] fn rotations_match_expected_wraparound() { assert_eq!(ZSTD_rotateRight_U16(0x1234, 4), 0x4123); assert_eq!(ZSTD_rotateRight_U32(0x1234_5678, 8), 0x7812_3456); assert_eq!( ZSTD_rotateRight_U64(0x0123_4567_89ab_cdef, 16), 0xcdef_0123_4567_89ab ); } }