use std::collections::hash_map::RandomState;
use std::collections::HashMap;
use std::hash::*;
use std::marker::PhantomData;
#[derive(Clone, Debug)]
pub struct EntryMap<K, V, KF, VF, P, S = RandomState> {
hashmap: HashMap<K, V, S>,
k_closure: KF,
v_closure: VF,
_phantom: PhantomData<P>,
}
pub type FxEntryMap<K, V, KF, VF, P> = EntryMap<K, V, KF, VF, P, rustc_hash::FxBuildHasher>;
impl<K, V, KF, VF, P, S> EntryMap<K, V, KF, VF, P, S>
where
K: Eq + Hash,
S: BuildHasher + Default,
P: Copy,
KF: FnMut(P) -> K,
VF: FnMut(P) -> V,
{
#[inline]
pub fn new(k_closure: KF, v_closure: VF) -> Self {
Self {
hashmap: HashMap::default(),
k_closure,
v_closure,
_phantom: PhantomData,
}
}
#[inline]
pub fn entry_or_insert(&mut self, p: P) -> &mut V {
self.hashmap
.entry((self.k_closure)(p))
.or_insert_with(|| (self.v_closure)(p))
}
}
impl<K, V, KF, VF, P, S> From<EntryMap<K, V, KF, VF, P, S>> for HashMap<K, V, S> {
#[inline]
fn from(x: EntryMap<K, V, KF, VF, P, S>) -> Self { x.hashmap }
}
impl<K, V, KF, VF, P, S> IntoIterator for EntryMap<K, V, KF, VF, P, S> {
type Item = (K, V);
type IntoIter = <HashMap<K, V, S> as IntoIterator>::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter { self.hashmap.into_iter() }
}