diff --git a/Cargo.toml b/Cargo.toml index 9b19105..2d7d679 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,7 @@ serde = { version = "1.0.117", optional = true } cfg-if = "1.0" atomic-polyfill = { version="1.0.1", optional=true} getrandom = { version = "0.2.7", optional = true } +zerocopy = { version = "0.7.0", default-features = false, features = ["simd"] } [target.'cfg(not(all(target_arch = "arm", target_os = "none")))'.dependencies] once_cell = { version = "1.13.1", default-features = false, features = ["unstable", "alloc"] } diff --git a/src/convert.rs b/src/convert.rs index fc47baa..712eae1 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -7,13 +7,13 @@ macro_rules! convert { impl Convert<$b> for $a { #[inline(always)] fn convert(self) -> $b { - unsafe { core::mem::transmute::<$a, $b>(self) } + zerocopy::transmute!(self) } } impl Convert<$a> for $b { #[inline(always)] fn convert(self) -> $a { - unsafe { core::mem::transmute::<$b, $a>(self) } + zerocopy::transmute!(self) } } }; @@ -65,8 +65,7 @@ macro_rules! as_array { { #[inline(always)] fn as_array(slice: &[T]) -> &[T; $len] { - assert_eq!(slice.len(), $len); - unsafe { &*(slice.as_ptr() as *const [_; $len]) } + core::convert::TryFrom::try_from(slice).unwrap() } as_array($input) } diff --git a/src/hash_quality_test.rs b/src/hash_quality_test.rs index 8f13d24..5a30a10 100644 --- a/src/hash_quality_test.rs +++ b/src/hash_quality_test.rs @@ -71,12 +71,8 @@ fn test_no_full_collisions(gen_hash: impl Fn() -> T) { gen_combinations(&options, 7, Vec::new(), &mut combinations); let mut map: HashMap> = HashMap::new(); for combination in combinations { - let array = unsafe { - let (begin, middle, end) = combination.align_to::(); - assert_eq!(0, begin.len()); - assert_eq!(0, end.len()); - middle.to_vec() - }; + use zerocopy::AsBytes; + let array = combination.as_slice().as_bytes().to_vec(); let mut hasher = gen_hash(); hasher.write(&array); let hash = hasher.finish(); diff --git a/src/operations.rs b/src/operations.rs index 5f027f4..dce83cb 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -1,4 +1,5 @@ use crate::convert::*; +use zerocopy::transmute; ///This constant comes from Kunth's prng (Empirically it works better than those from splitmix32). pub(crate) const MULTIPLE: u64 = 6364136223846793005; @@ -55,8 +56,7 @@ pub(crate) fn shuffle(a: u128) -> u128 { use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; - use core::mem::transmute; - unsafe { transmute(_mm_shuffle_epi8(transmute(a), transmute(SHUFFLE_MASK))) } + unsafe { transmute!(_mm_shuffle_epi8(transmute!(a), transmute!(SHUFFLE_MASK))) } } #[cfg(not(all(target_feature = "ssse3", not(miri))))] { @@ -81,13 +81,12 @@ pub(crate) fn shuffle_and_add(base: u128, to_add: u128) -> u128 { #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2", not(miri)))] #[inline(always)] pub(crate) fn add_by_64s(a: [u64; 2], b: [u64; 2]) -> [u64; 2] { - use core::mem::transmute; unsafe { #[cfg(target_arch = "x86")] use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; - transmute(_mm_add_epi64(transmute(a), transmute(b))) + transmute!(_mm_add_epi64(transmute!(a), transmute!(b))) } } @@ -105,10 +104,9 @@ pub(crate) fn aesenc(value: u128, xor: u128) -> u128 { use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; - use core::mem::transmute; unsafe { - let value = transmute(value); - transmute(_mm_aesenc_si128(value, transmute(xor))) + let value = transmute!(value); + transmute!(_mm_aesenc_si128(value, transmute!(xor))) } } @@ -125,10 +123,9 @@ pub(crate) fn aesenc(value: u128, xor: u128) -> u128 { use core::arch::aarch64::*; #[cfg(target_arch = "arm")] use core::arch::arm::*; - use core::mem::transmute; unsafe { - let value = transmute(value); - xor ^ transmute::<_, u128>(vaesmcq_u8(vaeseq_u8(value, transmute(0u128)))) + let value = transmute!(value); + xor ^ transmute::<_, u128>(vaesmcq_u8(vaeseq_u8(value, transmute!(0u128)))) } } @@ -140,10 +137,9 @@ pub(crate) fn aesdec(value: u128, xor: u128) -> u128 { use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; - use core::mem::transmute; unsafe { - let value = transmute(value); - transmute(_mm_aesdec_si128(value, transmute(xor))) + let value = transmute!(value); + transmute!(_mm_aesdec_si128(value, transmute!(xor))) } } @@ -160,10 +156,9 @@ pub(crate) fn aesdec(value: u128, xor: u128) -> u128 { use core::arch::aarch64::*; #[cfg(target_arch = "arm")] use core::arch::arm::*; - use core::mem::transmute; unsafe { - let value = transmute(value); - xor ^ transmute::<_, u128>(vaesimcq_u8(vaesdq_u8(value, transmute(0u128)))) + let value = transmute!(value); + xor ^ transmute::<_, u128>(vaesimcq_u8(vaesdq_u8(value, transmute!(0u128)))) } } @@ -207,7 +202,7 @@ mod test { // #[cfg(target_arch = "x86_64")] // use core::arch::x86_64::*; // MASK.with(|mask| { - // unsafe { transmute(_mm_shuffle_epi8(transmute(a), transmute(mask.get()))) } + // unsafe { transmute!(_mm_shuffle_epi8(transmute!(a), transmute!(mask.get()))) } // }) // } //