aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/arena.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/arena.rs')
-rw-r--r--crates/ra_analysis/src/arena.rs96
1 files changed, 96 insertions, 0 deletions
diff --git a/crates/ra_analysis/src/arena.rs b/crates/ra_analysis/src/arena.rs
new file mode 100644
index 000000000..98ed89274
--- /dev/null
+++ b/crates/ra_analysis/src/arena.rs
@@ -0,0 +1,96 @@
1//! A simple id-based arena, similar to https://github.com/fitzgen/id-arena.
2//! We use our own version for more compact id's and to allow inherent impls
3//! on Ids.
4
5use std::{
6 fmt,
7 ops::{Index, IndexMut},
8 hash::{Hash, Hasher},
9 marker::PhantomData,
10};
11
12pub(crate) struct Id<T> {
13 idx: u32,
14 _ty: PhantomData<fn() -> T>,
15}
16
17impl<T> fmt::Debug for Id<T> {
18 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19 f.debug_tuple("Id").field(&self.idx).finish()
20 }
21}
22impl<T> Copy for Id<T> {}
23impl<T> Clone for Id<T> {
24 fn clone(&self) -> Id<T> {
25 *self
26 }
27}
28
29impl<T> PartialEq for Id<T> {
30 fn eq(&self, other: &Id<T>) -> bool {
31 self.idx == other.idx
32 }
33}
34
35impl<T> Eq for Id<T> {}
36
37impl<T> Hash for Id<T> {
38 fn hash<H: Hasher>(&self, h: &mut H) {
39 self.idx.hash(h);
40 }
41}
42
43#[derive(Debug, PartialEq, Eq)]
44pub(crate) struct Arena<T> {
45 data: Vec<T>,
46}
47
48impl<T> Default for Arena<T> {
49 fn default() -> Arena<T> {
50 Arena { data: Vec::new() }
51 }
52}
53
54impl<T> Arena<T> {
55 pub(crate) fn push(&mut self, value: T) -> Id<T> {
56 let id = self.data.len() as u32;
57 self.data.push(value);
58 Id {
59 idx: id as u32,
60 _ty: PhantomData,
61 }
62 }
63
64 pub(crate) fn keys<'a>(&'a self) -> impl Iterator<Item = Id<T>> + 'a {
65 (0..(self.data.len() as u32)).into_iter().map(|idx| Id {
66 idx,
67 _ty: PhantomData,
68 })
69 }
70
71 pub(crate) fn items<'a>(&'a self) -> impl Iterator<Item = (Id<T>, &T)> + 'a {
72 self.data.iter().enumerate().map(|(idx, item)| {
73 let idx = idx as u32;
74 (
75 Id {
76 idx,
77 _ty: PhantomData,
78 },
79 item,
80 )
81 })
82 }
83}
84
85impl<T> Index<Id<T>> for Arena<T> {
86 type Output = T;
87 fn index(&self, id: Id<T>) -> &T {
88 &self.data[id.idx as usize]
89 }
90}
91
92impl<T> IndexMut<Id<T>> for Arena<T> {
93 fn index_mut(&mut self, id: Id<T>) -> &mut T {
94 &mut self.data[id.idx as usize]
95 }
96}