#![deny(missing_docs,)]
#![cfg_attr(feature = "map_get_key_value", feature(map_get_key_value,),)]
use std::{
hash::*, iter::*, fmt,
ops::{
Deref, DerefMut,
Add, AddAssign,
Neg, Sub, SubAssign,
Mul, MulAssign,
Div, DivAssign,
},
borrow::{Borrow, BorrowMut,},
convert::{AsRef, AsMut,},
collections::{hash_map::RandomState, HashMap,},
cmp::Ordering,
};
#[macro_export]
macro_rules! map {
($(($k:expr, $v:expr $(,)? ),)* ; $tp:ty) => {{
let mut map = nummap::NumMap::<_, _, $tp>::default();
$(map.set($k, $v,);)*
map
}};
($(($k:expr, $v:expr $(,)? )),* ; $tp:ty) => (map!($(($k, $v,),)*));
($($t:tt)*) => (map!($($t)*; std::collections::hash_map::RandomState));
}
mod number;
mod iter;
pub use self::{number::*, iter::*,};
pub struct NumMap<K, V, S = RandomState,>(HashMap<K, V::NonZero, S>,)
where V: Number;
impl<K, V,> NumMap<K, V, RandomState,>
where K: Hash + Eq,
V: Number, {
#[inline]
pub fn new() -> Self { HashMap::new().into() }
#[inline]
pub fn with_capacity(capactiy: usize,) -> Self { HashMap::with_capacity(capactiy,).into() }
}
impl<K, V, S,> NumMap<K, V, S,>
where V: Number, {
#[inline]
pub fn iter(&self,) -> Iter<K, V,> {
Iter(self.0.iter().map(|(k, v,): (&K, &V::NonZero,),| (k, v.get(),),),)
}
#[inline]
pub fn drain(&mut self,) -> Drain<K, V,> {
Drain(self.0.drain().map(|(k, v,): (K, V::NonZero,),| (k, v.get(),),),)
}
}
impl<K, V, S,> NumMap<K, V, S,>
where K: Eq + Hash,
V: Number,
S: BuildHasher, {
#[inline]
pub fn with_hasher(hash_builder: S,) -> Self { HashMap::with_hasher(hash_builder,).into() }
#[inline]
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S,) -> Self {
HashMap::with_capacity_and_hasher(capacity, hash_builder,).into()
}
#[inline]
pub fn get<Q,>(&self, k: &Q,) -> V
where K: Borrow<Q>,
Q: Hash + Eq + ?Sized, {
V::NonZero::num(self.0.get(k,).copied(),)
}
#[cfg(feature = "map_get_key_value",)]
#[inline]
pub fn get_key_value<'a,>(&self, k: &'a K,) -> (&'a K, V) {
self.get_key_value(k,)
.map(move |(k, v,),| (k, v.get(),),)
.unwrap_or((k, V::ZERO,),)
}
#[inline]
pub fn set(&mut self, k: K, v: V,) -> V {
match V::NonZero::new(v,) {
Some(v) => self.insert(k, v,),
None => self.remove(&k,),
}
}
#[inline]
pub fn update(&mut self, mut update: impl FnMut(&K, V,) -> V,)
where S: Default, {
use std::mem;
let map = mem::replace(self, Self::with_capacity_and_hasher(self.capacity(), S::default(),),);
for (k, mut v,) in map {
v = update(&k, v,);
self.set(k, v,);
}
}
#[inline]
pub fn insert(&mut self, k: K, v: V::NonZero,) -> V {
V::NonZero::num(self.0.insert(k, v,),)
}
#[inline]
pub fn remove<Q,>(&mut self, k: &Q,) -> V
where K: Borrow<Q>,
Q: Eq + Hash + ?Sized, {
V::NonZero::num(self.0.remove(k,),)
}
#[inline]
pub fn remove_entry(&mut self, k: K,) -> (K, V) {
self.0.remove_entry(&k,)
.map(move |(k, v,),| (k, v.get(),),)
.unwrap_or((k, V::ZERO,),)
}
#[inline]
pub fn retain<F,>(&mut self, mut f: F,)
where F: FnMut(&K, V,) -> bool, {
self.0.retain(move |k, v,| f(k, v.get(),),)
}
}
impl<K, V, S,> Clone for NumMap<K, V, S,>
where V: Number,
HashMap<K, V::NonZero, S>: Clone, {
#[inline]
fn clone(&self,) -> Self { self.0.clone().into() }
}
impl<K, V, S,> From<HashMap<K, V::NonZero, S>> for NumMap<K, V, S,>
where V: Number, {
#[inline]
fn from(from: HashMap<K, V::NonZero, S>,) -> Self { NumMap(from,) }
}
impl<K, V, S,> Default for NumMap<K, V, S,>
where V: Number, HashMap<K, V::NonZero, S>: Default, {
#[inline]
fn default() -> Self { HashMap::default().into() }
}
impl<K, V1, V2, S1, S2,> PartialEq<HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
Self: PartialOrd<HashMap<K, V2, S2>>, {
#[inline]
fn eq(&self, rhs: &HashMap<K, V2, S2>,) -> bool {
self.partial_cmp(rhs,)
.map(|cmp,| cmp == Ordering::Equal,)
.unwrap_or(false,)
}
}
impl<K, V1, V2, S1, S2,> PartialEq<NumMap<K, V2, S2,>> for NumMap<K, V1, S1,>
where V1: Number,
V2: Number,
Self: PartialOrd<NumMap<K, V2, S2>>, {
#[inline]
fn eq(&self, rhs: &NumMap<K, V2, S2>,) -> bool {
if self.len() != rhs.len() { return false }
self.partial_cmp(rhs,)
.map(|cmp,| cmp == Ordering::Equal,)
.unwrap_or(false,)
}
}
impl<K, V, S,> Eq for NumMap<K, V, S,>
where V: Number,
Self: PartialEq<Self>, {}
impl<K, V1, V2, S1, S2,> PartialOrd<HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Hash,
V1: Number + PartialOrd<V1> + PartialOrd<V2>,
S1: BuildHasher,
S2: BuildHasher, {
fn partial_cmp(&self, rhs: &HashMap<K, V2, S2>,) -> Option<Ordering> {
use std::collections::HashSet;
let keys = self.keys()
.chain(rhs.keys(),)
.collect::<HashSet<_>>()
.into_iter();
let mut comparisons = keys.map(|k,| {
let lhs = self.get(k,);
match rhs.get(k,) {
Some(rhs) => lhs.partial_cmp(rhs,),
None => lhs.partial_cmp(&V1::ZERO,),
}
},)
.filter(|cmp,| *cmp != Some(Ordering::Equal),);
let cmp = match comparisons.next() {
Some(cmp) => cmp?,
None => return Some(Ordering::Equal),
};
for compare in comparisons {
if compare? != cmp { return None }
}
Some(cmp)
}
}
impl<K, V1, V2, S1, S2,> PartialOrd<NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Hash,
V1: Number + PartialOrd<V2>,
V2: Number,
S1: BuildHasher,
S2: BuildHasher, {
fn partial_cmp(&self, rhs: &NumMap<K, V2, S2>,) -> Option<Ordering> {
use std::collections::HashSet;
let keys = self.keys()
.chain(rhs.keys(),)
.collect::<HashSet<_>>()
.into_iter();
let mut comparisons = keys.map(|k,| self.get(k,).partial_cmp(&rhs.get(k,),),)
.filter(|cmp,| *cmp != Some(Ordering::Equal),);
let cmp = match comparisons.next() {
Some(cmp) => cmp?,
None => return Some(Ordering::Equal),
};
for compare in comparisons {
if compare? != cmp { return None }
}
Some(cmp)
}
}
impl<K, V, S, A,> FromIterator<A> for NumMap<K, V, S,>
where K: Hash + Eq,
V: Number,
S: Default + BuildHasher,
A: Into<(K, V,)>, {
fn from_iter<Iter,>(iter: Iter,) -> Self
where Iter: IntoIterator<Item = A>, {
iter.into_iter()
.map(A::into,)
.filter_map(|(k, v,),| V::NonZero::new(v,).map(move |v,| (k, v,),),)
.collect::<HashMap<_, _, S,>>().into()
}
}
impl<'a, K, V, S,> Extend<(&'a K, &'a V,)> for NumMap<K, V, S,>
where K: 'a + Hash + Eq + Copy, V: 'a + Number, S: Default + BuildHasher, {
#[inline]
fn extend<Iter,>(&mut self, iter: Iter,)
where Iter: IntoIterator<Item = (&'a K, &'a V,)>, {
self.extend(iter.into_iter()
.map(|(&k, &v,),| (k, v,),),
)
}
}
impl<K, V, S,> Extend<(K, V,)> for NumMap<K, V, S,>
where K: Hash + Eq, V: Number, S: Default + BuildHasher, {
fn extend<Iter,>(&mut self, iter: Iter,)
where Iter: IntoIterator<Item = (K, V,)>, {
self.0.extend(
iter.into_iter()
.filter_map(|(k, v,),| V::NonZero::new(v,).map(move |v,| (k, v,),),),
)
}
}
impl<K, V, S,> IntoIterator for NumMap<K, V, S,>
where V: Number, {
type Item = (K, V,);
type IntoIter = IntoIter<K, V,>;
#[inline]
fn into_iter(self,) -> Self::IntoIter {
IntoIter(self.0.into_iter().map(|(k, v,): (K, V::NonZero,),| (k, v.get(),),),)
}
}
impl<'a, K, V, S,> IntoIterator for &'a NumMap<K, V, S,>
where V: Number, {
type Item = (&'a K, V,);
type IntoIter = Iter<'a, K, V,>;
#[inline]
fn into_iter(self,) -> Self::IntoIter { self.iter() }
}
impl<K, V, S,> Deref for NumMap<K, V, S,>
where V: Number, {
type Target = HashMap<K, V::NonZero, S>;
#[inline]
fn deref(&self,) -> &Self::Target { &self.0 }
}
impl<K, V, S,> DerefMut for NumMap<K, V, S,>
where V: Number, {
#[inline]
fn deref_mut(&mut self,) -> &mut Self::Target { &mut self.0 }
}
impl<K, V, S,> Borrow<HashMap<K, V::NonZero, S>> for NumMap<K, V, S,>
where V: Number, {
#[inline]
fn borrow(&self,) -> &HashMap<K, V::NonZero, S> { &self.0 }
}
impl<K, V, S,> BorrowMut<HashMap<K, V::NonZero, S>> for NumMap<K, V, S,>
where V: Number, {
#[inline]
fn borrow_mut(&mut self,) -> &mut HashMap<K, V::NonZero, S> { &mut self.0 }
}
impl<K, V, S,> AsRef<HashMap<K, V::NonZero, S>> for NumMap<K, V, S,>
where V: Number, {
#[inline]
fn as_ref(&self,) -> &HashMap<K, V::NonZero, S> { &self }
}
impl<K, V, S,> AsMut<HashMap<K, V::NonZero, S>> for NumMap<K, V, S,>
where V: Number, {
#[inline]
fn as_mut(&mut self,) -> &mut HashMap<K, V::NonZero, S> { &mut self.0 }
}
impl<K, V, S,> fmt::Debug for NumMap<K, V, S,>
where V: Number, HashMap<K, V::NonZero, S>: fmt::Debug, {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter,) -> fmt::Result { self.0.fmt(fmt,) }
}
impl<K, V1, V2, S1, S2,> Add<HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
Self: AddAssign<HashMap<K, V2, S2>>, {
type Output = Self;
#[inline]
fn add(mut self, rhs: HashMap<K, V2, S2>,) -> Self::Output { self += rhs; self }
}
impl<'a, K, V1, V2, S1, S2,> Add<&'a HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
Self: AddAssign<&'a HashMap<K, V2, S2>>, {
type Output = Self;
#[inline]
fn add(mut self, rhs: &'a HashMap<K, V2, S2>,) -> Self::Output { self += rhs; self }
}
impl<K, V1, V2, S1, S2,> Add<NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
V2: Number,
Self: AddAssign<NumMap<K, V2, S2>>, {
type Output = Self;
#[inline]
fn add(mut self, rhs: NumMap<K, V2, S2>,) -> Self::Output { self += rhs; self }
}
impl<'a, K, V1, V2, S1, S2,> Add<&'a NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
V2: Number,
Self: AddAssign<&'a NumMap<K, V2, S2>>, {
type Output = Self;
#[inline]
fn add(mut self, rhs: &'a NumMap<K, V2, S2>,) -> Self::Output { self += rhs; self }
}
impl<K, V1, V2, S1, S2,> AddAssign<HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Hash,
V1: Number + Add<V2, Output = V1>,
S1: BuildHasher, {
#[inline]
fn add_assign(&mut self, rhs: HashMap<K, V2, S2>,) {
for (k, v,) in rhs {
let v = self.get(&k,) + v;
self.set(k, v,);
}
}
}
impl<'a, K, V1, V2, S1, S2,> AddAssign<&'a HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Clone + Hash,
V1: Number + Add<V2, Output = V1>,
V2: Clone,
S1: BuildHasher, {
#[inline]
fn add_assign(&mut self, rhs: &'a HashMap<K, V2, S2>,) {
for (k, v,) in rhs {
let v = self.get(k,) + v.clone();
self.set(k.clone(), v,);
}
}
}
impl<K, V1, V2, S1, S2,> AddAssign<NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Hash,
V1: Number + Add<V2, Output = V1>,
V2: Number,
S1: BuildHasher, {
#[inline]
fn add_assign(&mut self, rhs: NumMap<K, V2, S2>,) {
for (k, v,) in rhs {
let v = self.get(&k,) + v;
self.set(k, v,);
}
}
}
impl<'a, K, V1, V2, S1, S2,> AddAssign<&'a NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Clone + Hash,
V1: Number + Add<V2, Output = V1>,
V2: Number,
S1: BuildHasher, {
#[inline]
fn add_assign(&mut self, rhs: &'a NumMap<K, V2, S2>,) {
for (k, v,) in rhs {
let v = self.get(k,) + v;
self.set(k.clone(), v,);
}
}
}
impl<K, V, S,> Neg for NumMap<K, V, S,>
where K: Eq + Hash,
V: Number + Neg,
S: BuildHasher + Default,
<V as Neg>::Output: Number, {
type Output = NumMap<K, <V as Neg>::Output, S,>;
#[inline]
fn neg(self,) -> Self::Output { self.into_iter().map(|(k, v,),| (k, -v,),).collect() }
}
impl<K, V1, V2, S1, S2,> Sub<HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
Self: SubAssign<HashMap<K, V2, S2>>, {
type Output = Self;
#[inline]
fn sub(mut self, rhs: HashMap<K, V2, S2>,) -> Self::Output { self -= rhs; self }
}
impl<'a, K, V1, V2, S1, S2,> Sub<&'a HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
Self: SubAssign<&'a HashMap<K, V2, S2>>, {
type Output = Self;
#[inline]
fn sub(mut self, rhs: &'a HashMap<K, V2, S2>,) -> Self::Output { self -= rhs; self }
}
impl<K, V1, V2, S1, S2,> Sub<NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
V2: Number,
Self: SubAssign<NumMap<K, V2, S2>>, {
type Output = Self;
#[inline]
fn sub(mut self, rhs: NumMap<K, V2, S2>,) -> Self::Output { self -= rhs; self }
}
impl<'a, K, V1, V2, S1, S2,> Sub<&'a NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where V1: Number,
V2: Number,
Self: SubAssign<&'a NumMap<K, V2, S2>>, {
type Output = Self;
#[inline]
fn sub(mut self, rhs: &'a NumMap<K, V2, S2>,) -> Self::Output { self -= rhs; self }
}
impl<K, V1, V2, S1, S2,> SubAssign<HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Hash,
V1: Number + Sub<V2, Output = V1>,
S1: BuildHasher, {
#[inline]
fn sub_assign(&mut self, rhs: HashMap<K, V2, S2>,) {
for (k, v,) in rhs {
let v = self.get(&k,) - v;
self.set(k, v,);
}
}
}
impl<'a, K, V1, V2, S1, S2,> SubAssign<&'a HashMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Clone + Hash,
V1: Number + Sub<V2, Output = V1>,
V2: Clone,
S1: BuildHasher, {
#[inline]
fn sub_assign(&mut self, rhs: &'a HashMap<K, V2, S2>,) {
for (k, v,) in rhs {
let v = self.get(k,) - v.clone();
self.set(k.clone(), v,);
}
}
}
impl<K, V1, V2, S1, S2,> SubAssign<NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Hash,
V1: Number + Sub<V2, Output = V1>,
V2: Number,
S1: BuildHasher, {
#[inline]
fn sub_assign(&mut self, rhs: NumMap<K, V2, S2>,) {
for (k, v,) in rhs {
let v = self.get(&k,) - v;
self.set(k, v,);
}
}
}
impl<'a, K, V1, V2, S1, S2,> SubAssign<&'a NumMap<K, V2, S2>> for NumMap<K, V1, S1,>
where K: Eq + Clone + Hash,
V1: Number + Sub<V2, Output = V1>,
V2: Number,
S1: BuildHasher, {
#[inline]
fn sub_assign(&mut self, rhs: &'a NumMap<K, V2, S2>,) {
for (k, v,) in rhs {
let v = self.get(k,) - v;
self.set(k.clone(), v,);
}
}
}
impl<K, V1, V2, S,> Mul<V2> for NumMap<K, V1, S,>
where V1: Number,
Self: MulAssign<V2>, {
type Output = Self;
#[inline]
fn mul(mut self, rhs: V2,) -> Self::Output { self *= rhs; self }
}
impl<K, V1, V2, S,> MulAssign<V2> for NumMap<K, V1, S,>
where K: Eq + Clone + Hash,
V1: Number + Mul<V2, Output = V1>,
V2: Clone,
S: BuildHasher, {
#[inline]
fn mul_assign(&mut self, rhs: V2,) {
let keys = self.keys().cloned().collect::<Vec<_>>();
for k in keys {
let v = self.get(&k,) * rhs.clone();
self.set(k, v,);
}
}
}
impl<K, V1, V2, S,> Div<V2> for NumMap<K, V1, S,>
where V1: Number,
Self: DivAssign<V2>, {
type Output = Self;
#[inline]
fn div(mut self, rhs: V2,) -> Self::Output { self /= rhs; self }
}
impl<K, V1, V2, S,> DivAssign<V2> for NumMap<K, V1, S,>
where K: Eq + Clone + Hash,
V1: Number + Div<V2, Output = V1>,
V2: Clone,
S: BuildHasher, {
#[inline]
fn div_assign(&mut self, rhs: V2,) {
let keys = self.keys().cloned().collect::<Vec<_>>();
for k in keys {
let v = self.get(&k,) / rhs.clone();
self.set(k, v,);
}
}
}
#[cfg(test,)]
mod tests {
use super::*;
#[test]
fn test_cmp() {
let one = (1..=10).map(|x,| (x, x,),).collect::<NumMap<_, _,>>();
let two = (1..=10).map(|x,| (x, 2 * x,),).collect::<NumMap<_, _,>>();
let neg_two = (1..=10).map(|x,| (x, -2 * x,),).collect::<NumMap<_, _,>>();
assert!(one < two);
assert!(one > neg_two);
assert!(two > neg_two);
assert!(one == one);
assert!(one >= one);
assert!(one <= one);
assert!(neg_two == neg_two);
assert!(neg_two >= neg_two);
assert!(neg_two <= neg_two);
}
#[test]
fn test_math() {
let one = (1..=10).map(|x,| (x, x,),).collect::<NumMap<_, _,>>();
let two = (1..=10).map(|x,| (x, 2 * x,),).collect::<NumMap<_, _,>>();
assert!(one.clone() + &one == two);
assert!(two.clone() - &one == one);
assert!(one.clone() - &two == -one.clone());
assert!(one.clone() * 2 == two);
assert!(two.clone() / 2 == one);
}
}