use std::ops::{Index, IndexMut};
mod iter;
use iter::*;
#[derive(Debug, Clone)]
pub struct VecGrow<T> {
free_idxs: Vec<usize>,
objects: Vec<Option<T>>,
}
impl<T> VecGrow<T> {
pub fn new() -> Self {
Self {
free_idxs: vec![],
objects: vec![],
}
}
pub fn push(&mut self, value: T) {
if let Some(last_index) = self.free_idxs.last() {
self.objects[*last_index] = Some(value);
self.free_idxs.remove(*last_index);
} else {
self.objects.push(Some(value));
}
}
pub fn remove(&mut self, index: usize) {
fn assert_failed(index: usize, len: usize) -> ! {
panic!("removal index (is {index}) should be < len (is {len})");
}
if index >= self.objects.len() {
assert_failed(index, self.objects.len());
}
self.free_idxs.push(index);
self[index] = None;
}
pub fn count(&self) -> usize {
self.objects.len() - self.free_idxs.len()
}
pub fn len(&self) -> usize {
self.objects.len()
}
pub fn iter(&self) -> Iter<'_, T> {
Iter::new(self)
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut::new(self)
}
pub fn is_empty(&self) -> bool {
self.free_idxs.len() == self.len()
}
}
impl<T> Index<usize> for VecGrow<T> {
type Output = Option<T>;
fn index(&self, index: usize) -> &Self::Output {
&self.objects[index]
}
}
impl<T> IndexMut<usize> for VecGrow<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.objects[index]
}
}
#[macro_export]
macro_rules! vec_grow {
[] => {
VecGrow::new()
};
[$($v:expr),*] => {
{
let mut vg = VecGrow::new();
$(
vg.push($v);
)*
vg
}
};
[$value:expr; $count:expr] => {
{
let mut vg = VecGrow::new();
for _ in 0..$count {
vg.push($value);
}
vg
}
}
}