ai-0/utility/src/graph/_preserve_index_vec.rs

131 lines
3.9 KiB
Rust

use std::ops::{Index, IndexMut};
enum Cell<T> {
Free { next_free_cell_id: Option<usize> },
Value { value: T },
}
pub struct _PreserveIndexVec<T> {
next_free: Option<usize>,
buffer: Vec<Cell<T>>,
len: usize,
}
impl<T> _PreserveIndexVec<T> {
pub fn new() -> Self {
return Self {
next_free: None,
buffer: Vec::new(),
len: 0,
};
}
pub fn len(&self) -> usize {
return self.len;
}
pub fn add(&mut self, constructor: impl FnOnce(&mut Self, usize) -> T) -> usize {
match self.next_free {
None => {
let cell = Cell::Value {
value: constructor(self, self.len),
};
self.buffer.push(cell);
self.len += 1;
return self.buffer.len() - 1;
}
Some(i) => match self.buffer[i] {
Cell::Free { next_free_cell_id } => {
self.next_free = next_free_cell_id;
let cell = Cell::Value {
value: constructor(self, i),
};
self.buffer[i] = cell;
self.len += 1;
return i;
}
Cell::Value { .. } => panic!("Busy cell marked as free"),
},
}
}
pub fn remove(&mut self, cell_index: usize) {
match self.buffer[cell_index] {
Cell::Free { .. } => panic!("Cell already free"),
Cell::Value { .. } => {
self.buffer[cell_index] = Cell::Free {
next_free_cell_id: self.next_free,
};
self.next_free = Some(cell_index);
self.len -= 1;
}
}
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
return self.buffer.iter().filter_map(|c| match c {
Cell::Free { .. } => return None,
Cell::Value { value } => return Some(value),
});
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
return self.buffer.iter_mut().filter_map(|c| match c {
Cell::Free { .. } => return None,
Cell::Value { value } => return Some(value),
});
}
pub fn iter_indexed(&self) -> impl Iterator<Item = (usize, &T)> {
return self.buffer.iter().enumerate().filter_map(|(i, c)| match c {
Cell::Free { .. } => return None,
Cell::Value { value } => return Some((i, value)),
});
}
pub fn iter_indexed_mut(&mut self) -> impl Iterator<Item = (usize, &mut T)> {
return self
.buffer
.iter_mut()
.enumerate()
.filter_map(|(i, c)| match c {
Cell::Free { .. } => return None,
Cell::Value { value } => return Some((i, value)),
});
}
pub fn iter_indexes(&self) -> impl Iterator<Item = (usize)> {
return self.buffer.iter().enumerate().filter_map(|(i, c)| match c {
Cell::Free { .. } => return None,
Cell::Value { value } => return Some(i),
});
}
pub fn capacity(&self) -> usize {
return self.buffer.len();
}
}
impl<T> Index<usize> for _PreserveIndexVec<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
match self.buffer.get(index).expect("Cell index out of bounds") {
Cell::Free { .. } => panic!("Referenced cell doesn't exists"),
Cell::Value { value } => return value,
}
}
}
impl<T> IndexMut<usize> for _PreserveIndexVec<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
match self
.buffer
.get_mut(index)
.expect("Cell index out of bounds")
{
Cell::Free { .. } => panic!("Referenced cell doesn't exists"),
Cell::Value { value } => return value,
}
}
}