use core::{cell::UnsafeCell, mem::MaybeUninit};
use crate::const_init::ConstInit;
#[repr(transparent)]
pub struct GroundedCell<T> {
inner: UnsafeCell<MaybeUninit<T>>,
}
unsafe impl<T> Sync for GroundedCell<T> {}
unsafe impl<T: Send> Send for GroundedCell<T> {}
impl<T: ConstInit> GroundedCell<T> {
pub const fn const_init() -> Self {
Self {
inner: UnsafeCell::new(MaybeUninit::new(T::VAL)),
}
}
}
impl<T> GroundedCell<T> {
pub const fn uninit() -> Self {
Self {
inner: UnsafeCell::new(MaybeUninit::uninit()),
}
}
pub fn get(&self) -> *mut T {
let mu_ptr: *mut MaybeUninit<T> = self.inner.get();
let t_ptr: *mut T = mu_ptr.cast::<T>();
t_ptr
}
}
#[repr(transparent)]
pub struct GroundedArrayCell<T, const N: usize> {
inner: UnsafeCell<MaybeUninit<[T; N]>>,
}
unsafe impl<T: Sync, const N: usize> Sync for GroundedArrayCell<T, N> {}
impl<T: ConstInit, const N: usize> GroundedArrayCell<T, N> {
pub const fn const_init() -> Self {
Self {
inner: UnsafeCell::new(MaybeUninit::new(<[T; N] as ConstInit>::VAL)),
}
}
}
impl<T, const N: usize> GroundedArrayCell<T, N> {
pub const fn uninit() -> Self {
Self {
inner: UnsafeCell::new(MaybeUninit::uninit()),
}
}
#[inline]
pub unsafe fn initialize_all_copied(&self, val: T)
where
T: Copy,
{
let (mut ptr, len) = self.get_ptr_len();
let end = ptr.add(len);
while ptr != end {
ptr.write(val);
ptr = ptr.add(1);
}
}
#[inline]
pub unsafe fn initialize_all_with<F: FnMut() -> T>(&self, mut f: F) {
let (mut ptr, len) = self.get_ptr_len();
let end = ptr.add(len);
while ptr != end {
ptr.write(f());
ptr = ptr.add(1);
}
}
#[inline]
pub fn as_mut_ptr(&self) -> *mut T {
let mu_ptr: *mut MaybeUninit<[T; N]> = self.inner.get();
let arr_ptr: *mut [T; N] = mu_ptr.cast::<[T; N]>();
let t_ptr: *mut T = arr_ptr.cast::<T>();
t_ptr
}
#[inline]
pub fn get_ptr_len(&self) -> (*mut T, usize) {
(self.as_mut_ptr(), N)
}
#[inline]
pub unsafe fn get_element_unchecked(&self, offset: usize) -> &'_ T {
&*self.as_mut_ptr().add(offset)
}
#[allow(clippy::mut_from_ref)]
#[inline]
pub unsafe fn get_element_mut_unchecked(&self, offset: usize) -> &mut T {
&mut *self.as_mut_ptr().add(offset)
}
#[inline]
pub unsafe fn get_subslice_unchecked(&self, offset: usize, len: usize) -> &'_ [T] {
core::slice::from_raw_parts(self.as_mut_ptr().add(offset), len)
}
#[allow(clippy::mut_from_ref)]
#[inline]
pub unsafe fn get_subslice_mut_unchecked(&self, offset: usize, len: usize) -> &'_ mut [T] {
core::slice::from_raw_parts_mut(self.as_mut_ptr().add(offset), len)
}
}