use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Index, IndexMut};
pub mod id;
mod iter;
pub mod span;
pub(crate) use iter::Node;
use span::Span;
#[derive(Debug, PartialEq)]
pub struct Arena<T, I> {
pub(super) inner: Vec<T>,
_marker: PhantomData<I>,
}
impl<T, I: From<usize>> Arena<T, I> {
pub fn new() -> Self {
Self {
inner: Vec::new(),
_marker: PhantomData,
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
inner: Vec::with_capacity(capacity),
_marker: PhantomData,
}
}
pub unsafe fn index_of(&self, item: &T) -> I {
let list_ptr_range = self.inner.as_ptr_range();
let ptr = std::ptr::from_ref(item);
assert!(list_ptr_range.contains(&ptr));
let index = unsafe { ptr.offset_from_unsigned(list_ptr_range.start) };
I::from(index)
}
pub fn iter_from<'a>(&'a self, from: I) -> iter::ArenaIterator<'a, T, I> {
iter::ArenaIterator::new(self, from)
}
}
impl<T, I: From<usize>> Default for Arena<T, I> {
fn default() -> Self {
Self::new()
}
}
impl<T, I> Deref for Arena<T, I> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T, I> DerefMut for Arena<T, I> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<T> Index<Span<u32>> for Arena<T, u32> {
type Output = [T];
fn index(&self, index: Span<u32>) -> &Self::Output {
&self.inner[std::ops::Range::from(index)]
}
}
impl<T, I: Into<usize>> Index<I> for Arena<T, I> {
type Output = T;
fn index(&self, index: I) -> &Self::Output {
&self.inner[index.into()]
}
}
impl<T, I: Into<usize>> IndexMut<I> for Arena<T, I> {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
&mut self.inner[index.into()]
}
}