use std::cell::UnsafeCell;
use std::ops::Index;
#[derive(Copy, Clone, Debug)]
pub(crate) struct UnsafeSlice<'a, T> {
slice: &'a [UnsafeCell<T>],
}
unsafe impl<T: Send + Sync> Send for UnsafeSlice<'_, T> {}
unsafe impl<T: Send + Sync> Sync for UnsafeSlice<'_, T> {}
impl<'a, T> UnsafeSlice<'a, T> {
pub(crate) fn new(slice: &'a mut [T]) -> Self {
let ptr = slice as *mut [T] as *const [UnsafeCell<T>];
Self {
slice: unsafe { &*ptr },
}
}
#[inline(always)]
pub(crate) unsafe fn write(&self, i: usize, value: T) {
let ptr = unsafe { self.slice.get_unchecked(i) }.get();
unsafe {
*ptr = value;
}
}
#[inline(always)]
#[allow(clippy::mut_from_ref)]
pub(crate) fn get(&self, i: usize) -> &mut T {
let ptr = unsafe { self.slice.get_unchecked(i) }.get();
unsafe { &mut *ptr }
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) fn get_ptr(&self, i: usize) -> *mut T {
unsafe { self.slice.get_unchecked(i) }.get()
}
#[allow(dead_code)]
#[inline(always)]
pub(crate) fn len(&self) -> usize {
self.slice.len()
}
}
impl<T> Index<usize> for UnsafeSlice<'_, T> {
type Output = T;
#[allow(dead_code)]
#[inline(always)]
fn index(&self, index: usize) -> &Self::Output {
let ptr = unsafe { self.slice.get_unchecked(index) }.get();
unsafe { &*ptr }
}
}