//! Pooled list data structure. use std::convert::TryFrom; use std::default::Default; use std::fmt::Debug; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; #[derive(Clone, Debug)] pub struct ListPool { storage: Vec, } impl Default for ListPool { fn default() -> Self { ListPool { storage: vec![] } } } #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub struct ListRef(u32, u32, PhantomData); impl Default for ListRef { fn default() -> Self { ListRef(0, 0, PhantomData) } } impl ListPool { pub fn from_iter>(&mut self, iter: I) -> ListRef { let start = u32::try_from(self.storage.len()).unwrap(); self.storage.extend(iter); let end = u32::try_from(self.storage.len()).unwrap(); ListRef(start, end, PhantomData) } pub fn single(&mut self, value: T) -> ListRef { self.from_iter(std::iter::once(value)) } pub fn allocate(&mut self, size: usize, initial: T) -> ListRef { self.from_iter(std::iter::repeat(initial).take(size)) } } impl Index> for ListPool { type Output = [T]; fn index(&self, index: ListRef) -> &[T] { &self.storage[index.0 as usize..index.1 as usize] } } impl IndexMut> for ListPool { fn index_mut(&mut self, index: ListRef) -> &mut [T] { &mut self.storage[index.0 as usize..index.1 as usize] } } impl ListRef { pub fn len(&self) -> usize { (self.1 - self.0) as usize } pub fn is_empty(&self) -> bool { self.len() == 0 } }