use alloc::alloc::{alloc, dealloc};
use core::alloc::Layout;
pub struct RawMemory<T> {
memory: *mut T,
}
impl<T> Drop for RawMemory<T> {
fn drop(&mut self) {
unsafe { dealloc(self.memory.cast(), Layout::new::<T>()) }
}
}
impl<T> RawMemory<T> {
pub fn new<F: FnMut(usize) -> u8>(mut fill: F) -> Self {
let layout = Layout::new::<T>();
let memory = unsafe { alloc(layout) };
for i in 0..layout.size() {
unsafe { memory.add(i).write(fill(i)) }
}
Self {
memory: memory.cast(),
}
}
pub fn new_zeroed() -> Self {
Self::new(|_| 0u8)
}
pub fn new_filled(value: u8) -> Self {
Self::new(|_| value)
}
pub fn as_ptr(&self) -> *const T {
self.memory
}
pub fn as_mut_ptr(&self) -> *mut T {
self.memory
}
pub unsafe fn assume_init(&self) -> &T {
unsafe { &*self.memory }
}
pub unsafe fn assume_init_mut(&mut self) -> &mut T {
unsafe { &mut *self.memory }
}
pub fn as_slice(&self) -> &[u8] {
unsafe { core::slice::from_raw_parts(self.memory.cast(), core::mem::size_of::<T>()) }
}
pub fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe { core::slice::from_raw_parts_mut(self.memory.cast(), core::mem::size_of::<T>()) }
}
}