la_arena/
lib.rs

1//! Yet another index-based arena.
2
3#![warn(rust_2018_idioms, unused_lifetimes)]
4#![warn(missing_docs)]
5
6use std::{
7    cmp, fmt,
8    hash::{Hash, Hasher},
9    iter::{Enumerate, FusedIterator},
10    marker::PhantomData,
11    ops::{Index, IndexMut, Range, RangeInclusive},
12};
13
14mod map;
15pub use map::{ArenaMap, Entry, OccupiedEntry, VacantEntry};
16
17/// The raw index of a value in an arena.
18#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct RawIdx(u32);
20
21impl RawIdx {
22    /// Constructs a [`RawIdx`] from a u32.
23    pub const fn from_u32(u32: u32) -> Self {
24        RawIdx(u32)
25    }
26
27    /// Deconstructs a [`RawIdx`] into the underlying u32.
28    pub const fn into_u32(self) -> u32 {
29        self.0
30    }
31}
32
33impl From<RawIdx> for u32 {
34    #[inline]
35    fn from(raw: RawIdx) -> u32 {
36        raw.0
37    }
38}
39
40impl From<u32> for RawIdx {
41    #[inline]
42    fn from(idx: u32) -> RawIdx {
43        RawIdx(idx)
44    }
45}
46
47impl fmt::Debug for RawIdx {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        self.0.fmt(f)
50    }
51}
52
53impl fmt::Display for RawIdx {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        self.0.fmt(f)
56    }
57}
58
59/// The index of a value allocated in an arena that holds `T`s.
60pub struct Idx<T> {
61    raw: RawIdx,
62    _ty: PhantomData<fn() -> T>,
63}
64
65impl<T> Ord for Idx<T> {
66    fn cmp(&self, other: &Self) -> cmp::Ordering {
67        self.raw.cmp(&other.raw)
68    }
69}
70
71impl<T> PartialOrd for Idx<T> {
72    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
73        Some(self.cmp(other))
74    }
75}
76
77impl<T> Clone for Idx<T> {
78    fn clone(&self) -> Self {
79        *self
80    }
81}
82impl<T> Copy for Idx<T> {}
83
84impl<T> PartialEq for Idx<T> {
85    fn eq(&self, other: &Idx<T>) -> bool {
86        self.raw == other.raw
87    }
88}
89impl<T> Eq for Idx<T> {}
90
91impl<T> Hash for Idx<T> {
92    fn hash<H: Hasher>(&self, state: &mut H) {
93        self.raw.hash(state);
94    }
95}
96
97impl<T> fmt::Debug for Idx<T> {
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        let mut type_name = std::any::type_name::<T>();
100        if let Some(idx) = type_name.rfind(':') {
101            type_name = &type_name[idx + 1..];
102        }
103        write!(f, "Idx::<{}>({})", type_name, self.raw)
104    }
105}
106
107impl<T> Idx<T> {
108    /// Creates a new index from a [`RawIdx`].
109    pub const fn from_raw(raw: RawIdx) -> Self {
110        Idx { raw, _ty: PhantomData }
111    }
112
113    /// Converts this index into the underlying [`RawIdx`].
114    pub const fn into_raw(self) -> RawIdx {
115        self.raw
116    }
117}
118
119/// A range of densely allocated arena values.
120pub struct IdxRange<T> {
121    range: Range<u32>,
122    _p: PhantomData<T>,
123}
124
125impl<T> IdxRange<T> {
126    /// Creates a new index range
127    /// inclusive of the start value and exclusive of the end value.
128    ///
129    /// ```
130    /// let mut arena = la_arena::Arena::new();
131    /// let a = arena.alloc("a");
132    /// let b = arena.alloc("b");
133    /// let c = arena.alloc("c");
134    /// let d = arena.alloc("d");
135    ///
136    /// let range = la_arena::IdxRange::new(b..d);
137    /// assert_eq!(&arena[range], &["b", "c"]);
138    /// ```
139    pub fn new(range: Range<Idx<T>>) -> Self {
140        Self { range: range.start.into_raw().into()..range.end.into_raw().into(), _p: PhantomData }
141    }
142
143    /// Creates a new index range
144    /// inclusive of the start value and end value.
145    ///
146    /// ```
147    /// let mut arena = la_arena::Arena::new();
148    /// let foo = arena.alloc("foo");
149    /// let bar = arena.alloc("bar");
150    /// let baz = arena.alloc("baz");
151    ///
152    /// let range = la_arena::IdxRange::new_inclusive(foo..=baz);
153    /// assert_eq!(&arena[range], &["foo", "bar", "baz"]);
154    ///
155    /// let range = la_arena::IdxRange::new_inclusive(foo..=foo);
156    /// assert_eq!(&arena[range], &["foo"]);
157    /// ```
158    pub fn new_inclusive(range: RangeInclusive<Idx<T>>) -> Self {
159        Self {
160            range: u32::from(range.start().into_raw())..u32::from(range.end().into_raw()) + 1,
161            _p: PhantomData,
162        }
163    }
164
165    /// Returns whether the index range is empty.
166    ///
167    /// ```
168    /// let mut arena = la_arena::Arena::new();
169    /// let one = arena.alloc(1);
170    /// let two = arena.alloc(2);
171    ///
172    /// assert!(la_arena::IdxRange::new(one..one).is_empty());
173    /// ```
174    pub fn is_empty(&self) -> bool {
175        self.range.is_empty()
176    }
177
178    /// Returns the start of the index range.
179    pub fn start(&self) -> Idx<T> {
180        Idx::from_raw(RawIdx::from(self.range.start))
181    }
182
183    /// Returns the end of the index range.
184    pub fn end(&self) -> Idx<T> {
185        Idx::from_raw(RawIdx::from(self.range.end))
186    }
187}
188
189impl<T> Iterator for IdxRange<T> {
190    type Item = Idx<T>;
191
192    fn next(&mut self) -> Option<Self::Item> {
193        self.range.next().map(|raw| Idx::from_raw(raw.into()))
194    }
195
196    fn size_hint(&self) -> (usize, Option<usize>) {
197        self.range.size_hint()
198    }
199
200    fn count(self) -> usize
201    where
202        Self: Sized,
203    {
204        self.range.count()
205    }
206
207    fn last(self) -> Option<Self::Item>
208    where
209        Self: Sized,
210    {
211        self.range.last().map(|raw| Idx::from_raw(raw.into()))
212    }
213
214    fn nth(&mut self, n: usize) -> Option<Self::Item> {
215        self.range.nth(n).map(|raw| Idx::from_raw(raw.into()))
216    }
217}
218
219impl<T> DoubleEndedIterator for IdxRange<T> {
220    fn next_back(&mut self) -> Option<Self::Item> {
221        self.range.next_back().map(|raw| Idx::from_raw(raw.into()))
222    }
223}
224
225impl<T> ExactSizeIterator for IdxRange<T> {}
226
227impl<T> FusedIterator for IdxRange<T> {}
228
229impl<T> fmt::Debug for IdxRange<T> {
230    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231        f.debug_tuple(&format!("IdxRange::<{}>", std::any::type_name::<T>()))
232            .field(&self.range)
233            .finish()
234    }
235}
236
237impl<T> Clone for IdxRange<T> {
238    fn clone(&self) -> Self {
239        Self { range: self.range.clone(), _p: PhantomData }
240    }
241}
242
243impl<T> PartialEq for IdxRange<T> {
244    fn eq(&self, other: &Self) -> bool {
245        self.range == other.range
246    }
247}
248
249impl<T> Eq for IdxRange<T> {}
250
251/// Yet another index-based arena.
252#[derive(Clone, PartialEq, Eq, Hash)]
253pub struct Arena<T> {
254    data: Vec<T>,
255}
256
257impl<T: fmt::Debug> fmt::Debug for Arena<T> {
258    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
259        fmt.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish()
260    }
261}
262
263impl<T> Arena<T> {
264    /// Creates a new empty arena.
265    ///
266    /// ```
267    /// let arena: la_arena::Arena<i32> = la_arena::Arena::new();
268    /// assert!(arena.is_empty());
269    /// ```
270    pub const fn new() -> Arena<T> {
271        Arena { data: Vec::new() }
272    }
273
274    /// Create a new empty arena with specific capacity.
275    ///
276    /// ```
277    /// let arena: la_arena::Arena<i32> = la_arena::Arena::with_capacity(42);
278    /// assert!(arena.is_empty());
279    /// ```
280    pub fn with_capacity(capacity: usize) -> Arena<T> {
281        Arena { data: Vec::with_capacity(capacity) }
282    }
283
284    /// Empties the arena, removing all contained values.
285    ///
286    /// ```
287    /// let mut arena = la_arena::Arena::new();
288    ///
289    /// arena.alloc(1);
290    /// arena.alloc(2);
291    /// arena.alloc(3);
292    /// assert_eq!(arena.len(), 3);
293    ///
294    /// arena.clear();
295    /// assert!(arena.is_empty());
296    /// ```
297    pub fn clear(&mut self) {
298        self.data.clear();
299    }
300
301    /// Returns the length of the arena.
302    ///
303    /// ```
304    /// let mut arena = la_arena::Arena::new();
305    /// assert_eq!(arena.len(), 0);
306    ///
307    /// arena.alloc("foo");
308    /// assert_eq!(arena.len(), 1);
309    ///
310    /// arena.alloc("bar");
311    /// assert_eq!(arena.len(), 2);
312    ///
313    /// arena.alloc("baz");
314    /// assert_eq!(arena.len(), 3);
315    /// ```
316    pub fn len(&self) -> usize {
317        self.data.len()
318    }
319
320    /// Returns whether the arena contains no elements.
321    ///
322    /// ```
323    /// let mut arena = la_arena::Arena::new();
324    /// assert!(arena.is_empty());
325    ///
326    /// arena.alloc(0.5);
327    /// assert!(!arena.is_empty());
328    /// ```
329    pub fn is_empty(&self) -> bool {
330        self.data.is_empty()
331    }
332
333    /// Allocates a new value on the arena, returning the value’s index.
334    ///
335    /// ```
336    /// let mut arena = la_arena::Arena::new();
337    /// let idx = arena.alloc(50);
338    ///
339    /// assert_eq!(arena[idx], 50);
340    /// ```
341    pub fn alloc(&mut self, value: T) -> Idx<T> {
342        let idx = self.next_idx();
343        self.data.push(value);
344        idx
345    }
346
347    /// Densely allocates multiple values, returning the values’ index range.
348    ///
349    /// ```
350    /// let mut arena = la_arena::Arena::new();
351    /// let range = arena.alloc_many(0..4);
352    ///
353    /// assert_eq!(arena[range], [0, 1, 2, 3]);
354    /// ```
355    pub fn alloc_many<II: IntoIterator<Item = T>>(&mut self, iter: II) -> IdxRange<T> {
356        let start = self.next_idx();
357        self.extend(iter);
358        let end = self.next_idx();
359        IdxRange::new(start..end)
360    }
361
362    /// Returns an iterator over the arena’s elements.
363    ///
364    /// ```
365    /// let mut arena = la_arena::Arena::new();
366    /// let idx1 = arena.alloc(20);
367    /// let idx2 = arena.alloc(40);
368    /// let idx3 = arena.alloc(60);
369    ///
370    /// let mut iterator = arena.iter();
371    /// assert_eq!(iterator.next(), Some((idx1, &20)));
372    /// assert_eq!(iterator.next(), Some((idx2, &40)));
373    /// assert_eq!(iterator.next(), Some((idx3, &60)));
374    /// ```
375    pub fn iter(
376        &self,
377    ) -> impl ExactSizeIterator<Item = (Idx<T>, &T)> + DoubleEndedIterator + Clone {
378        self.data.iter().enumerate().map(|(idx, value)| (Idx::from_raw(RawIdx(idx as u32)), value))
379    }
380
381    /// Returns an iterator over the arena’s mutable elements.
382    ///
383    /// ```
384    /// let mut arena = la_arena::Arena::new();
385    /// let idx1 = arena.alloc(20);
386    ///
387    /// assert_eq!(arena[idx1], 20);
388    ///
389    /// let mut iterator = arena.iter_mut();
390    /// *iterator.next().unwrap().1 = 10;
391    /// drop(iterator);
392    ///
393    /// assert_eq!(arena[idx1], 10);
394    /// ```
395    pub fn iter_mut(
396        &mut self,
397    ) -> impl ExactSizeIterator<Item = (Idx<T>, &mut T)> + DoubleEndedIterator {
398        self.data
399            .iter_mut()
400            .enumerate()
401            .map(|(idx, value)| (Idx::from_raw(RawIdx(idx as u32)), value))
402    }
403
404    /// Returns an iterator over the arena’s values.
405    ///
406    /// ```
407    /// let mut arena = la_arena::Arena::new();
408    /// let idx1 = arena.alloc(20);
409    /// let idx2 = arena.alloc(40);
410    /// let idx3 = arena.alloc(60);
411    ///
412    /// let mut iterator = arena.values();
413    /// assert_eq!(iterator.next(), Some(&20));
414    /// assert_eq!(iterator.next(), Some(&40));
415    /// assert_eq!(iterator.next(), Some(&60));
416    /// ```
417    pub fn values(&self) -> impl ExactSizeIterator<Item = &T> + DoubleEndedIterator {
418        self.data.iter()
419    }
420
421    /// Returns an iterator over the arena’s mutable values.
422    ///
423    /// ```
424    /// let mut arena = la_arena::Arena::new();
425    /// let idx1 = arena.alloc(20);
426    ///
427    /// assert_eq!(arena[idx1], 20);
428    ///
429    /// let mut iterator = arena.values_mut();
430    /// *iterator.next().unwrap() = 10;
431    /// drop(iterator);
432    ///
433    /// assert_eq!(arena[idx1], 10);
434    /// ```
435    pub fn values_mut(&mut self) -> impl ExactSizeIterator<Item = &mut T> + DoubleEndedIterator {
436        self.data.iter_mut()
437    }
438
439    /// Reallocates the arena to make it take up as little space as possible.
440    pub fn shrink_to_fit(&mut self) {
441        self.data.shrink_to_fit();
442    }
443
444    /// Returns the index of the next value allocated on the arena.
445    ///
446    /// This method should remain private to make creating invalid `Idx`s harder.
447    fn next_idx(&self) -> Idx<T> {
448        Idx::from_raw(RawIdx(self.data.len() as u32))
449    }
450}
451
452impl<T> AsMut<[T]> for Arena<T> {
453    fn as_mut(&mut self) -> &mut [T] {
454        self.data.as_mut()
455    }
456}
457
458impl<T> Default for Arena<T> {
459    fn default() -> Arena<T> {
460        Arena { data: Vec::new() }
461    }
462}
463
464impl<T> Index<Idx<T>> for Arena<T> {
465    type Output = T;
466    fn index(&self, idx: Idx<T>) -> &T {
467        let idx = idx.into_raw().0 as usize;
468        &self.data[idx]
469    }
470}
471
472impl<T> IndexMut<Idx<T>> for Arena<T> {
473    fn index_mut(&mut self, idx: Idx<T>) -> &mut T {
474        let idx = idx.into_raw().0 as usize;
475        &mut self.data[idx]
476    }
477}
478
479impl<T> Index<IdxRange<T>> for Arena<T> {
480    type Output = [T];
481    fn index(&self, range: IdxRange<T>) -> &[T] {
482        let start = range.range.start as usize;
483        let end = range.range.end as usize;
484        &self.data[start..end]
485    }
486}
487
488impl<T> FromIterator<T> for Arena<T> {
489    fn from_iter<I>(iter: I) -> Self
490    where
491        I: IntoIterator<Item = T>,
492    {
493        Arena { data: Vec::from_iter(iter) }
494    }
495}
496
497/// An iterator over the arena’s elements.
498pub struct IntoIter<T>(Enumerate<<Vec<T> as IntoIterator>::IntoIter>);
499
500impl<T> Iterator for IntoIter<T> {
501    type Item = (Idx<T>, T);
502
503    fn next(&mut self) -> Option<Self::Item> {
504        self.0.next().map(|(idx, value)| (Idx::from_raw(RawIdx(idx as u32)), value))
505    }
506}
507
508impl<T> IntoIterator for Arena<T> {
509    type Item = (Idx<T>, T);
510
511    type IntoIter = IntoIter<T>;
512
513    fn into_iter(self) -> Self::IntoIter {
514        IntoIter(self.data.into_iter().enumerate())
515    }
516}
517
518impl<T> Extend<T> for Arena<T> {
519    fn extend<II: IntoIterator<Item = T>>(&mut self, iter: II) {
520        for t in iter {
521            self.alloc(t);
522        }
523    }
524}