pub use alloc_def::Global;
#[cfg(feature = "alloc_unstable")]
mod alloc_def {
pub use std::alloc::Global;
}
#[cfg(not(feature = "alloc_unstable"))]
mod alloc_def {
use core::ptr;
use core::ptr::NonNull;
use std::alloc;
use std::alloc::Layout;
use crate::alloc::AllocError;
use crate::alloc::AltAllocator;
#[derive(Debug, Copy, Clone)]
pub struct Global;
unsafe impl AltAllocator for Global {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
if layout.size() == 0 {
return Err(AllocError);
};
let ptr = unsafe { alloc::alloc(layout) };
let Some(ptr) = NonNull::new(ptr) else {
return Err(AllocError);
};
return Ok(NonNull::slice_from_raw_parts(ptr, layout.size()));
}
fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
if layout.size() == 0 {
return Err(AllocError);
};
let ptr = unsafe { alloc::alloc_zeroed(layout) };
let Some(ptr) = NonNull::new(ptr) else {
return Err(AllocError);
};
return Ok(NonNull::slice_from_raw_parts(ptr, layout.size()));
}
unsafe fn deallocate(&self, ptr: ptr::NonNull<u8>, layout: Layout) {
unsafe { alloc::dealloc(ptr.as_ptr(), layout) };
}
unsafe fn grow(
&self,
old_ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
if new_layout.size() == 0 {
return Err(AllocError);
}
let new = unsafe { alloc::realloc(old_ptr.as_ptr(), old_layout, new_layout.size()) };
let Some(new) = NonNull::new(new) else {
return Err(AllocError);
};
return Ok(NonNull::slice_from_raw_parts(new, new_layout.size()));
}
unsafe fn grow_zeroed(
&self,
old_ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
let old_sz = old_layout.size();
let new_sz = new_layout.size();
if old_sz == 0 {
return self.allocate_zeroed(new_layout);
}
if new_sz <= old_sz {
return Ok(NonNull::slice_from_raw_parts(old_ptr, old_layout.size()));
}
let new = unsafe { alloc::realloc(old_ptr.as_ptr(), old_layout, new_layout.size()) };
let Some(new) = NonNull::new(new) else {
return Err(AllocError);
};
let start = unsafe { new.add(old_sz) };
unsafe {
start.write_bytes(0, new_sz - old_sz);
};
return Ok(NonNull::slice_from_raw_parts(new, new_layout.size()));
}
unsafe fn shrink(
&self,
old_ptr: NonNull<u8>,
old_layout: Layout,
new_layout: Layout,
) -> Result<NonNull<[u8]>, AllocError> {
if new_layout.size() == 0 {
return Err(AllocError);
}
let new = unsafe { alloc::realloc(old_ptr.as_ptr(), old_layout, new_layout.size()) };
let Some(new) = NonNull::new(new) else {
return Err(AllocError);
};
return Ok(NonNull::slice_from_raw_parts(new, new_layout.size()));
}
}
}