use core::alloc::{GlobalAlloc, Layout};
use core::{cmp, ptr};
pub struct PtrAndMeta<M> {
pub ptr: *mut u8,
pub meta: M,
}
pub unsafe trait GlobalCoAlloc<M>: GlobalAlloc {
unsafe fn co_alloc(&self, layout: Layout) -> PtrAndMeta<M>;
unsafe fn co_dealloc(&self, ptr_and_meta: PtrAndMeta<M>, layout: Layout);
unsafe fn co_alloc_zeroed(&self, layout: Layout) -> PtrAndMeta<M> {
let size = layout.size();
let ptr_and_meta = unsafe { self.co_alloc(layout) };
if !ptr_and_meta.ptr.is_null() {
unsafe { ptr::write_bytes(ptr_and_meta.ptr, 0, size) };
}
ptr_and_meta
}
unsafe fn co_realloc(
&self,
ptr_and_meta: PtrAndMeta<M>,
layout: Layout,
new_size: usize,
) -> PtrAndMeta<M> {
let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
let new_ptr_and_meta = unsafe { self.co_alloc(new_layout) };
if !new_ptr_and_meta.ptr.is_null() {
unsafe {
ptr::copy_nonoverlapping(
ptr_and_meta.ptr,
new_ptr_and_meta.ptr,
cmp::min(layout.size(), new_size),
);
self.co_dealloc(ptr_and_meta, layout);
}
}
new_ptr_and_meta
}
}