aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_vfs/src/arena.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_vfs/src/arena.rs')
-rw-r--r--crates/ra_vfs/src/arena.rs48
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 @@
1use std::{
2 hash::{Hash, Hasher},
3 marker::PhantomData,
4 ops::{Index, IndexMut},
5};
6
7#[derive(Clone, Debug)]
8pub(crate) struct Arena<ID: ArenaId, T> {
9 data: Vec<T>,
10 _ty: PhantomData<ID>,
11}
12
13pub(crate) trait ArenaId {
14 fn from_u32(id: u32) -> Self;
15 fn to_u32(self) -> u32;
16}
17
18impl<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
26impl<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
35impl<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
43impl<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}