generational_array/
lib.rs1use std::fmt;
2use std::collections::VecDeque;
3
4#[derive(Copy, Clone)] pub struct GenerationalIndex {
6 pub index: usize,
7 pub generation: usize,
8}
9
10impl fmt::Display for GenerationalIndex {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 write!(f, "(index: {}, generation: {})", self.index, self.generation)
13 }
14}
15
16#[derive(Debug)]
17pub struct GenerationalArray<ValueType> {
18
19 values: Vec<Option<ValueType>>,
20 generations: Vec<usize>,
21 free_indices: VecDeque<usize>,
22 size: usize,
23 used_size: usize,
24
25}
26
27#[derive(Debug)]
28pub enum GenerationalArrayResult<'a, ValueType> {
29 None,
30 OutDated,
31 OutOfBounds,
32 Some(&'a ValueType),
33}
34
35#[derive(Debug)]
36pub enum GenerationalArrayResultMut<'a, ValueType> {
37 None,
38 OutDated,
39 OutOfBounds,
40 Some(&'a mut ValueType),
41}
42
43impl<ValueType> GenerationalArray<ValueType> {
44
45 pub fn new() -> GenerationalArray<ValueType> {
46 GenerationalArray::<ValueType> {
47 values: Vec::<Option<ValueType>>::new(),
48 generations: Vec::<usize>::new(),
49 free_indices: VecDeque::<usize>::new(),
50 size: 0,
51 used_size: 0,
52 }
53 }
54
55 pub fn insert(&mut self, value: ValueType) -> GenerationalIndex {
56
57 let next_index: usize = match self.free_indices.pop_front() {
59 None => {
60 self.values.push(None);
62 self.generations.push(0);
63 self.size += 1;
64 self.size - 1
65 }
66 Some(idx) => {
67 idx
68 }
69 };
70
71 self.values[next_index] = Some(value);
73 self.used_size += 1;
74 GenerationalIndex { index: next_index, generation: self.generations[next_index] }
78
79 }
80
81 pub fn remove(&mut self, index: GenerationalIndex) -> Result<(), &'static str> {
82
83 if index.generation != self.generations[index.index] {
85 return Err("The generation is outdated");
86 }
87
88 if index.index >=self.size{
90 return Err("The index is out of range");
91 }
92
93 self.values[index.index] = None;
95 self.generations[index.index] += 1;
96
97 self.free_indices.push_back(index.index);
98 self.used_size -= 1;
99
100 Ok(())
101
102 }
103
104 pub fn get(&self, index: &GenerationalIndex) -> GenerationalArrayResult<ValueType> {
105
106 if index.generation != self.generations[index.index] {
108 return GenerationalArrayResult::OutDated;
109 }
110
111 if index.index >=self.size{
113 return GenerationalArrayResult::OutOfBounds;
114 }
115
116 match &self.values[index.index] {
117 None => GenerationalArrayResult::None,
118 Some(val) => GenerationalArrayResult::Some(val),
119 }
120
121 }
122
123 pub fn get_mut(&mut self, index: &GenerationalIndex) -> GenerationalArrayResultMut<ValueType> {
124
125 if index.generation != self.generations[index.index] {
127 return GenerationalArrayResultMut::OutDated;
128 }
129
130 if index.index >= self.size{
132 return GenerationalArrayResultMut::OutOfBounds;
133 }
134
135 if self.values[index.index].is_none() {
136 return GenerationalArrayResultMut::None;
137 }
138
139 GenerationalArrayResultMut::Some(self.values[index.index].as_mut().unwrap())
140
141 }
142
143 pub fn is_empty(&self) -> bool {
144 self.used_size == 0
145 }
146
147 pub fn size(&self) -> usize {
148 self.size
149 }
150
151 pub fn used_size(&self) -> usize {
152 self.used_size
153 }
154
155}