use super::{Location, Region};
use std::alloc::Layout;
pub struct Global<H> {
locations: Vec<Location<H>>,
}
impl<H> Default for Global<H> {
fn default() -> Self {
Self {
locations: Vec::default(),
}
}
}
impl<H> Region<H> for Global<H> {
type Pointers = std::vec::IntoIter<*mut u8>;
fn allocate(&mut self, layout: Layout, header: H) -> Result<*mut u8, H> {
let ptr = unsafe { std::alloc::alloc(layout) };
if ptr.is_null() {
Err(header)
} else {
self.locations.push(Location {
ptr,
header,
layout,
});
Ok(ptr)
}
}
fn deallocate(&mut self, ptr: *mut u8) -> Option<H> {
match self.locations.iter().position(|loc| loc.ptr == ptr) {
Some(idx) => {
let loc = self.locations.remove(idx);
unsafe { std::alloc::dealloc(loc.ptr, loc.layout) };
Some(loc.header)
}
None => None,
}
}
fn has_allocated(&self, ptr: *mut u8) -> bool {
self.locations.iter().any(|loc| loc.ptr == ptr)
}
fn count(&self) -> usize {
self.locations.len()
}
fn allocations(&self) -> Self::Pointers {
self.locations
.iter()
.map(|loc| loc.ptr)
.collect::<Vec<*mut u8>>()
.into_iter()
}
}