#![no_std]
#![deny(missing_docs)]
mod layout;
use core::fmt;
use core::marker::PhantomData;
use core::ptr::{copy_nonoverlapping, write_bytes, NonNull};
pub use layout::{Layout, NonZeroLayout};
#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Invariant<'lt> {
marker: PhantomData<&'lt fn(&'lt ())>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Allocation<'alloc> {
pub ptr: NonNull<u8>,
pub layout: NonZeroLayout,
pub lifetime: Invariant<'alloc>,
}
pub unsafe trait LocalAlloc<'alloc> {
fn alloc(&'alloc self, layout: NonZeroLayout) -> Option<Allocation<'alloc>>;
unsafe fn dealloc(&'alloc self, alloc: Allocation<'alloc>);
fn alloc_zeroed(&'alloc self, layout: NonZeroLayout)
-> Option<Allocation<'alloc>>
{
let allocation = self.alloc(layout)?;
unsafe {
write_bytes(allocation.ptr.as_ptr(), 0u8, allocation.layout.size().into());
}
Some(allocation)
}
unsafe fn realloc(&'alloc self, alloc: Allocation<'alloc>, layout: NonZeroLayout)
-> Option<Allocation<'alloc>>
{
let new_alloc = self.alloc(layout)?;
copy_nonoverlapping(
alloc.ptr.as_ptr(),
new_alloc.ptr.as_ptr(),
layout.size().min(alloc.layout.size()).into());
Some(new_alloc)
}
}
impl fmt::Debug for Invariant<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Invariant")
}
}