use std::{ marker::PhantomData, ops::{Index, IndexMut}, }; #[derive(Clone, Debug)] pub(crate) struct Arena { data: Vec, _ty: PhantomData, } pub(crate) trait ArenaId { fn from_u32(id: u32) -> Self; fn to_u32(self) -> u32; } impl Arena { pub fn alloc(&mut self, value: T) -> ID { let id = self.data.len() as u32; self.data.push(value); ID::from_u32(id) } pub fn iter<'a>(&'a self) -> impl Iterator { self.data .iter() .enumerate() .map(|(idx, value)| (ID::from_u32(idx as u32), value)) } } impl Default for Arena { fn default() -> Arena { Arena { data: Vec::new(), _ty: PhantomData, } } } impl Index for Arena { type Output = T; fn index(&self, idx: ID) -> &T { let idx = idx.to_u32() as usize; &self.data[idx] } } impl IndexMut for Arena { fn index_mut(&mut self, idx: ID) -> &mut T { let idx = idx.to_u32() as usize; &mut self.data[idx] } }