use crate::{error::AllocError, Alloc};
use alloc::alloc::Layout;
use core::{
fmt::{Debug, Display, Formatter, Result as FmtResult},
ptr::NonNull,
};
pub trait FallibleDealloc: Alloc {
fn try_dealloc(&self, _: NonNull<u8>, _: Layout) -> Result<(), AllocError>;
fn status(&self, ptr: NonNull<u8>, layout: Layout) -> BlockStatus;
fn owns(&self, p: NonNull<u8>) -> bool;
}
#[must_use]
pub fn ptr_max_align(ptr: NonNull<u8>) -> usize {
let p = ptr.as_ptr() as usize;
p & p.wrapping_neg()
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum BlockStatus {
NotOwnedMisaligned(Option<usize>),
NotOwned,
OwnedNonHead(Option<NonNull<u8>>),
OwnedIncomplete(Option<Layout>),
Misaligned(Option<usize>),
Owned,
}
impl Display for BlockStatus {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
BlockStatus::Owned => write!(f, "owned"),
BlockStatus::Misaligned(Some(max_align)) => {
write!(f, "owned (misaligned, max alignment: {})", max_align)
}
BlockStatus::Misaligned(None) => {
write!(f, "owned (misaligned, max alignment: unknown)")
}
BlockStatus::OwnedIncomplete(Some(layout)) => {
write!(f, "owned (incomplete, full layout: {:?})", layout)
}
BlockStatus::OwnedIncomplete(None) => {
write!(f, "owned (incomplete, full layout: unknown)")
}
BlockStatus::OwnedNonHead(Some(ptr)) => {
write!(f, "owned (non-head, block start: {:p})", *ptr)
}
BlockStatus::OwnedNonHead(None) => write!(f, "owned (non-head, block start: unknown)"),
BlockStatus::NotOwned => write!(f, "not owned"),
BlockStatus::NotOwnedMisaligned(Some(max_align)) => {
write!(f, "not owned (misaligned, max alignment: {})", max_align)
}
BlockStatus::NotOwnedMisaligned(None) => {
write!(f, "not owned (misaligned, max alignment: unknown)")
}
}
}
}