use crate::math::IndexType;
pub trait Deletable<I> {
fn is_deleted(&self) -> bool;
fn delete(&mut self);
fn set_id(&mut self, id: I);
fn allocate() -> Self;
}
#[derive(Debug, Clone)]
pub struct DeletableVector<T: Deletable<I>, I: IndexType> {
data: Vec<T>,
deleted: Vec<I>,
}
impl<T: Deletable<I>, I: IndexType> DeletableVector<T, I> {
pub fn new() -> Self {
Self {
data: Vec::new(),
deleted: Vec::new(),
}
}
pub fn clear(&mut self) {
self.data.clear();
self.deleted.clear();
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.data.iter().filter(|f| !f.is_deleted())
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.data.iter_mut().filter(|f| !f.is_deleted())
}
pub fn get(&self, index: I) -> &T {
let v = &self.data[index.index()];
assert!(
!v.is_deleted(),
"Tried to access deleted element at {}",
index
);
v
}
pub fn has(&self, index: I) -> bool {
let i = index.index();
i < self.data.len() && !self.data[i].is_deleted()
}
pub fn get_mut(&mut self, index: I) -> &mut T {
let v = &mut self.data[index.index()];
assert!(
!v.is_deleted(),
"Tried to mutably access deleted element at {}",
index
);
v
}
pub fn len(&self) -> usize {
self.data.len() - self.deleted.len()
}
pub fn capacity(&self) -> usize {
self.data.len()
}
pub fn push(&mut self, mut v: T) -> I {
assert!(
v.is_deleted(),
"Tried to push an element that already has an id"
);
if let Some(index) = self.deleted.pop() {
v.set_id(index);
self.data[index.index()] = v;
index
} else {
let index = I::new(self.data.len());
v.set_id(index);
self.data.push(v);
index
}
}
pub fn set(&mut self, index: I, mut v: T) {
assert!(
self.data[index.index()].is_deleted(),
"Tried to overwrite a non-deleted element at {}",
index
);
assert!(
v.is_deleted(),
"Tried to set an element that already has an id"
);
v.set_id(index);
self.data[index.index()] = v;
}
pub fn delete_internal(&mut self, f: I) {
self.data[f.index()].delete();
self.deleted.push(f);
}
pub fn allocate(&mut self) -> I {
if let Some(index) = self.deleted.pop() {
index
} else {
let t = T::allocate();
debug_assert!(t.is_deleted());
self.data.push(t);
I::new(self.data.len() - 1)
}
}
}