use crate::cn;
use std::ops::{Index, IndexMut};
#[derive(Debug, Clone)]
pub struct VecMap<T> {
data: Vec<Option<T>>,
indexes: Vec<usize>,
}
impl<T> VecMap<T> {
pub fn new() -> Self {
VecMap {
data: Vec::new(),
indexes: Vec::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
let mut map = VecMap {
data: Vec::with_capacity(capacity),
indexes: Vec::with_capacity(capacity),
};
for _ in 0..capacity {
map.data.push(None);
}
map
}
pub fn len(&self) -> usize {
self.indexes.len()
}
pub fn is_empty(&self) -> bool {
self.indexes.is_empty()
}
pub fn get(&self, index: usize) -> Option<&T> {
self.data.get(index).unwrap_or(&None).as_ref()
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.data
.get_mut(index)
.map(|opt| opt.as_mut())
.unwrap_or(None)
}
pub fn insert(&mut self, index: usize, item: T) -> Option<T> {
while index >= self.data.len() {
self.data.push(None);
}
let old = std::mem::replace(&mut self.data[index], Some(item));
if old.is_none() {
self.indexes.push(index)
}
old
}
pub fn remove(&mut self, index: usize) -> Option<T> {
let mut old = None;
if self.contains(index) {
old = std::mem::replace(&mut self.data[index], None);
self.indexes.retain(|&idx| idx != index);
self.shrink();
}
old
}
pub fn shrink(&mut self) {
while let Some(None) = self.data.last() {
self.data.pop();
}
}
pub fn contains(&self, index: usize) -> bool {
self.data.get(index).unwrap_or(&None).is_some()
}
pub fn indexes(&self) -> impl cn::Iter<usize> + '_ {
self.indexes.iter().copied()
}
pub fn iter(&self) -> impl cn::Iter<(usize, &T)> + '_ {
self.data
.iter()
.enumerate()
.filter_map(|(idx, item)| item.as_ref().map(|item| (idx, item)))
}
pub fn as_vec(&self) -> &Vec<Option<T>> {
&self.data
}
pub fn as_vec_mut(&mut self) -> &mut Vec<Option<T>> {
&mut self.data
}
}
impl<T> From<Vec<T>> for VecMap<T> {
fn from(vec: Vec<T>) -> Self {
let mut map = VecMap::default();
for (index, item) in vec.into_iter().enumerate() {
map.insert(index, item);
}
map
}
}
impl<T: PartialEq> PartialEq for VecMap<T> {
fn eq(&self, other: &Self) -> bool {
self.data == other.data
}
}
impl<T: Eq> Eq for VecMap<T> {}
impl<T> Index<usize> for VecMap<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
self.data[index].as_ref().unwrap()
}
}
impl<T> IndexMut<usize> for VecMap<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
self.data[index].as_mut().unwrap()
}
}
impl<T> Default for VecMap<T> {
fn default() -> Self {
VecMap::new()
}
}
impl<T> std::iter::FromIterator<(usize, T)> for VecMap<T> {
fn from_iter<I: IntoIterator<Item = (usize, T)>>(iter: I) -> Self {
let mut map = VecMap::new();
for (idx, item) in iter {
map.insert(idx, item);
}
map
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VecSet(cn::VecMap<()>);
impl VecSet {
pub fn new() -> Self {
VecSet(cn::VecMap::new())
}
pub fn with_capacity(capacity: usize) -> Self {
VecSet(cn::VecMap::with_capacity(capacity))
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn contains(&self, index: usize) -> bool {
self.0.contains(index)
}
pub fn insert(&mut self, index: usize) -> bool {
self.0.insert(index, ()).is_none()
}
pub fn remove(&mut self, index: usize) -> bool {
self.0.remove(index).is_some()
}
pub fn indexes(&self) -> impl cn::Iter<usize> + '_ {
self.0.indexes()
}
pub fn iter(&self) -> impl cn::Iter<usize> + '_ {
self.0.iter().map(|(idx, _item)| idx)
}
}
impl Default for VecSet {
fn default() -> Self {
VecSet::new()
}
}
impl std::iter::FromIterator<usize> for VecSet {
fn from_iter<I: IntoIterator<Item = usize>>(iter: I) -> Self {
let mut set = VecSet::new();
for idx in iter {
set.insert(idx);
}
set
}
}
#[test]
fn test_remove() {
let mut map: VecMap<usize> = VecMap::new();
assert!(map.data.is_empty());
for i in [3, 10, 12] {
assert!(map.insert(i, 0).is_none());
}
assert_eq!(map.data.len(), 13);
assert_eq!(map.len(), 3);
assert!(map.remove(100).is_none());
assert_eq!(map.data.len(), 13);
assert_eq!(map.len(), 3);
assert_eq!(map.remove(3), Some(0));
assert_eq!(map.data.len(), 13);
assert_eq!(map.len(), 2);
assert_eq!(map.indexes, vec![10, 12]);
}
#[test]
fn test_new() {
let map: VecMap<usize> = VecMap::new();
assert!(map.data.is_empty());
assert_eq!(map.len(), 0);
let map: VecMap<i32> = [(1, 0), (10, 0), (3, 0)].iter().cloned().collect();
for i in [1, 10, 3] {
assert_eq!(map[i], 0);
}
assert_eq!(map.len(), 3);
assert_eq!(map.indexes, vec![1, 10, 3]);
}
#[test]
fn test_insert() {
let mut map: VecMap<usize> = VecMap::new();
assert!(map.data.is_empty());
assert!(map.insert(3, 0).is_none());
assert_eq!(map.data.len(), 4);
assert_eq!(map.indexes.len(), 1);
assert_eq!(map.len(), map.indexes.len());
assert_eq!(map.data[3], Some(0));
assert!(map.insert(10, 0).is_none());
assert_eq!(map.indexes.len(), 2);
assert_eq!(map.data.len(), 11);
assert_eq!(map.data[10], Some(0));
assert_eq!(map.insert(3, 12), Some(0));
assert_eq!(map.indexes.len(), 2);
assert_eq!(map.len(), map.indexes.len());
assert_eq!(map.data.len(), 11);
assert_eq!(map.data[3], Some(12));
}