use core::marker::PhantomData;
use core::ptr::NonNull;
pub(crate) struct UninitSlot<T: ?Sized> {
ptr: NonNull<T>,
_marker: PhantomData<*mut T>,
}
impl<T> UninitSlot<T> {
#[inline]
pub(crate) const unsafe fn new(ptr: NonNull<T>) -> Self {
Self { ptr, _marker: PhantomData }
}
#[inline]
pub(crate) const unsafe fn from_raw(ptr: *mut T) -> Self {
let nn = unsafe { NonNull::new_unchecked(ptr) };
unsafe { Self::new(nn) }
}
#[inline]
pub(crate) fn write_unaligned(self, value: T) -> NonNull<T> {
unsafe { core::ptr::write_unaligned(self.ptr.as_ptr(), value) };
self.ptr
}
}
#[cfg(test)]
mod tests {
use super::UninitSlot;
#[test]
fn write_unaligned_initializes_slot() {
let mut bytes = [0_u8; 16];
#[allow(
clippy::cast_ptr_alignment,
reason = "intentionally misaligned to exercise UninitSlot::write_unaligned"
)]
let ptr: *mut u64 = unsafe { bytes.as_mut_ptr().add(1).cast::<u64>() };
let slot = unsafe { UninitSlot::<u64>::from_raw(ptr) };
let _ = slot.write_unaligned(0x0102_0304_0506_0708);
let read = unsafe { core::ptr::read_unaligned(ptr) };
assert_eq!(read, 0x0102_0304_0506_0708);
}
}