use std::
{
vec,
vec::Vec,
iter,
slice
};
use crate::{Index, Item};
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[derive(Default, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ExposedGenVec<T>
{
items: Vec<Option<Item<T>>>
}
impl<T> ExposedGenVec<T>
{
pub fn new() -> ExposedGenVec<T>
{
ExposedGenVec
{
items: Vec::new()
}
}
pub fn with_capacity(capacity: usize) -> ExposedGenVec<T>
{
ExposedGenVec
{
items: Vec::with_capacity(capacity)
}
}
pub fn capacity(&self) -> usize
{
self.items.capacity()
}
pub fn reserve(&mut self, additional: usize)
{
self.items.reserve(additional)
}
pub fn contains(&self, index: Index) -> bool
{
self.get(index).is_some()
}
pub fn set(&mut self, index: Index, value: T) -> Option<T>
{
if self.items.len() < index.index + 1
{
self.items.resize_with(index.index + 1, | | None);
}
match self.items.get_mut(index.index)
{
Some(Some(item)) if item.generation <= index.generation =>
{
match std::mem::replace(&mut self.items[index.index], Some(Item { value, generation: index.generation }))
{
Some(item) => Some(item.value),
_ => None
}
},
Some(_) =>
{
self.items[index.index] = Some(Item { value, generation: index.generation });
None
}
_ => panic!(format!("Index is out of bounds despite internal vec being resized: {:?}", index))
}
}
pub fn remove(&mut self, index: Index) -> Option<T>
{
match self.items.get(index.index)
{
Some(Some(item)) if index.generation == item.generation =>
{
let removed = std::mem::replace(&mut self.items[index.index], None)
.expect(format!("{:?} shouldn't access a None", index).as_str());
Some(removed.value)
},
_ => None
}
}
pub fn get(&self, index: Index) -> Option<&T>
{
match self.items.get(index.index)
{
Some(Some(item)) if item.generation == index.generation => Some(&item.value),
_ => None
}
}
pub fn get_mut(&mut self, index: Index) -> Option<&mut T>
{
match self.items.get_mut(index.index)
{
Some(Some(item)) if item.generation == index.generation => Some(&mut item.value),
_ => None
}
}
pub fn iter(&self) -> Iter<T>
{
Iter
{
internal: self.items.iter().enumerate()
}
}
pub fn iter_mut(&mut self) -> IterMut<T>
{
IterMut
{
internal: self.items.iter_mut().enumerate()
}
}
}
#[derive(Debug)]
pub struct IntoIter<T>
{
internal: iter::Enumerate<vec::IntoIter<Option<Item<T>>>>
}
impl<T> Iterator for IntoIter<T>
{
type Item = (Index, T);
fn next(&mut self) -> Option<Self::Item>
{
loop
{
match self.internal.next()
{
Some((_, None)) => { continue; },
Some((index, Some(item))) => return Some((Index { index, generation: item.generation}, item.value)),
_ => return None
};
}
}
}
impl<T> IntoIterator for ExposedGenVec<T>
{
type Item = (Index, T);
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter
{
IntoIter
{
internal: self.items.into_iter().enumerate()
}
}
}
#[derive(Debug)]
pub struct Iter<'a, T: 'a>
{
internal: iter::Enumerate<slice::Iter<'a, Option<Item<T>>>>
}
impl<'a, T> Iterator for Iter<'a, T>
{
type Item = (Index, &'a T);
fn next(&mut self) -> Option<Self::Item>
{
loop
{
match self.internal.next()
{
Some((_, None)) => { continue; },
Some((index, Some(item))) => return Some((Index { index, generation: item.generation}, &item.value)),
_ => return None
};
}
}
}
impl<'a, T> IntoIterator for &'a ExposedGenVec<T>
{
type Item = (Index, &'a T);
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter
{
self.iter()
}
}
#[derive(Debug)]
pub struct IterMut<'a, T: 'a>
{
internal: iter::Enumerate<slice::IterMut<'a, Option<Item<T>>>>
}
impl<'a, T: 'a> Iterator for IterMut<'a, T>
{
type Item = (Index, &'a mut T);
fn next(&mut self) -> Option<Self::Item>
{
loop
{
match self.internal.next()
{
Some((_, None)) => { continue; },
Some((index, Some(item))) => return Some((Index { index, generation: item.generation}, &mut item.value)),
_ => return None
};
}
}
}
impl<'a, T> IntoIterator for &'a mut ExposedGenVec<T>
{
type Item = (Index, &'a mut T);
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter
{
self.iter_mut()
}
}
impl<T> std::ops::Index<Index> for ExposedGenVec<T>
{
type Output = T;
fn index(&self, index: Index) -> &Self::Output
{
self.get(index).expect(format!("Index should be valid: {:?}", index).as_str())
}
}
impl<T> std::ops::IndexMut<Index> for ExposedGenVec<T>
{
fn index_mut(&mut self, index: Index) -> &mut Self::Output
{
self.get_mut(index).expect(format!("Index should be valid: {:?}", index).as_str())
}
}
#[cfg(test)]
mod vec_tests
{
use crate::exposed::*;
#[test]
fn capacity()
{
let mut vec = ExposedGenVec::<i32>::new();
assert_eq!(vec.capacity(), 0);
vec.reserve(4);
assert_eq!(vec.capacity(), 4);
}
#[test]
fn set()
{
let mut allocator = IndexAllocator::new();
let index = allocator.allocate();
let mut vec = ExposedGenVec::new();
let replaced = vec.set(index, 0);
assert!(vec.contains(index));
assert_eq!(replaced, None);
allocator.deallocate(index);
let index1 = allocator.allocate();
let replaced = vec.set(index1, 1);
assert!(!vec.contains(index));
assert!(vec.contains(index1));
assert_eq!(replaced, Some(0));
for _ in 0..50
{
allocator.allocate();
}
let index = allocator.allocate();
let replaced = vec.set(index, 20);
assert!(vec.contains(index));
assert_eq!(replaced, None);
let new_val = vec.get(index);
assert_eq!(new_val, Some(&20));
}
#[test]
fn get()
{
let mut allocator = IndexAllocator::new();
let index = allocator.allocate();
let index1 = allocator.allocate();
let mut vec = ExposedGenVec::new();
vec.set(index, 0);
vec.set(index1, 1);
let value = vec.get(index);
assert_eq!(value, Some(&0));
let value = vec.get(index1);
assert_eq!(value, Some(&1));
if let Some(value) = vec.get_mut(index)
{
*value = 2;
}
let value = vec.get(index);
assert_eq!(value, Some(&2));
}
#[test]
fn iter()
{
let mut allocator = IndexAllocator::new();
let index = allocator.allocate();
let index1 = allocator.allocate();
let mut vec = ExposedGenVec::<i32>::new();
vec.set(index, 4);
vec.set(index1, 5);
let mut iter = vec.iter();
let (i, value) = iter.next().expect("Iterator should have next");
assert_eq!(i, index);
assert_eq!(*value, 4);
let (i, value) = iter.next().expect("Iterator should have next");
assert_eq!(i, index1);
assert_eq!(*value, 5);
}
#[test]
fn iter_mut()
{
let mut allocator = IndexAllocator::new();
let index = allocator.allocate();
let index1 = allocator.allocate();
let mut vec = ExposedGenVec::<i32>::new();
vec.set(index, 4);
vec.set(index1, 5);
let mut iter = vec.iter_mut();
let (i, value) = iter.next().expect("Iterator should have next");
assert_eq!(i, index);
assert_eq!(*value, 4);
*value = 0;
let (i, value) = iter.next().expect("Iterator should have next");
assert_eq!(i, index1);
assert_eq!(*value, 5);
*value = 1;
let value = vec.get(index);
assert_eq!(value, Some(&0));
let value = vec.get(index1);
assert_eq!(value, Some(&1));
}
#[test]
fn index()
{
let mut allocator = IndexAllocator::new();
let index = allocator.allocate();
let mut vec = ExposedGenVec::<i32>::new();
vec.set(index, 4);
assert_eq!(vec[index], 4);
}
#[test]
fn index_mut()
{
let mut allocator = IndexAllocator::new();
let index = allocator.allocate();
let mut vec = ExposedGenVec::<i32>::new();
vec.set(index, 3);
vec[index] = 5;
let value = vec.get(index);
assert_eq!(value, Some(&5));
}
}