#[repr(C)]
struct Wrapper<T, const Y: usize, const Z: usize>([T; Y], [T; Z]);
const fn check_impl<T, const X: usize, const Y: usize, const Z: usize>() {
assert!(X == Y + Z, "Array cannot be split: sizes don't match");
assert!(
usize::checked_add(Y, Z).is_some(),
"Array cannot be split: length would overflow"
);
assert!(core::mem::size_of::<Wrapper<T, Y, Z>>() == core::mem::size_of::<[T; X]>());
assert!(core::mem::align_of::<Wrapper<T, Y, Z>>() == core::mem::align_of::<[T; X]>());
}
trait SizeCheck<T, const X: usize, const Y: usize, const Z: usize> {
const CHECK: Self;
}
impl<T, const X: usize, const Y: usize, const Z: usize> SizeCheck<T, X, Y, Z> for () {
const CHECK: () = check_impl::<T, X, Y, Z>();
}
fn check<T, const X: usize, const Y: usize, const Z: usize>() {
let _: () = SizeCheck::<T, X, Y, Z>::CHECK;
check_impl::<T, X, Y, Z>();
}
pub(crate) fn split_mut<'a, T, const X: usize, const Y: usize, const Z: usize>(
x: &'a mut [T; X],
) -> (&'a mut [T; Y], &'a mut [T; Z]) {
check::<T, X, Y, Z>();
let wrapper: &'a mut Wrapper<T, Y, Z> = unsafe { core::mem::transmute(x) };
(&mut wrapper.0, &mut wrapper.1)
}