#[macro_export]
macro_rules! transmute {
(#![allow(shrink)] $e:expr) => {{
let mut e = $e;
if false {
fn transmute<Src, Dst>(src: Src) -> Dst
where
Src: $crate::IntoBytes,
Dst: $crate::FromBytes,
{
let _ = src;
loop {}
}
loop {}
#[allow(unreachable_code)]
transmute(e)
} else {
use $crate::util::macro_util::core_reexport::mem::ManuallyDrop;
#[repr(C, packed)]
union Transmute<Src, Dst> {
src: ManuallyDrop<Src>,
dst: ManuallyDrop<Dst>,
}
let u: Transmute<_, _> = unsafe {
#[allow(clippy::missing_transmute_annotations)]
$crate::util::macro_util::core_reexport::mem::transmute(e)
};
if false {
e = ManuallyDrop::into_inner(unsafe { u.src });
let _ = e;
loop {}
} else {
let dst = unsafe { u.dst };
$crate::util::macro_util::must_use(ManuallyDrop::into_inner(dst))
}
}
}};
($e:expr) => {{
let e = $e;
if false {
fn transmute<Src, Dst>(src: Src) -> Dst
where
Src: $crate::IntoBytes,
Dst: $crate::FromBytes,
{
let _ = src;
loop {}
}
loop {}
#[allow(unreachable_code)]
transmute(e)
} else {
let u = unsafe {
#[allow(clippy::missing_transmute_annotations, unnecessary_transmutes)]
$crate::util::macro_util::core_reexport::mem::transmute(e)
};
$crate::util::macro_util::must_use(u)
}
}};
}
#[macro_export]
macro_rules! transmute_ref {
($e:expr) => {{
let e: &_ = $e;
#[allow(unused, clippy::diverging_sub_expression)]
if false {
struct AssertSrcIsIntoBytes<'a, T: ?::core::marker::Sized + $crate::IntoBytes>(&'a T);
struct AssertSrcIsImmutable<'a, T: ?::core::marker::Sized + $crate::Immutable>(&'a T);
struct AssertDstIsFromBytes<'a, U: ?::core::marker::Sized + $crate::FromBytes>(&'a U);
struct AssertDstIsImmutable<'a, T: ?::core::marker::Sized + $crate::Immutable>(&'a T);
let _ = AssertSrcIsIntoBytes(e);
let _ = AssertSrcIsImmutable(e);
if true {
#[allow(unused, unreachable_code)]
let u = AssertDstIsFromBytes(loop {});
u.0
} else {
#[allow(unused, unreachable_code)]
let u = AssertDstIsImmutable(loop {});
u.0
}
} else {
use $crate::util::macro_util::TransmuteRefDst;
let t = $crate::util::macro_util::Wrap::new(e);
unsafe {
t.transmute_ref()
}
}
}}
}
#[macro_export]
macro_rules! transmute_mut {
($e:expr) => {{
let e: &mut _ = $e;
#[allow(unused)]
use $crate::util::macro_util::TransmuteMutDst as _;
let t = $crate::util::macro_util::Wrap::new(e);
t.transmute_mut()
}}
}
#[macro_export]
macro_rules! try_transmute {
($e:expr) => {{
let e = $e;
if false {
Ok(unsafe {
#[allow(clippy::missing_transmute_annotations)]
$crate::util::macro_util::core_reexport::mem::transmute(e)
})
} else {
$crate::util::macro_util::try_transmute::<_, _>(e)
}
}}
}
#[macro_export]
macro_rules! try_transmute_ref {
($e:expr) => {{
let e: &_ = $e;
#[allow(unreachable_code, unused, clippy::diverging_sub_expression)]
if false {
let mut t = loop {};
e = &t;
let u;
$crate::assert_size_eq!(t, u);
$crate::assert_align_gt_eq!(t, u);
Ok(&u)
} else {
$crate::util::macro_util::try_transmute_ref::<_, _>(e)
}
}}
}
#[macro_export]
macro_rules! try_transmute_mut {
($e:expr) => {{
let e: &mut _ = $e;
#[allow(unreachable_code, unused, clippy::diverging_sub_expression)]
if false {
let mut t = loop {};
e = &mut t;
let u;
$crate::assert_size_eq!(t, u);
$crate::assert_align_gt_eq!(t, u);
Ok(&mut u)
} else {
$crate::util::macro_util::try_transmute_mut::<_, _>(e)
}
}}
}
#[doc(alias("include_bytes", "include_data", "include_type"))]
#[macro_export]
macro_rules! include_value {
($file:expr $(,)?) => {
$crate::transmute!(*::core::include_bytes!($file))
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! cryptocorrosion_derive_traits {
(
#[repr($repr:ident)]
$(#[$attr:meta])*
$vis:vis struct $name:ident $(<$($tyvar:ident),*>)?
$(
(
$($tuple_field_vis:vis $tuple_field_ty:ty),*
);
)?
$(
{
$($field_vis:vis $field_name:ident: $field_ty:ty,)*
}
)?
) => {
$crate::cryptocorrosion_derive_traits!(@assert_allowed_struct_repr #[repr($repr)]);
$(#[$attr])*
#[repr($repr)]
$vis struct $name $(<$($tyvar),*>)?
$(
(
$($tuple_field_vis $tuple_field_ty),*
);
)?
$(
{
$($field_vis $field_name: $field_ty,)*
}
)?
unsafe impl $(<$($tyvar),*>)? $crate::TryFromBytes for $name$(<$($tyvar),*>)?
where
$(
$($tuple_field_ty: $crate::FromBytes,)*
)?
$(
$($field_ty: $crate::FromBytes,)*
)?
{
fn is_bit_valid<A>(_c: $crate::Maybe<'_, Self, A>) -> bool
where
A: $crate::pointer::invariant::Reference
{
true
}
fn only_derive_is_allowed_to_implement_this_trait() {}
}
unsafe impl $(<$($tyvar),*>)? $crate::FromZeros for $name$(<$($tyvar),*>)?
where
$(
$($tuple_field_ty: $crate::FromBytes,)*
)?
$(
$($field_ty: $crate::FromBytes,)*
)?
{
fn only_derive_is_allowed_to_implement_this_trait() {}
}
unsafe impl $(<$($tyvar),*>)? $crate::FromBytes for $name$(<$($tyvar),*>)?
where
$(
$($tuple_field_ty: $crate::FromBytes,)*
)?
$(
$($field_ty: $crate::FromBytes,)*
)?
{
fn only_derive_is_allowed_to_implement_this_trait() {}
}
unsafe impl $(<$($tyvar),*>)? $crate::IntoBytes for $name$(<$($tyvar),*>)?
where
$(
$($tuple_field_ty: $crate::IntoBytes,)*
)?
$(
$($field_ty: $crate::IntoBytes,)*
)?
(): $crate::util::macro_util::PaddingFree<
Self,
{
$crate::cryptocorrosion_derive_traits!(
@struct_padding_check #[repr($repr)]
$(($($tuple_field_ty),*))?
$({$($field_ty),*})?
)
},
>,
{
fn only_derive_is_allowed_to_implement_this_trait() {}
}
unsafe impl $(<$($tyvar),*>)? $crate::Immutable for $name$(<$($tyvar),*>)?
where
$(
$($tuple_field_ty: $crate::Immutable,)*
)?
$(
$($field_ty: $crate::Immutable,)*
)?
{
fn only_derive_is_allowed_to_implement_this_trait() {}
}
};
(@assert_allowed_struct_repr #[repr(transparent)]) => {};
(@assert_allowed_struct_repr #[repr(C)]) => {};
(@assert_allowed_struct_repr #[$_attr:meta]) => {
compile_error!("repr must be `#[repr(transparent)]` or `#[repr(C)]`");
};
(
@struct_padding_check #[repr(transparent)]
$(($($tuple_field_ty:ty),*))?
$({$($field_ty:ty),*})?
) => {
0
};
(
@struct_padding_check #[repr(C)]
$(($($tuple_field_ty:ty),*))?
$({$($field_ty:ty),*})?
) => {
$crate::struct_padding!(
Self,
[
$($($tuple_field_ty),*)?
$($($field_ty),*)?
]
)
};
(
#[repr(C)]
$(#[$attr:meta])*
$vis:vis union $name:ident {
$(
$field_name:ident: $field_ty:ty,
)*
}
) => {
$(#[$attr])*
#[repr(C)]
$vis union $name {
$(
$field_name: $field_ty,
)*
}
unsafe impl $crate::TryFromBytes for $name
where
$(
$field_ty: $crate::FromBytes,
)*
{
fn is_bit_valid<A>(_c: $crate::Maybe<'_, Self, A>) -> bool
where
A: $crate::pointer::invariant::Reference
{
true
}
fn only_derive_is_allowed_to_implement_this_trait() {}
}
unsafe impl $crate::FromZeros for $name
where
$(
$field_ty: $crate::FromBytes,
)*
{
fn only_derive_is_allowed_to_implement_this_trait() {}
}
unsafe impl $crate::FromBytes for $name
where
$(
$field_ty: $crate::FromBytes,
)*
{
fn only_derive_is_allowed_to_implement_this_trait() {}
}
unsafe impl $crate::IntoBytes for $name
where
$(
$field_ty: $crate::IntoBytes,
)*
(): $crate::util::macro_util::PaddingFree<
Self,
{
$crate::union_padding!(
Self,
[$($field_ty),*]
)
},
>,
{
fn only_derive_is_allowed_to_implement_this_trait() {}
}
unsafe impl $crate::Immutable for $name
where
$(
$field_ty: $crate::Immutable,
)*
{
fn only_derive_is_allowed_to_implement_this_trait() {}
}
};
}
#[cfg(test)]
mod tests {
use crate::{
byteorder::native_endian::{U16, U32},
util::testutil::*,
*,
};
#[derive(KnownLayout, Immutable, FromBytes, IntoBytes, PartialEq, Debug)]
#[repr(C)]
struct SliceDst<T, U> {
a: T,
b: [U],
}
#[test]
fn test_transmute() {
let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
let x: [[u8; 2]; 4] = transmute!(array_of_u8s);
assert_eq!(x, array_of_arrays);
let x: [u8; 8] = transmute!(array_of_arrays);
assert_eq!(x, array_of_u8s);
let x: [[u8; 2]; 3] = transmute!(#![allow(shrink)] array_of_u8s);
assert_eq!(x, [[0u8, 1], [2, 3], [4, 5]]);
#[derive(IntoBytes)]
#[repr(transparent)]
struct PanicOnDrop(());
impl Drop for PanicOnDrop {
fn drop(&mut self) {
panic!("PanicOnDrop::drop");
}
}
#[allow(clippy::let_unit_value)]
let _: () = transmute!(PanicOnDrop(()));
#[allow(clippy::let_unit_value)]
let _: () = transmute!(#![allow(shrink)] PanicOnDrop(()));
const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
const X: [[u8; 2]; 4] = transmute!(ARRAY_OF_U8S);
assert_eq!(X, ARRAY_OF_ARRAYS);
const X_SHRINK: [[u8; 2]; 3] = transmute!(#![allow(shrink)] ARRAY_OF_U8S);
assert_eq!(X_SHRINK, [[0u8, 1], [2, 3], [4, 5]]);
let x: usize = transmute!(UnsafeCell::new(1usize));
assert_eq!(x, 1);
let x: UnsafeCell<usize> = transmute!(1usize);
assert_eq!(x.into_inner(), 1);
let x: UnsafeCell<isize> = transmute!(UnsafeCell::new(1usize));
assert_eq!(x.into_inner(), 1);
}
#[derive(FromBytes, IntoBytes, Immutable, PartialEq, Eq, Debug)]
#[repr(transparent)]
struct Nkl<T>(T);
#[test]
fn test_transmute_ref() {
let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
let x: &[[u8; 2]; 4] = transmute_ref!(&array_of_u8s);
assert_eq!(*x, array_of_arrays);
let x: &[u8; 8] = transmute_ref!(&array_of_arrays);
assert_eq!(*x, array_of_u8s);
const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
#[allow(clippy::redundant_static_lifetimes)]
const X: &'static [[u8; 2]; 4] = transmute_ref!(&ARRAY_OF_U8S);
assert_eq!(*X, ARRAY_OF_ARRAYS);
#[cfg(not(zerocopy_generic_bounds_in_const_fn_1_61_0))]
{
const ARRAY_OF_NKL_U8S: Nkl<[u8; 8]> = Nkl([0u8, 1, 2, 3, 4, 5, 6, 7]);
const ARRAY_OF_NKL_ARRAYS: Nkl<[[u8; 2]; 4]> = Nkl([[0, 1], [2, 3], [4, 5], [6, 7]]);
const X_NKL: &Nkl<[[u8; 2]; 4]> = transmute_ref!(&ARRAY_OF_NKL_U8S);
assert_eq!(*X_NKL, ARRAY_OF_NKL_ARRAYS);
}
#[cfg(zerocopy_generic_bounds_in_const_fn_1_61_0)]
{
const fn transmute_ref<T, U>(t: &T) -> &U
where
T: IntoBytes + Immutable,
U: FromBytes + Immutable,
{
transmute_ref!(t)
}
const ARRAY_OF_NKL_U8S: Nkl<[u8; 8]> = Nkl([0u8, 1, 2, 3, 4, 5, 6, 7]);
const ARRAY_OF_NKL_ARRAYS: Nkl<[[u8; 2]; 4]> = Nkl([[0, 1], [2, 3], [4, 5], [6, 7]]);
const X_NKL: &Nkl<[[u8; 2]; 4]> = transmute_ref(&ARRAY_OF_NKL_U8S);
assert_eq!(*X_NKL, ARRAY_OF_NKL_ARRAYS);
}
let slice_dst_of_u8s =
SliceDst::<U16, [u8; 2]>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();
let slice_dst_of_u16s =
SliceDst::<U16, U16>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();
let x: &SliceDst<U16, U16> = transmute_ref!(slice_dst_of_u8s);
assert_eq!(x, slice_dst_of_u16s);
let slice_dst_of_u8s =
SliceDst::<U16, u8>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();
let x: &[u8] = transmute_ref!(slice_dst_of_u8s);
assert_eq!(x, [0, 1, 2, 3, 4, 5]);
let x: &[u8] = transmute_ref!(slice_dst_of_u16s);
assert_eq!(x, [0, 1, 2, 3, 4, 5]);
let x: &[U16] = transmute_ref!(slice_dst_of_u16s);
let slice_of_u16s: &[U16] = <[U16]>::ref_from_bytes(&[0, 1, 2, 3, 4, 5][..]).unwrap();
assert_eq!(x, slice_of_u16s);
let bytes = &[0, 1, 2, 3, 4, 5, 6, 7][..];
let slice_dst_big = SliceDst::<U32, U16>::ref_from_bytes(bytes).unwrap();
let slice_dst_small = SliceDst::<U16, u8>::ref_from_bytes(bytes).unwrap();
let x: &SliceDst<U16, u8> = transmute_ref!(slice_dst_big);
assert_eq!(x, slice_dst_small);
let x: &[u8; 8] = transmute_ref!(X);
assert_eq!(*x, ARRAY_OF_U8S);
let u = AU64(0);
let array = [0, 0, 0, 0, 0, 0, 0, 0];
let x: &[u8; 8] = transmute_ref!(&u);
assert_eq!(*x, array);
let mut x = 0u8;
#[allow(clippy::useless_transmute)]
let y: &u8 = transmute_ref!(&mut x);
assert_eq!(*y, 0);
}
#[test]
fn test_try_transmute() {
let array_of_bools = [false, true, false, true, false, true, false, true];
let array_of_arrays = [[0, 1], [0, 1], [0, 1], [0, 1]];
let x: Result<[[u8; 2]; 4], _> = try_transmute!(array_of_bools);
assert_eq!(x, Ok(array_of_arrays));
let x: Result<[bool; 8], _> = try_transmute!(array_of_arrays);
assert_eq!(x, Ok(array_of_bools));
let x: Result<usize, _> = try_transmute!(UnsafeCell::new(1usize));
assert_eq!(x.unwrap(), 1);
let x: Result<UnsafeCell<usize>, _> = try_transmute!(1usize);
assert_eq!(x.unwrap().into_inner(), 1);
let x: Result<UnsafeCell<isize>, _> = try_transmute!(UnsafeCell::new(1usize));
assert_eq!(x.unwrap().into_inner(), 1);
#[derive(FromBytes, IntoBytes, Debug, PartialEq)]
#[repr(transparent)]
struct PanicOnDrop<T>(T);
impl<T> Drop for PanicOnDrop<T> {
fn drop(&mut self) {
panic!("PanicOnDrop dropped");
}
}
let x: Result<usize, _> = try_transmute!(PanicOnDrop(1usize));
assert_eq!(x, Ok(1));
let y: Result<bool, _> = try_transmute!(PanicOnDrop(2u8));
assert_eq!(y.as_ref().map_err(|p| &p.src.0), Err::<&bool, _>(&2u8));
mem::forget(y);
}
#[test]
fn test_try_transmute_ref() {
let array_of_bools = &[false, true, false, true, false, true, false, true];
let array_of_arrays = &[[0, 1], [0, 1], [0, 1], [0, 1]];
let x: Result<&[[u8; 2]; 4], _> = try_transmute_ref!(array_of_bools);
assert_eq!(x, Ok(array_of_arrays));
let x: Result<&[bool; 8], _> = try_transmute_ref!(array_of_arrays);
assert_eq!(x, Ok(array_of_bools));
{
let x: Result<&[[u8; 2]; 4], _> = try_transmute_ref!(array_of_bools);
assert_eq!(x, Ok(array_of_arrays));
}
let u = AU64(0);
let array = [0u8, 0, 0, 0, 0, 0, 0, 0];
let x: Result<&[u8; 8], _> = try_transmute_ref!(&u);
assert_eq!(x, Ok(&array));
let mut x = 0u8;
#[allow(clippy::useless_transmute)]
let y: Result<&u8, _> = try_transmute_ref!(&mut x);
assert_eq!(y, Ok(&0));
}
#[test]
fn test_try_transmute_mut() {
let array_of_u8s = &mut [0u8, 1, 0, 1, 0, 1, 0, 1];
let array_of_arrays = &mut [[0u8, 1], [0, 1], [0, 1], [0, 1]];
let x: Result<&mut [[u8; 2]; 4], _> = try_transmute_mut!(array_of_u8s);
assert_eq!(x, Ok(array_of_arrays));
let array_of_bools = &mut [false, true, false, true, false, true, false, true];
let array_of_arrays = &mut [[0u8, 1], [0, 1], [0, 1], [0, 1]];
let x: Result<&mut [bool; 8], _> = try_transmute_mut!(array_of_arrays);
assert_eq!(x, Ok(array_of_bools));
let array_of_bools = &mut [false, true, false, true, false, true, false, true];
let array_of_arrays = &mut [[0u8, 1], [0, 1], [0, 1], [0, 1]];
{
let x: Result<&mut [bool; 8], _> = try_transmute_mut!(array_of_arrays);
assert_eq!(x, Ok(array_of_bools));
}
let u = &mut AU64(0);
let array = &mut [0u8, 0, 0, 0, 0, 0, 0, 0];
let x: Result<&mut [u8; 8], _> = try_transmute_mut!(u);
assert_eq!(x, Ok(array));
let mut x = 0u8;
#[allow(clippy::useless_transmute)]
let y: Result<&mut u8, _> = try_transmute_mut!(&mut x);
assert_eq!(y, Ok(&mut 0));
}
#[test]
fn test_transmute_mut() {
let mut array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
let mut array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
let x: &mut [[u8; 2]; 4] = transmute_mut!(&mut array_of_u8s);
assert_eq!(*x, array_of_arrays);
let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);
assert_eq!(*x, array_of_u8s);
{
let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);
assert_eq!(*x, array_of_u8s);
}
let mut array_of_u8s = Nkl([0u8, 1, 2, 3, 4, 5, 6, 7]);
let mut array_of_arrays = Nkl([[0, 1], [2, 3], [4, 5], [6, 7]]);
let x: &mut Nkl<[[u8; 2]; 4]> = transmute_mut!(&mut array_of_u8s);
assert_eq!(*x, array_of_arrays);
let x: &mut Nkl<[u8; 8]> = transmute_mut!(&mut array_of_arrays);
assert_eq!(*x, array_of_u8s);
let mut u = AU64(0);
let array = [0, 0, 0, 0, 0, 0, 0, 0];
let x: &[u8; 8] = transmute_mut!(&mut u);
assert_eq!(*x, array);
let mut x = 0u8;
#[allow(clippy::useless_transmute)]
let y: &u8 = transmute_mut!(&mut x);
assert_eq!(*y, 0);
let mut bytes = [0, 1, 2, 3, 4, 5, 6];
let slice_dst_of_u8s = SliceDst::<u8, [u8; 2]>::mut_from_bytes(&mut bytes[..]).unwrap();
let mut bytes = [0, 1, 2, 3, 4, 5, 6];
let slice_dst_of_u16s = SliceDst::<u8, U16>::mut_from_bytes(&mut bytes[..]).unwrap();
let x: &mut SliceDst<u8, U16> = transmute_mut!(slice_dst_of_u8s);
assert_eq!(x, slice_dst_of_u16s);
let array_of_u16s: &mut [u16] = &mut [0u16, 1, 2];
let array_of_i16s: &mut [i16] = &mut [0i16, 1, 2];
let x: &mut [i16] = transmute_mut!(array_of_u16s);
assert_eq!(x, array_of_i16s);
let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7];
let slice_dst_big = SliceDst::<U32, U16>::mut_from_bytes(&mut bytes[..]).unwrap();
let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7];
let slice_dst_small = SliceDst::<U16, u8>::mut_from_bytes(&mut bytes[..]).unwrap();
let x: &mut SliceDst<U16, u8> = transmute_mut!(slice_dst_big);
assert_eq!(x, slice_dst_small);
}
#[test]
fn test_macros_evaluate_args_once() {
let mut ctr = 0;
#[allow(clippy::useless_transmute)]
let _: usize = transmute!({
ctr += 1;
0usize
});
assert_eq!(ctr, 1);
let mut ctr = 0;
let _: &usize = transmute_ref!({
ctr += 1;
&0usize
});
assert_eq!(ctr, 1);
let mut ctr: usize = 0;
let _: &mut usize = transmute_mut!({
ctr += 1;
&mut ctr
});
assert_eq!(ctr, 1);
let mut ctr = 0;
#[allow(clippy::useless_transmute)]
let _: usize = try_transmute!({
ctr += 1;
0usize
})
.unwrap();
assert_eq!(ctr, 1);
}
#[test]
fn test_include_value() {
const AS_U32: u32 = include_value!("../testdata/include_value/data");
assert_eq!(AS_U32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));
const AS_I32: i32 = include_value!("../testdata/include_value/data");
assert_eq!(AS_I32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));
}
#[test]
#[allow(non_camel_case_types, unreachable_pub, dead_code)]
fn test_cryptocorrosion_derive_traits() {
fn assert_impls<T: FromBytes + IntoBytes + Immutable>() {}
cryptocorrosion_derive_traits! {
#[repr(C)]
#[derive(Clone, Copy)]
pub union vec128_storage {
d: [u32; 4],
q: [u64; 2],
}
}
assert_impls::<vec128_storage>();
cryptocorrosion_derive_traits! {
#[repr(transparent)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct u32x4_generic([u32; 4]);
}
assert_impls::<u32x4_generic>();
cryptocorrosion_derive_traits! {
#[repr(transparent)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct u64x2_generic([u64; 2]);
}
assert_impls::<u64x2_generic>();
cryptocorrosion_derive_traits! {
#[repr(transparent)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct u128x1_generic([u128; 1]);
}
assert_impls::<u128x1_generic>();
cryptocorrosion_derive_traits! {
#[repr(transparent)]
#[derive(Copy, Clone, Default)]
#[allow(non_camel_case_types)]
pub struct x2<W, G>(pub [W; 2], PhantomData<G>);
}
enum NotZerocopy {}
assert_impls::<x2<(), NotZerocopy>>();
cryptocorrosion_derive_traits! {
#[repr(transparent)]
#[derive(Copy, Clone, Default)]
#[allow(non_camel_case_types)]
pub struct x4<W>(pub [W; 4]);
}
assert_impls::<x4<()>>();
#[cfg(feature = "simd")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
#[cfg(target_arch = "x86")]
use core::arch::x86::{__m128i, __m256i};
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::{__m128i, __m256i};
cryptocorrosion_derive_traits! {
#[repr(C)]
#[derive(Copy, Clone)]
pub struct X4(__m128i, __m128i, __m128i, __m128i);
}
assert_impls::<X4>();
cryptocorrosion_derive_traits! {
#[repr(C)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub union vec128_storage {
u32x4: [u32; 4],
u64x2: [u64; 2],
u128x1: [u128; 1],
sse2: __m128i,
}
}
assert_impls::<vec128_storage>();
cryptocorrosion_derive_traits! {
#[repr(transparent)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub struct vec<S3, S4, NI> {
x: __m128i,
s3: PhantomData<S3>,
s4: PhantomData<S4>,
ni: PhantomData<NI>,
}
}
assert_impls::<vec<NotZerocopy, NotZerocopy, NotZerocopy>>();
cryptocorrosion_derive_traits! {
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct u32x4x2_avx2<NI> {
x: __m256i,
ni: PhantomData<NI>,
}
}
assert_impls::<u32x4x2_avx2<NotZerocopy>>();
}
cryptocorrosion_derive_traits! {
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct ReprC(u8, u8, u16);
}
}
}