use std::alloc::Layout;
use super::{align_to, TempArena};
pub struct Array<'t, T> {
arena: &'t mut TempArena,
count: usize,
start: usize,
phantom: std::marker::PhantomData<T>,
}
impl<'t, T> Array<'t, T> {
pub fn new(arena: &'t mut TempArena) -> Self {
let start = {
let memory = arena.memory.borrow();
let layout = Layout::new::<T>();
align_to(memory.next, layout.align())
};
Self {
arena,
start,
count: 0,
phantom: std::marker::PhantomData,
}
}
pub fn push(&mut self, value: T) {
self.arena.push(value);
self.count += 1;
}
pub const fn len(&self) -> usize {
self.count
}
pub fn end(self) -> &'t mut [T] {
unsafe { std::slice::from_raw_parts_mut(self.start as *mut T, self.count) }
}
}
impl<'t, T> std::ops::Index<usize> for Array<'t, T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
assert!(
index < self.count,
"Invalid index({}). Array has {} item(s).",
index,
self.count
);
unsafe {
let ptr = self.start as *const T;
&*ptr.add(index)
}
}
}
impl<'t, T> std::ops::IndexMut<usize> for Array<'t, T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
assert!(
index < self.count,
"Invalid index({}). Array has {} item(s).",
index,
self.count
);
unsafe {
let ptr = self.start as *mut T;
&mut *ptr.add(index)
}
}
}