1#![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#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct RawIdx(u32);
20
21impl RawIdx {
22 pub const fn from_u32(u32: u32) -> Self {
24 RawIdx(u32)
25 }
26
27 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
59pub 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 pub const fn from_raw(raw: RawIdx) -> Self {
110 Idx { raw, _ty: PhantomData }
111 }
112
113 pub const fn into_raw(self) -> RawIdx {
115 self.raw
116 }
117}
118
119pub struct IdxRange<T> {
121 range: Range<u32>,
122 _p: PhantomData<T>,
123}
124
125impl<T> IdxRange<T> {
126 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 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 pub fn is_empty(&self) -> bool {
175 self.range.is_empty()
176 }
177
178 pub fn start(&self) -> Idx<T> {
180 Idx::from_raw(RawIdx::from(self.range.start))
181 }
182
183 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#[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 pub const fn new() -> Arena<T> {
271 Arena { data: Vec::new() }
272 }
273
274 pub fn with_capacity(capacity: usize) -> Arena<T> {
281 Arena { data: Vec::with_capacity(capacity) }
282 }
283
284 pub fn clear(&mut self) {
298 self.data.clear();
299 }
300
301 pub fn len(&self) -> usize {
317 self.data.len()
318 }
319
320 pub fn is_empty(&self) -> bool {
330 self.data.is_empty()
331 }
332
333 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 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 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 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 pub fn values(&self) -> impl ExactSizeIterator<Item = &T> + DoubleEndedIterator {
418 self.data.iter()
419 }
420
421 pub fn values_mut(&mut self) -> impl ExactSizeIterator<Item = &mut T> + DoubleEndedIterator {
436 self.data.iter_mut()
437 }
438
439 pub fn shrink_to_fit(&mut self) {
441 self.data.shrink_to_fit();
442 }
443
444 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
497pub 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}