diff options
Diffstat (limited to 'crates/ra_vfs/src/arena.rs')
-rw-r--r-- | crates/ra_vfs/src/arena.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/crates/ra_vfs/src/arena.rs b/crates/ra_vfs/src/arena.rs new file mode 100644 index 000000000..d6fad753b --- /dev/null +++ b/crates/ra_vfs/src/arena.rs | |||
@@ -0,0 +1,48 @@ | |||
1 | use std::{ | ||
2 | hash::{Hash, Hasher}, | ||
3 | marker::PhantomData, | ||
4 | ops::{Index, IndexMut}, | ||
5 | }; | ||
6 | |||
7 | #[derive(Clone, Debug)] | ||
8 | pub(crate) struct Arena<ID: ArenaId, T> { | ||
9 | data: Vec<T>, | ||
10 | _ty: PhantomData<ID>, | ||
11 | } | ||
12 | |||
13 | pub(crate) trait ArenaId { | ||
14 | fn from_u32(id: u32) -> Self; | ||
15 | fn to_u32(self) -> u32; | ||
16 | } | ||
17 | |||
18 | impl<ID: ArenaId, T> Arena<ID, T> { | ||
19 | pub fn alloc(&mut self, value: T) -> ID { | ||
20 | let id = self.data.len() as u32; | ||
21 | self.data.push(value); | ||
22 | ID::from_u32(id) | ||
23 | } | ||
24 | } | ||
25 | |||
26 | impl<ID: ArenaId, T> Default for Arena<ID, T> { | ||
27 | fn default() -> Arena<ID, T> { | ||
28 | Arena { | ||
29 | data: Vec::new(), | ||
30 | _ty: PhantomData, | ||
31 | } | ||
32 | } | ||
33 | } | ||
34 | |||
35 | impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> { | ||
36 | type Output = T; | ||
37 | fn index(&self, idx: ID) -> &T { | ||
38 | let idx = idx.to_u32() as usize; | ||
39 | &self.data[idx] | ||
40 | } | ||
41 | } | ||
42 | |||
43 | impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> { | ||
44 | fn index_mut(&mut self, idx: ID) -> &mut T { | ||
45 | let idx = idx.to_u32() as usize; | ||
46 | &mut self.data[idx] | ||
47 | } | ||
48 | } | ||