use std::{
fmt,
iter::FromIterator,
marker::PhantomData,
ops::{Index, IndexMut},
};
use stable_vec::{
StableVec,
core::DefaultCore,
};
use crate::{
hsize,
prelude::*,
};
use super::{PropMap, PropStore, PropStoreMut, Value, util::gen_mapped_iter};
#[derive(Clone)]
pub struct DenseMap<H: Handle, T> {
vec: StableVec<T>,
_dummy: PhantomData<H>,
}
impl<H: Handle, T> DenseMap<H, T> {
pub fn new() -> Self {
Self {
vec: StableVec::new(),
_dummy: PhantomData,
}
}
pub fn push(&mut self, elem: T) -> H {
H::from_usize(self.vec.push(elem))
}
pub(crate) fn next_push_handle(&self) -> H {
H::from_usize(self.vec.next_push_index())
}
pub(crate) fn last_handle(&self) -> Option<H> {
self.vec.find_last_index().map(H::from_usize)
}
pub fn num_elements(&self) -> hsize {
self.vec.num_elements() as hsize
}
pub unsafe fn get_unchecked(&self, handle: H) -> &T {
self.vec.get_unchecked(handle.to_usize())
}
pub unsafe fn get_unchecked_mut(&mut self, handle: H) -> &mut T {
self.vec.get_unchecked_mut(handle.to_usize())
}
}
impl<H: Handle, T: Clone> DenseMap<H, T> {
pub fn from_elem(elem: T, count: usize) -> Self {
let mut v = StableVec::with_capacity(count);
for _ in 0..count {
v.push(elem.clone());
}
Self {
vec: v,
_dummy: PhantomData,
}
}
}
impl<H: Handle, T> PropMap<H> for DenseMap<H, T> {
type Target = T;
type Ret<'s> = &'s Self::Target where Self::Target: 's;
fn get(&self, handle: H) -> Option<Value<Self::Ret<'_>, Self::Target>> {
self.get_ref(handle).map(Into::into)
}
fn contains_handle(&self, handle: H) -> bool {
self.vec.has_element_at(handle.to_usize())
}
}
impl<H: Handle, T> Index<H> for DenseMap<H, T> {
type Output = T;
fn index(&self, handle: H) -> &Self::Output {
match self.get_ref(handle) {
None => panic!("no property found for handle '{:?}'", handle),
Some(r) => r,
}
}
}
impl<H: Handle, T> PropStore<H> for DenseMap<H, T> {
fn get_ref(&self, handle: H) -> Option<&Self::Output> {
self.vec.get(handle.to_usize())
}
fn num_props(&self) -> hsize {
self.vec.num_elements() as hsize
}
type Iter<'s> = Iter<'s, H, T> where Self: 's;
fn iter(&self) -> Self::Iter<'_> {
Iter(self.vec.iter(), PhantomData)
}
}
impl<H: Handle, T> IndexMut<H> for DenseMap<H, T> {
fn index_mut(&mut self, handle: H) -> &mut Self::Output {
match self.get_mut(handle) {
None => panic!("no property found for handle '{:?}'", handle),
Some(r) => r,
}
}
}
impl<H: Handle, T> Empty for DenseMap<H, T> {
fn empty() -> Self {
Self::new()
}
}
impl<H: Handle, T> PropStoreMut<H> for DenseMap<H, T> {
fn get_mut(&mut self, handle: H) -> Option<&mut Self::Output> {
self.vec.get_mut(handle.to_usize())
}
fn insert(&mut self, handle: H, elem: Self::Output) -> Option<Self::Output> {
let idx = handle.to_usize();
self.vec.reserve_for(idx);
self.vec.insert(idx, elem)
}
fn remove(&mut self, handle: H) -> Option<Self::Output> {
let idx = handle.to_usize();
if idx >= self.vec.capacity() {
return None;
}
self.vec.remove(idx)
}
fn clear(&mut self) {
self.vec.clear()
}
fn reserve(&mut self, additional: hsize) {
self.vec.reserve(additional as usize);
}
type IterMut<'s> = IterMut<'s, H, T> where Self: 's;
fn iter_mut(&mut self) -> Self::IterMut<'_> {
IterMut(self.vec.iter_mut(), PhantomData)
}
}
impl<H: Handle, T: fmt::Debug> fmt::Debug for DenseMap<H, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_map()
.entries(self.vec.indices().map(|k| (H::from_usize(k), &self.vec[k])))
.finish()
}
}
impl<H: Handle, T> Extend<(H, T)> for DenseMap<H, T> {
fn extend<I: IntoIterator<Item = (H, T)>>(&mut self, iter: I) {
let iter = iter.into_iter();
let cap = if self.is_empty() {
iter.size_hint().0
} else {
(iter.size_hint().0 + 1) / 2
};
self.reserve(cap as hsize);
for (handle, value) in iter {
self.insert(handle, value);
}
}
}
impl<H: Handle, T> FromIterator<(H, T)> for DenseMap<H, T> {
fn from_iter<I: IntoIterator<Item = (H, T)>>(iter: I) -> Self {
let mut out = Self::empty();
out.extend(iter);
out
}
}
gen_mapped_iter!(
Iter<'a, H, T>(stable_vec::iter::Iter<'a, T, DefaultCore<T>>, PhantomData<H>);
mut_token: [],
extra_derives: [Clone],
mapping: |(i, v)| (H::from_usize(i), v),
double_ended: true,
);
gen_mapped_iter!(
IterMut<'a, H, T>(stable_vec::iter::IterMut<'a, T, DefaultCore<T>>, PhantomData<H>);
mut_token: [mut],
extra_derives: [],
mapping: |(i, v)| (H::from_usize(i), v),
double_ended: true,
);
#[cfg(test)]
mod tests {
use super::*;
gen_tests_for_store_impl!(DenseMap);
}