1use std::{iter::FilterMap, slice::Iter};
2
3#[derive(Debug)]
5pub struct HolyArray<T> {
6 data: Vec<Option<T>>,
7 free_slots: Vec<usize>,
8}
9
10impl<T> HolyArray<T> {
11 pub fn new() -> Self {
12 return Self {
13 data: vec![],
14 free_slots: vec![],
15 };
16 }
17
18 pub fn acquire(&mut self, value: T) -> usize {
19 let Some(idx) = self.free_slots.pop() else {
20 let idx = self.data.len();
21 self.data.push(Some(value));
22 return idx;
23 };
24
25 self.data[idx] = Some(value);
26
27 return idx;
28 }
29
30 pub fn release(&mut self, index: usize) {
31 if index >= self.data.len() {
32 return;
33 }
34
35 if self.data[index].is_none() {
36 return;
37 }
38
39 self.data[index] = None;
40 self.free_slots.push(index);
41 }
42
43 pub fn get(&self, index: usize) -> Option<&T> {
44 let Some(Some(value)) = self.data.get(index) else {
45 return None;
46 };
47
48 return Some(value);
49 }
50
51 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
52 let Some(Some(value)) = self.data.get_mut(index) else {
53 return None;
54 };
55
56 return Some(value);
57 }
58
59 pub fn len(&self) -> usize {
60 return self.data.len();
61 }
62}
63
64impl<'a, T> IntoIterator for &'a HolyArray<T> {
65 type Item = &'a T;
66 type IntoIter = FilterMap<Iter<'a, Option<T>>, fn(&'a Option<T>) -> Option<&'a T>>;
67
68 fn into_iter(self) -> Self::IntoIter {
69 self.data.iter().filter_map(|item| item.as_ref())
70 }
71}