1 //! Yet another index-based arena.
10 ops::{Index, IndexMut},
14 pub use map::ArenaMap;
16 /// The raw index of a value in an arena.
17 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
18 pub struct RawIdx(u32);
20 impl From<RawIdx> for u32 {
21 fn from(raw: RawIdx) -> u32 {
26 impl From<u32> for RawIdx {
27 fn from(idx: u32) -> RawIdx {
32 impl fmt::Debug for RawIdx {
33 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 impl fmt::Display for RawIdx {
39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44 /// The index of a value allocated in an arena that holds `T`s.
47 _ty: PhantomData<fn() -> T>,
50 impl<T> Clone for Idx<T> {
51 fn clone(&self) -> Self {
55 impl<T> Copy for Idx<T> {}
57 impl<T> PartialEq for Idx<T> {
58 fn eq(&self, other: &Idx<T>) -> bool {
62 impl<T> Eq for Idx<T> {}
64 impl<T> Hash for Idx<T> {
65 fn hash<H: Hasher>(&self, state: &mut H) {
70 impl<T> fmt::Debug for Idx<T> {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 let mut type_name = std::any::type_name::<T>();
73 if let Some(idx) = type_name.rfind(':') {
74 type_name = &type_name[idx + 1..]
76 write!(f, "Idx::<{}>({})", type_name, self.raw)
81 /// Creates a new index from a [`RawIdx`].
82 pub fn from_raw(raw: RawIdx) -> Self {
83 Idx { raw, _ty: PhantomData }
86 /// Converts this index into the underlying [`RawIdx`].
87 pub fn into_raw(self) -> RawIdx {
92 /// Yet another index-based arena.
93 #[derive(Clone, PartialEq, Eq, Hash)]
98 impl<T: fmt::Debug> fmt::Debug for Arena<T> {
99 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
100 fmt.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish()
105 /// Creates a new empty arena.
108 /// let arena: la_arena::Arena<i32> = la_arena::Arena::new();
109 /// assert!(arena.is_empty());
111 pub const fn new() -> Arena<T> {
112 Arena { data: Vec::new() }
115 /// Empties the arena, removing all contained values.
118 /// let mut arena = la_arena::Arena::new();
123 /// assert_eq!(arena.len(), 3);
126 /// assert!(arena.is_empty());
128 pub fn clear(&mut self) {
132 /// Returns the length of the arena.
135 /// let mut arena = la_arena::Arena::new();
136 /// assert_eq!(arena.len(), 0);
138 /// arena.alloc("foo");
139 /// assert_eq!(arena.len(), 1);
141 /// arena.alloc("bar");
142 /// assert_eq!(arena.len(), 2);
144 /// arena.alloc("baz");
145 /// assert_eq!(arena.len(), 3);
147 pub fn len(&self) -> usize {
151 /// Returns whether the arena contains no elements.
154 /// let mut arena = la_arena::Arena::new();
155 /// assert!(arena.is_empty());
157 /// arena.alloc(0.5);
158 /// assert!(!arena.is_empty());
160 pub fn is_empty(&self) -> bool {
164 /// Allocates a new value on the arena, returning the value’s index.
167 /// let mut arena = la_arena::Arena::new();
168 /// let idx = arena.alloc(50);
170 /// assert_eq!(arena[idx], 50);
172 pub fn alloc(&mut self, value: T) -> Idx<T> {
173 let idx = RawIdx(self.data.len() as u32);
174 self.data.push(value);
178 /// Returns an iterator over the arena’s elements.
181 /// let mut arena = la_arena::Arena::new();
182 /// let idx1 = arena.alloc(20);
183 /// let idx2 = arena.alloc(40);
184 /// let idx3 = arena.alloc(60);
186 /// let mut iterator = arena.iter();
187 /// assert_eq!(iterator.next(), Some((idx1, &20)));
188 /// assert_eq!(iterator.next(), Some((idx2, &40)));
189 /// assert_eq!(iterator.next(), Some((idx3, &60)));
193 ) -> impl Iterator<Item = (Idx<T>, &T)> + ExactSizeIterator + DoubleEndedIterator {
194 self.data.iter().enumerate().map(|(idx, value)| (Idx::from_raw(RawIdx(idx as u32)), value))
197 /// Returns an iterator over the arena’s mutable elements.
200 /// let mut arena = la_arena::Arena::new();
201 /// let idx1 = arena.alloc(20);
203 /// assert_eq!(arena[idx1], 20);
205 /// let mut iterator = arena.iter_mut();
206 /// *iterator.next().unwrap().1 = 10;
209 /// assert_eq!(arena[idx1], 10);
213 ) -> impl Iterator<Item = (Idx<T>, &mut T)> + ExactSizeIterator + DoubleEndedIterator {
217 .map(|(idx, value)| (Idx::from_raw(RawIdx(idx as u32)), value))
220 /// Reallocates the arena to make it take up as little space as possible.
221 pub fn shrink_to_fit(&mut self) {
222 self.data.shrink_to_fit();
226 impl<T> Default for Arena<T> {
227 fn default() -> Arena<T> {
228 Arena { data: Vec::new() }
232 impl<T> Index<Idx<T>> for Arena<T> {
234 fn index(&self, idx: Idx<T>) -> &T {
235 let idx = idx.into_raw().0 as usize;
240 impl<T> IndexMut<Idx<T>> for Arena<T> {
241 fn index_mut(&mut self, idx: Idx<T>) -> &mut T {
242 let idx = idx.into_raw().0 as usize;
247 impl<T> FromIterator<T> for Arena<T> {
248 fn from_iter<I>(iter: I) -> Self
250 I: IntoIterator<Item = T>,
252 Arena { data: Vec::from_iter(iter) }