extern crate alloc;
use core::ptr::NonNull;
pub unsafe fn uninitialized_vec<T>(size: usize) -> Result<Vec<T>, String> {
unsafe { aligned_uninitialized_vec::<T, 128>(size, 64) }
}
#[allow(clippy::uninit_vec)]
pub unsafe fn unaligned_uninitialized_vec<T>(size: usize) -> Result<Vec<T>, String> {
let mut v: Vec<T> = vec![];
v.try_reserve_exact(size).map_err(|e| format!("AllocationError: {:?}", e))?;
unsafe { v.set_len(size) };
Ok(v)
}
pub fn aligned_alloc(numbytes: usize, alignment: usize) -> Result<Option<NonNull<()>>, String> {
if numbytes == 0 {
return Ok(None);
}
let layout =
alloc::alloc::Layout::from_size_align(numbytes, alignment).map_err(|e| format!("LayoutError: {:?}", e))?;
let pointer = NonNull::new(unsafe { alloc::alloc::alloc(layout) }).map(|p| p.cast::<()>());
Ok(pointer)
}
#[allow(clippy::uninit_vec)]
pub unsafe fn aligned_uninitialized_vec<T, const N: usize>(size: usize, alignment: usize) -> Result<Vec<T>, String> {
if size == 0 {
Ok(vec![])
} else if size < N {
unsafe { unaligned_uninitialized_vec(size) }
} else {
let sizeof = core::mem::size_of::<T>();
let pointer = aligned_alloc(size * sizeof, alignment)?;
if let Some(pointer) = pointer {
let mut v = unsafe { Vec::from_raw_parts(pointer.as_ptr() as *mut T, size, size) };
unsafe { v.set_len(size) };
Ok(v)
} else {
Err("Allocation failed (probably due to out-of-memory)".to_string())
}
}
}