use core::mem::MaybeUninit;
pub trait WriteOnlyBuffer: sealed::Sealed {
type Item;
fn raw_buffer_len(&self) -> usize;
unsafe fn as_write_only_ptr(&mut self) -> *mut Self::Item;
#[inline(always)]
unsafe fn write_at(&mut self, idx: usize, value: Self::Item) {
let ptr = self.as_write_only_ptr();
ptr.add(idx).write(value)
}
}
mod sealed {
use core::mem::MaybeUninit;
pub trait Sealed {}
impl Sealed for &mut [f32] {}
impl Sealed for &mut [f64] {}
impl Sealed for &mut [i8] {}
impl Sealed for &mut [i16] {}
impl Sealed for &mut [i32] {}
impl Sealed for &mut [i64] {}
impl Sealed for &mut [u8] {}
impl Sealed for &mut [u16] {}
impl Sealed for &mut [u32] {}
impl Sealed for &mut [u64] {}
impl Sealed for &mut [MaybeUninit<f32>] {}
impl Sealed for &mut [MaybeUninit<f64>] {}
impl Sealed for &mut [MaybeUninit<i8>] {}
impl Sealed for &mut [MaybeUninit<i16>] {}
impl Sealed for &mut [MaybeUninit<i32>] {}
impl Sealed for &mut [MaybeUninit<i64>] {}
impl Sealed for &mut [MaybeUninit<u8>] {}
impl Sealed for &mut [MaybeUninit<u16>] {}
impl Sealed for &mut [MaybeUninit<u32>] {}
impl Sealed for &mut [MaybeUninit<u64>] {}
}
macro_rules! add_slice_impl {
($t:ty, inner = $inner:ty) => {
impl WriteOnlyBuffer for &mut [$t] {
type Item = $inner;
#[inline(always)]
fn raw_buffer_len(&self) -> usize {
self.len()
}
#[inline(always)]
unsafe fn as_write_only_ptr(&mut self) -> *mut Self::Item {
self.as_mut_ptr().cast()
}
}
};
}
add_slice_impl!(f32, inner = f32);
add_slice_impl!(f64, inner = f64);
add_slice_impl!(i8, inner = i8);
add_slice_impl!(i16, inner = i16);
add_slice_impl!(i32, inner = i32);
add_slice_impl!(i64, inner = i64);
add_slice_impl!(u8, inner = u8);
add_slice_impl!(u16, inner = u16);
add_slice_impl!(u32, inner = u32);
add_slice_impl!(u64, inner = u64);
add_slice_impl!(MaybeUninit<f32>, inner = f32);
add_slice_impl!(MaybeUninit<f64>, inner = f64);
add_slice_impl!(MaybeUninit<i8>, inner = i8);
add_slice_impl!(MaybeUninit<i16>, inner = i16);
add_slice_impl!(MaybeUninit<i32>, inner = i32);
add_slice_impl!(MaybeUninit<i64>, inner = i64);
add_slice_impl!(MaybeUninit<u8>, inner = u8);
add_slice_impl!(MaybeUninit<u16>, inner = u16);
add_slice_impl!(MaybeUninit<u32>, inner = u32);
add_slice_impl!(MaybeUninit<u64>, inner = u64);