use core::mem::MaybeUninit;
pub trait Zip {
type TLhs;
type TSelf<T>;
fn zip_with<TRhs, TTo, F: FnMut(Self::TLhs, TRhs) -> TTo>(self, rhs: Self::TSelf<TRhs>, f: F) -> Self::TSelf<TTo>;
}
impl<TLhs, const N: usize> Zip for [TLhs; N] {
type TLhs = TLhs;
type TSelf<T> = [T; N];
fn zip_with<TRhs, TTo, F: FnMut(Self::TLhs, TRhs) -> TTo>(self, rhs: Self::TSelf<TRhs>, mut f: F) -> Self::TSelf<TTo> {
let consumed_lhs: [MaybeUninit<TLhs>; N] = self.map(MaybeUninit::new);
let consumed_rhs: [MaybeUninit<TRhs>; N] = rhs.map(MaybeUninit::new);
let mut contents: [MaybeUninit<TTo>; N] = MaybeUninit::uninit_array();
for i in 0..N {
contents[i].write(f(unsafe { consumed_lhs[i].assume_init_read() }, unsafe { consumed_rhs[i].assume_init_read() }));
}
unsafe { MaybeUninit::array_assume_init(contents) }
}
}