use crate::common::*; use core::hash::Hash; use core::marker::PhantomData; #[derive(serde::Serialize, serde::Deserialize)] pub struct Id { pub(crate) index: u32, _phantom: PhantomData, } impl Id { pub(crate) fn new(index: u32) -> Self { Self{ index, _phantom: Default::default() } } } #[derive(Debug, serde::Serialize, serde::Deserialize)] pub(crate) struct Arena { store: Vec, } ////////////////////////////////// impl Debug for Id { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { f.debug_struct("Id").field("index", &self.index).finish() } } impl Clone for Id { fn clone(&self) -> Self { *self } } impl Copy for Id {} impl PartialEq for Id { fn eq(&self, other: &Self) -> bool { self.index.eq(&other.index) } } impl Eq for Id {} impl Hash for Id { fn hash(&self, h: &mut H) { self.index.hash(h); } } impl Arena { pub fn new() -> Self { Self { store: vec![] } } pub fn alloc_with_id(&mut self, f: impl FnOnce(Id) -> T) -> Id { use std::convert::TryFrom; let id = Id::new(u32::try_from(self.store.len()).expect("Out of capacity!")); self.store.push(f(id)); id } pub fn iter(&self) -> impl Iterator { self.store.iter() } pub fn len(&self) -> usize { self.store.len() } } impl core::ops::Index> for Arena { type Output = T; fn index(&self, id: Id) -> &Self::Output { self.store.index(id.index as usize) } } impl core::ops::IndexMut> for Arena { fn index_mut(&mut self, id: Id) -> &mut Self::Output { self.store.index_mut(id.index as usize) } }