extern crate bit_vec;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;
use bit_vec::BitVec;
use std::ops::{Index, IndexMut};
use std::ptr;
#[cfg(test)]
mod tests;
#[derive(Clone, PartialEq, Eq)]
pub struct StableVec<T> {
data: Vec<T>,
deleted: BitVec,
used_count: usize,
}
impl<T> StableVec<T> {
pub fn new() -> Self {
Self {
data: Vec::new(),
deleted: BitVec::new(),
used_count: 0,
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
data: Vec::with_capacity(capacity),
deleted: BitVec::with_capacity(capacity),
used_count: 0,
}
}
pub fn reserve(&mut self, additional: usize) {
self.data.reserve(additional);
self.deleted.reserve(additional);
}
pub fn push(&mut self, elem: T) -> usize {
self.data.push(elem);
self.deleted.push(false);
self.used_count += 1;
self.data.len() - 1
}
pub fn pop(&mut self) -> Option<T> {
let last_index = self.deleted.iter()
.enumerate()
.rev()
.find(|&(_, deleted)| !deleted)
.map(|(i, _)| i)
.unwrap_or(0);
self.remove(last_index)
}
pub fn remove(&mut self, index: usize) -> Option<T> {
if self.exists(index) {
let elem = unsafe {
self.deleted.set(index, true);
ptr::read(&self.data[index])
};
self.used_count -= 1;
Some(elem)
} else {
None
}
}
pub fn get(&self, index: usize) -> Option<&T> {
if self.exists(index) {
Some(&self.data[index])
} else {
None
}
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
if self.exists(index) {
Some(&mut self.data[index])
} else {
None
}
}
pub fn exists(&self, index: usize) -> bool {
index < self.data.len() && !self.deleted[index]
}
pub fn shrink_to_fit(&mut self) {
self.data.shrink_to_fit();
}
pub fn compact(&mut self) {
if self.is_compact() {
return;
}
if self.used_count > 0 {
let len = self.data.len();
let mut element_index = len - 1;
let mut hole_index = 0;
loop {
while element_index > 0 && self.deleted[element_index] {
element_index -= 1;
}
while hole_index < len && !self.deleted[hole_index] {
hole_index += 1;
}
if hole_index > element_index {
break;
}
self.data.swap(hole_index, element_index);
self.deleted.set(hole_index, false);
self.deleted.set(element_index, true);
}
}
unsafe {
self.data.set_len(self.used_count);
self.deleted.set_len(self.used_count);
}
}
pub fn is_compact(&self) -> bool {
self.used_count == self.data.len()
}
pub fn num_elements(&self) -> usize {
self.used_count
}
pub fn is_empty(&self) -> bool {
self.used_count == 0
}
pub fn capacity(&self) -> usize {
self.data.capacity()
}
pub fn next_index(&self) -> usize {
self.data.len()
}
pub fn iter(&self) -> Iter<T> {
Iter {
sv: self,
pos: 0,
}
}
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut {
deleted: &self.deleted,
vec_iter: self.data.iter_mut(),
pos: 0,
}
}
}
impl<T> Drop for StableVec<T> {
fn drop(&mut self) {
let living_indices = self.deleted.iter()
.enumerate()
.filter_map(|(i, deleted)| if deleted { None } else { Some(i) });
for i in living_indices {
unsafe {
ptr::drop_in_place(&mut self.data[i]);
}
}
unsafe {
self.data.set_len(0);
}
}
}
impl<T> Index<usize> for StableVec<T> {
type Output = T;
fn index(&self, index: usize) -> &T {
assert!(self.exists(index));
&self.data[index]
}
}
impl<T> IndexMut<usize> for StableVec<T> {
fn index_mut(&mut self, index: usize) -> &mut T {
assert!(self.exists(index));
&mut self.data[index]
}
}
impl<T, S> From<S> for StableVec<T>
where S: AsRef<[T]>,
T: Clone
{
fn from(slice: S) -> Self {
let len = slice.as_ref().len();
Self {
data: slice.as_ref().into(),
deleted: BitVec::from_elem(len, false),
used_count: len,
}
}
}
impl<'a, T> IntoIterator for &'a StableVec<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut StableVec<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
pub struct Iter<'a, T: 'a> {
sv: &'a StableVec<T>,
pos: usize,
}
impl<'a, T: 'a> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
while self.pos < self.sv.deleted.len() && self.sv.deleted[self.pos] {
self.pos += 1;
}
if self.pos == self.sv.data.len() {
None
} else {
self.pos += 1;
Some(&self.sv.data[self.pos - 1])
}
}
}
pub struct IterMut<'a, T: 'a> {
deleted: &'a BitVec,
vec_iter: ::std::slice::IterMut<'a, T>,
pos: usize,
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
while self.pos < self.deleted.len() && self.deleted[self.pos] {
self.pos += 1;
self.vec_iter.next();
}
if self.pos == self.deleted.len() {
None
} else {
self.pos += 1;
self.vec_iter.next()
}
}
}