use std::mem::MaybeUninit;
use std::ptr::{drop_in_place, read};
use hibitset::BitSetLike;
use crate::entity::Index;
use super::{DistinctStorage, Storage};
pub struct VecStorage<T>(Vec<MaybeUninit<T>>);
impl<T> Storage<T> for VecStorage<T> {
unsafe fn get(&self, index: Index) -> &T {
&*self.0.get_unchecked(index as usize).as_ptr()
}
unsafe fn get_mut(&mut self, index: Index) -> &mut T {
&mut *self.0.get_unchecked_mut(index as usize).as_mut_ptr()
}
unsafe fn insert(&mut self, index: Index, value: T) {
let index = index as usize;
if self.0.len() <= index {
let delta = index + 1 - self.0.len();
self.0.reserve(delta);
self.0.set_len(index + 1);
}
*self.0.get_unchecked_mut(index) = MaybeUninit::new(value);
}
unsafe fn remove(&mut self, index: Index) -> T {
read(self.get(index))
}
unsafe fn clean<B>(&mut self, has: B)
where
B: BitSetLike,
{
for (i, v) in self.0.iter_mut().enumerate() {
if has.contains(i as u32) {
drop_in_place(&mut *v.as_mut_ptr());
}
}
self.0.set_len(0);
}
}
impl<T> DistinctStorage for VecStorage<T> {}
impl<T> Default for VecStorage<T> {
fn default() -> Self {
Self(Vec::new())
}
}