1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
#[macro_use] extern crate serde_derive; use std::marker::PhantomData; use std::ops::{Range, Index, IndexMut}; use std::iter::Map; use std::usize::MAX; pub trait Id: Copy + From<usize> + Into<usize> { fn index(&self) -> usize { Into::<usize>::into(*self) } fn is_valid(&self) -> bool { self.index() != MAX } fn is_invalid(&self) -> bool { self.index() == MAX } fn invalid() -> Self { Self::from(MAX) } } pub type IdsIter<I> = Map<Range<usize>, fn(usize) -> I>; #[derive(Debug)] #[derive(Serialize, Deserialize)] pub struct IdVec<I: Id, T> { items: Vec<T>, marker: PhantomData<I>, } impl<I: Id, T> IdVec<I, T> { pub fn new() -> Self { Self::default() } pub fn push(&mut self, item: T) -> I { self.items.push(item); I::from(self.len() - 1) } pub fn len(&self) -> usize { self.items.len() } pub fn ids(&self) -> IdsIter<I> { (0 .. self.len()).map(I::from) } pub fn items(&self) -> &[T] { &self.items } } impl<I: Id, T> Index<I> for IdVec<I, T> { type Output = T; fn index(&self, id: I) -> &Self::Output { &self.items[id.index()] } } impl<I: Id, T> IndexMut<I> for IdVec<I, T> { fn index_mut(&mut self, id: I) -> &mut Self::Output { &mut self.items[id.index()] } } impl<I: Id, T> Default for IdVec<I, T> { fn default() -> Self { Self { items: Default::default(), marker: Default::default(), } } } impl<I: Id, T> From<Vec<T>> for IdVec<I, T> { fn from(items: Vec<T>) -> Self { Self { items: items, marker: Default::default(), } } } impl<I: Id, T> Into<Vec<T>> for IdVec<I, T> { fn into(self) -> Vec<T> { self.items } } #[macro_export] macro_rules! create_id { ($id: ident) => { #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Serialize, Deserialize)] pub struct $id(pub usize); impl $crate::Id for $id {} impl From<usize> for $id { fn from(index: usize) -> Self { $id(index) } } impl Into<usize> for $id { fn into(self) -> usize { self.0 } } impl Default for $id { fn default() -> Self { $crate::Id::invalid() } } } } create_id!(Test);