1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
#![no_std] #[cfg(feature = "alloc")] extern crate alloc; pub mod prelude { pub use super::a::Allocator; #[cfg(feature = "alloc")] pub use super::a::AllocatorAwareContainer; } pub mod a { #[cfg(feature = "alloc")] use alloc::rc::Rc; use core::{cell::RefCell, mem, mem::MaybeUninit, ptr::NonNull}; #[cfg(feature = "alloc")] pub trait AllocatorAwareContainer { fn allocator(&self) -> Rc<RefCell<dyn Allocator>>; } pub type Ptr<T> = Option<NonNull<T>>; pub type PtrUninit<T> = Ptr<MaybeUninit<T>>; pub trait Allocator { unsafe fn allocate(&mut self, size: usize, align: usize) -> PtrUninit<()>; unsafe fn deallocate(&mut self, pointer: *mut (), size: usize, align: usize); } pub unsafe fn allocate<T>(alloc: &RefCell<dyn Allocator>, num_objects: usize) -> PtrUninit<T> { alloc .borrow_mut() .allocate(mem::size_of::<T>() * num_objects, mem::align_of::<T>()) .map(NonNull::cast::<MaybeUninit<T>>) } pub unsafe fn deallocate<T>( alloc: &RefCell<dyn Allocator>, pointer: *mut T, num_objects: usize, ) { alloc.borrow_mut().deallocate( pointer as *mut (), mem::size_of::<T>() * num_objects, mem::align_of::<T>(), ) } }