#![cfg(feature = "alloc")]
use crate::prelude::*;
use core::cell::UnsafeCell;
#[derive(Default)]
pub struct Arena {
allocations: UnsafeCell<Vec<*mut [u8]>>,
}
impl Arena {
#[inline]
pub fn new() -> Arena {
Self::default()
}
#[inline]
pub fn clear(&mut self) {
unsafe {
for bytes in (*self.allocations.get()).drain(..) {
drop(Box::from_raw(bytes));
}
}
}
#[inline]
pub fn len(&self) -> usize {
unsafe { (*self.allocations.get()).len() }
}
#[inline]
pub fn add<'a, 'b>(&'a self, bytes: &'b [u8]) -> &'a mut [u8] {
self.add_boxed(Box::from(bytes))
}
#[inline]
pub fn add_vec<'a>(&'a self, bytes: Vec<u8>) -> &'a mut [u8] {
self.add_boxed(bytes.into_boxed_slice())
}
#[inline]
pub fn add_u7<'a, 'b>(&'a self, databytes: &'b [u7]) -> &'a mut [u7] {
unsafe { u7::slice_from_int_unchecked_mut(self.add(u7::slice_as_int(databytes))) }
}
#[inline]
pub fn add_u7_vec<'a>(&'a self, databytes: Vec<u7>) -> &'a mut [u7] {
unsafe {
u7::slice_from_int_unchecked_mut(
self.add_vec(mem::transmute::<Vec<u7>, Vec<u8>>(databytes)),
)
}
}
#[inline]
fn add_boxed<'a>(&'a self, boxed_bytes: Box<[u8]>) -> &'a mut [u8] {
unsafe {
let pointer = Box::into_raw(boxed_bytes);
(*self.allocations.get()).push(pointer);
&mut *pointer
}
}
}
impl Drop for Arena {
#[inline]
fn drop(&mut self) {
self.clear();
}
}
unsafe impl Send for Arena {}
impl fmt::Debug for Arena {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Arena({})", self.len())?;
Ok(())
}
}