dynvec 0.1.4

This crate provides the `DynVec` type that acts like a vector to store any datatype.
Documentation
use super::{Location, Region};

use std::alloc::Layout;

/// A region that allocates items using the global allocator.
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()
    }
}