pub trait IndexedSource {
type Item: Copy;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
unsafe fn get_unchecked(&self, i: usize) -> Self::Item;
}
impl<T: Copy> IndexedSource for &[T] {
type Item = T;
#[inline]
fn len(&self) -> usize {
<[T]>::len(self)
}
#[inline]
unsafe fn get_unchecked(&self, i: usize) -> T {
unsafe { *<[T]>::get_unchecked(self, i) }
}
}
impl<T: Copy> IndexedSource for &mut [T] {
type Item = T;
#[inline]
fn len(&self) -> usize {
<[T]>::len(self)
}
#[inline]
unsafe fn get_unchecked(&self, i: usize) -> T {
unsafe { *<[T]>::get_unchecked(self, i) }
}
}
pub struct LaneZip<A, B>(pub A, pub B);
impl<A: IndexedSource, B: IndexedSource> LaneZip<A, B> {
pub fn new(a: A, b: B) -> Self {
assert_eq!(
a.len(),
b.len(),
"LaneZip operands must have the same length"
);
Self(a, b)
}
}
impl<A: IndexedSource, B: IndexedSource> IndexedSource for LaneZip<A, B> {
type Item = (A::Item, B::Item);
#[inline]
fn len(&self) -> usize {
debug_assert_eq!(self.0.len(), self.1.len());
self.0.len()
}
#[inline]
unsafe fn get_unchecked(&self, i: usize) -> (A::Item, B::Item) {
unsafe { (self.0.get_unchecked(i), self.1.get_unchecked(i)) }
}
}