use crate::{ChunkStorage, Ident};
use crate::arena::{Arena, ArenaIndex};
use std::marker::PhantomData;
pub struct Vector<Item: Clone> {
arena: Arena,
_marker: PhantomData<Item>,
}
impl<Item: Clone> Vector<Item> {
pub fn new(ident: Ident, chunk_size: usize, storage: ::std::rc::Rc<dyn ChunkStorage>) -> Self {
let item_size = ::std::mem::size_of::<Item>();
Vector {
arena: Arena::new(ident, ::std::cmp::max(item_size, chunk_size), item_size, storage),
_marker: PhantomData,
}
}
pub fn len(&self) -> usize {
self.arena.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn at(&self, index: usize) -> Option<&Item> {
if index < self.len() {
Some(unsafe { &*(self.arena.at(ArenaIndex(index)) as *const Item) })
} else {
None
}
}
pub fn at_mut(&mut self, index: usize) -> Option<&mut Item> {
if index < self.len() {
Some(unsafe { &mut *(self.arena.at(ArenaIndex(index)) as *mut Item) })
} else {
None
}
}
pub fn push(&mut self, item: Item) {
unsafe {
let item_ptr = self.arena.push().0 as *mut Item;
*item_ptr = item;
}
}
pub fn pop(&mut self) -> Option<Item> {
if self.arena.len() == 0 {
None
} else {
unsafe {
let item_ptr: *const Item =
self.arena.at(ArenaIndex(self.arena.len() - 1)) as *const Item;
let item = Some(::std::ptr::read(item_ptr));
self.arena.pop_away();
item
}
}
}
}