use std::{
collections::HashMap,
hash::Hash,
ops::{Index, IndexMut},
};
use crate::{
hsize,
prelude::*,
};
use super::{PropMap, PropStore, PropStoreMut, Value, util::gen_mapped_iter};
#[derive(Clone, Debug)]
pub struct SparseMap<H: Handle + Hash, T>(HashMap<H, T, ahash::RandomState>);
impl<H: Handle + Hash, T> SparseMap<H, T> {
pub fn new() -> Self {
SparseMap(HashMap::default())
}
}
impl<H: Handle + Hash, T> PropMap<H> for SparseMap<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.0.contains_key(&handle)
}
}
impl<H: Handle + Hash, T> Index<H> for SparseMap<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 + Hash, T> PropStore<H> for SparseMap<H, T> {
fn get_ref(&self, handle: H) -> Option<&Self::Output> {
self.0.get(&handle)
}
fn num_props(&self) -> hsize {
self.0.len() as hsize
}
type Iter<'s> = Iter<'s, H, T> where Self: 's;
fn iter(&self) -> Self::Iter<'_> {
Iter(self.0.iter())
}
}
impl<H: Handle + Hash, T> IndexMut<H> for SparseMap<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 + Hash, T> Empty for SparseMap<H, T> {
fn empty() -> Self {
Self::new()
}
}
impl<H: Handle + Hash, T> PropStoreMut<H> for SparseMap<H, T> {
fn get_mut(&mut self, handle: H) -> Option<&mut Self::Output> {
self.0.get_mut(&handle)
}
fn insert(&mut self, handle: H, elem: Self::Output) -> Option<Self::Output> {
self.0.insert(handle, elem)
}
fn remove(&mut self, handle: H) -> Option<Self::Output> {
self.0.remove(&handle)
}
fn clear(&mut self) {
self.0.clear()
}
fn reserve(&mut self, additional: hsize) {
self.0.reserve(additional as usize);
}
type IterMut<'s> = IterMut<'s, H, T> where Self: 's;
fn iter_mut(&mut self) -> Self::IterMut<'_> {
IterMut(self.0.iter_mut())
}
}
gen_mapped_iter!(
Iter<'a, H, T>(std::collections::hash_map::Iter<'a, H, T>);
mut_token: [],
extra_derives: [Clone],
mapping: |(k, v)| (*k, v),
double_ended: false,
);
gen_mapped_iter!(
IterMut<'a, H, T>(std::collections::hash_map::IterMut<'a, H, T>);
mut_token: [mut],
extra_derives: [],
mapping: |(k, v)| (*k, v),
double_ended: false,
);
#[cfg(test)]
mod tests {
use super::*;
gen_tests_for_store_impl!(SparseMap);
}