use std::marker::PhantomData;
use std::mem::align_of;
use std::mem::size_of;
use crate::lane_kernels::source::IndexedSource;
pub trait IndexedSink: IndexedSource {
type Write: Copy;
unsafe fn set_unchecked(&mut self, i: usize, value: Self::Write);
}
impl<T: Copy> IndexedSink for &mut [T] {
type Write = T;
#[inline]
unsafe fn set_unchecked(&mut self, i: usize, value: T) {
unsafe { *<[T]>::get_unchecked_mut(self, i) = value };
}
}
pub struct ReinterpretSink<'a, F, T> {
slice: &'a mut [F],
_phantom: PhantomData<T>,
}
impl<'a, F, T> ReinterpretSink<'a, F, T> {
pub fn new(slice: &'a mut [F]) -> Self {
assert_eq!(
size_of::<F>(),
size_of::<T>(),
"ReinterpretSink requires F and T to have the same size",
);
assert_eq!(
align_of::<F>(),
align_of::<T>(),
"ReinterpretSink requires F and T to have the same alignment",
);
Self {
slice,
_phantom: PhantomData,
}
}
}
impl<F: Copy, T: Copy> IndexedSource for ReinterpretSink<'_, F, T> {
type Item = F;
#[inline]
fn len(&self) -> usize {
self.slice.len()
}
#[inline]
unsafe fn get_unchecked(&self, i: usize) -> F {
unsafe { *self.slice.as_ptr().add(i) }
}
}
impl<F: Copy, T: Copy> IndexedSink for ReinterpretSink<'_, F, T> {
type Write = T;
#[inline]
unsafe fn set_unchecked(&mut self, i: usize, value: T) {
unsafe {
let ptr = self.slice.as_mut_ptr().add(i) as *mut T;
ptr.write(value);
}
}
}