logicsim/data_structures/
slab.rs1use std::fmt::{self, Display, Formatter};
2
3#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
7#[repr(transparent)]
8pub struct SlabIndex(pub(super) usize);
9impl SlabIndex {
10 pub fn i_actually_really_know_what_i_am_doing_and_i_want_the_inner_usize(&self) -> usize {
14 self.0
15 }
16 pub fn i_actually_really_know_what_i_am_doing_and_i_want_to_construct_from_usize(
19 i: usize,
20 ) -> Self {
21 Self(i)
22 }
23}
24impl Display for SlabIndex {
25 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
26 write!(f, "{}", self.0)
27 }
28}
29
30#[derive(Debug, Clone)]
46pub struct Slab<T: Sized> {
47 data: Vec<Option<T>>,
48 removed_indexes: Vec<SlabIndex>,
49}
50#[allow(dead_code)]
51impl<T: Sized> Slab<T> {
52 pub fn new() -> Self {
54 Self {
55 data: Vec::new(),
56 removed_indexes: Default::default(),
57 }
58 }
59
60 pub fn insert(&mut self, item: T) -> SlabIndex {
64 if let Some(index) = self.removed_indexes.pop() {
65 self.data[index.0] = Some(item);
66 index
67 } else {
68 let index = SlabIndex(self.data.len());
69 self.data.push(Some(item));
70 index
71 }
72 }
73
74 pub fn get_mut(&mut self, index: SlabIndex) -> Option<&mut T> {
78 if let Some(item) = self.data.get_mut(index.0) {
79 return item.as_mut();
80 }
81 None
82 }
83
84 pub fn get(&self, index: SlabIndex) -> Option<&T> {
88 if let Some(item) = self.data.get(index.0) {
89 return item.as_ref();
90 }
91 None
92 }
93
94 pub fn remove(&mut self, index: SlabIndex) -> Option<T> {
99 if let Some(position) = self.data.get_mut(index.0) {
100 if position.is_none() {
101 return None;
102 }
103 self.removed_indexes.push(index);
104 return position.take();
105 }
106 None
107 }
108
109 pub fn len(&self) -> usize {
113 self.data.len() - self.removed_indexes.len()
114 }
115
116 pub fn is_empty(&self) -> bool {
120 self.len() == 0
121 }
122
123 pub fn total_len(&self) -> usize {
125 self.data.len()
126 }
127
128 pub fn iter(&self) -> Iter<T> {
130 Iter {
131 iter: self.data.iter().enumerate(),
132 }
133 }
134
135 pub unsafe fn get_very_unsafely(&self, index: SlabIndex) -> &T {
144 debug_assert!(
145 index.0 < self.data.len(),
146 "Tried to access index out of bounds, len:{}, index:{}",
147 self.data.len(),
148 index
149 );
150 debug_assert!(
151 !self.removed_indexes.contains(&index),
152 "Tried to access removed index:{}",
153 index
154 );
155 &self.data.get_unchecked(index.0).as_ref().unwrap()
156 }
157}
158
159pub struct IntoIter<T> {
161 slab: Slab<T>,
162 i: SlabIndex,
163}
164impl<T> IntoIterator for Slab<T> {
165 type IntoIter = IntoIter<T>;
166 type Item = (SlabIndex, T);
167 fn into_iter(self) -> Self::IntoIter {
168 IntoIter {
169 slab: self,
170 i: SlabIndex(0),
171 }
172 }
173}
174impl<T> Iterator for IntoIter<T> {
175 type Item = (SlabIndex, T);
176 fn next(&mut self) -> Option<Self::Item> {
177 loop {
178 if self.i.0 == self.slab.data.len() {
179 return None;
180 }
181 let item = self.slab.data[self.i.0].take();
182
183 if item.is_none() {
184 self.i.0 += 1;
185 continue;
186 }
187 let item = Some((self.i, item.unwrap()));
189 self.i.0 += 1;
190 return item;
191 }
192 }
193}
194
195pub struct Iter<'a, T> {
197 iter: std::iter::Enumerate<std::slice::Iter<'a, Option<T>>>,
198}
199impl<'a, T> Iterator for Iter<'a, T> {
200 type Item = (SlabIndex, &'a T);
201 fn next(&mut self) -> Option<Self::Item> {
202 loop {
203 let (i, item) = self.iter.next()?;
204 let si = SlabIndex(i);
205
206 if item.is_none() {
207 continue;
208 }
209
210 return Some((si, item.as_ref().unwrap()));
212 }
213 }
214}
215
216impl<T> Default for Slab<T> {
217 fn default() -> Self {
218 Self::new()
219 }
220}
221
222#[cfg(test)]
223mod tests {
224 use super::*;
225
226 #[test]
227 fn test_insert_get() {
228 let mut s: Slab<_> = Default::default();
229
230 assert_eq!(s.get(SlabIndex(0)), None);
231
232 let index = s.insert(1);
233 assert_eq!(*s.get(index).unwrap(), 1);
234 assert_eq!(s.get(SlabIndex(1)), None);
235
236 s.remove(index);
237 assert_eq!(s.get(index), None);
238 }
239
240 #[test]
241 fn test_get_mut() {
242 let mut s: Slab<_> = Default::default();
243
244 assert_eq!(s.get_mut(SlabIndex(0)), None);
245
246 let index = s.insert(1);
247 assert_eq!(*s.get_mut(index).unwrap(), 1);
248 assert_eq!(s.get_mut(SlabIndex(1)), None);
249
250 s.remove(index);
251 assert_eq!(s.get_mut(index), None);
252 }
253
254 #[test]
255 fn test_remove() {
256 let mut s = Slab::new();
257
258 assert_eq!(s.remove(SlabIndex(0)), None);
259
260 let index = s.insert(1);
261 assert_eq!(s.remove(index), Some(1));
262
263 let new_index = s.insert(2);
264 assert_eq!(index, new_index);
265 assert_eq!(s.remove(new_index), Some(2));
266 }
267
268 #[test]
269 fn test_len() {
270 let mut s = Slab::new();
271
272 assert_eq!(s.len(), 0);
273 assert_eq!(s.is_empty(), true);
274 assert_eq!(s.total_len(), 0);
275
276 let index = s.insert(1);
277 assert_eq!(s.len(), 1);
278 assert_eq!(s.is_empty(), false);
279 assert_eq!(s.total_len(), 1);
280
281 s.remove(index);
282 assert_eq!(s.len(), 0);
283 assert_eq!(s.is_empty(), true);
284 assert_eq!(s.total_len(), 1);
285 }
286
287 #[test]
288 fn test_iter() {
289 let mut s = Slab::new();
290 for i in 0..10 {
291 s.insert(i);
292 }
293 for i in (1..10).step_by(2) {
294 s.remove(SlabIndex(i));
295 }
296 for (i, n) in s.iter() {
297 assert_eq!(i.0, *n)
298 }
299 }
300
301 #[test]
302 fn test_into_iter() {
303 let mut s = Slab::new();
304 for i in 0..10 {
305 s.insert(i);
306 }
307 for i in (0..10).step_by(2) {
308 s.remove(SlabIndex(i));
309 }
310 for (i, n) in s.into_iter() {
311 assert_eq!(i.0, n)
312 }
313 }
314
315 #[test]
316 fn test_clone() {
317 let mut s = Slab::new();
318 for i in 0..10 {
319 s.insert(i);
320 }
321 for i in (0..10).step_by(2) {
322 s.remove(SlabIndex(i));
323 }
324 let ss = s.clone();
325 for ((i1, n1), (i2, n2)) in s.into_iter().zip(ss) {
326 assert_eq!(i1, i2);
327 assert_eq!(n1, n2);
328 }
329 }
330 #[test]
331 fn test_get_very_unsafely() {
332 let mut s = Slab::new();
333
334 let index = s.insert(1);
335 let other_index = s.insert(2);
336
337 s.remove(index);
338 unsafe { assert_eq!(*s.get_very_unsafely(other_index), 2) };
339 }
340
341 #[test]
342 #[cfg(debug_assertions)]
343 #[should_panic(expected = "Tried to access index out of bounds, len:0, index:0")]
344 fn test_get_very_unsafely_panics_out_of_bounds() {
345 let s = Slab::<u8>::new();
346
347 unsafe { assert_eq!(*s.get_very_unsafely(SlabIndex(0)), 2) };
348 }
349
350 #[test]
351 #[cfg(debug_assertions)]
352 #[should_panic(expected = "Tried to access removed index:1")]
353 fn test_get_very_unsafely_panics_removed_index() {
354 let mut s = Slab::<u8>::new();
355
356 s.insert(3);
357 let index = s.insert(2);
358 s.insert(4);
359
360 s.remove(index);
361
362 unsafe { assert_eq!(*s.get_very_unsafely(index), 2) };
363 }
364}