#[cfg(test)]
mod tests_double_map;
use core::borrow::Borrow;
use core::convert::From;
use core::default::Default;
use core::fmt::{self, Debug};
use core::hash::{BuildHasher, Hash};
use core::hint::unreachable_unchecked;
use core::iter::{Extend, FromIterator, FusedIterator};
use core::mem;
use core::ops::Index;
use std::collections::{hash_map, HashMap, TryReserveError};
#[derive(Clone, Debug)]
pub struct DHashMap<K1, K2, V, S = hash_map::RandomState> {
value_map: HashMap<K1, (K2, V), S>,
key_map: HashMap<K2, K1, S>,
}
impl<K1, K2, V> DHashMap<K1, K2, V, hash_map::RandomState> {
#[inline]
#[must_use]
pub fn new() -> DHashMap<K1, K2, V, hash_map::RandomState> {
DHashMap {
value_map: HashMap::new(),
key_map: HashMap::new(),
}
}
#[inline]
#[must_use]
pub fn with_capacity(capacity: usize) -> DHashMap<K1, K2, V, hash_map::RandomState> {
DHashMap {
value_map: HashMap::with_capacity(capacity),
key_map: HashMap::with_capacity(capacity),
}
}
}
impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
where
S: Clone,
{
#[inline]
pub fn with_hasher(hash_builder: S) -> DHashMap<K1, K2, V, S> {
DHashMap {
value_map: HashMap::with_hasher(hash_builder.clone()),
key_map: HashMap::with_hasher(hash_builder),
}
}
#[inline]
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> DHashMap<K1, K2, V, S> {
DHashMap {
value_map: HashMap::with_capacity_and_hasher(capacity, hash_builder.clone()),
key_map: HashMap::with_capacity_and_hasher(capacity, hash_builder),
}
}
}
impl<K1, K2, V, S> DHashMap<K1, K2, V, S> {
#[inline]
pub fn capacity(&self) -> usize {
self.value_map.capacity()
}
pub fn keys(&self) -> Keys<'_, K1, K2, V> {
Keys { inner: self.iter() }
}
#[inline]
pub fn into_keys(self) -> IntoKeys<K1, K2, V> {
IntoKeys {
inner: self.into_iter(),
}
}
pub fn values(&self) -> Values<'_, K1, K2, V> {
Values { inner: self.iter() }
}
pub fn values_mut(&mut self) -> ValuesMut<'_, K1, K2, V> {
ValuesMut {
inner: self.iter_mut(),
}
}
#[inline]
pub fn into_values(self) -> IntoValues<K1, K2, V> {
IntoValues {
inner: self.into_iter(),
}
}
pub fn iter(&self) -> Iter<'_, K1, K2, V> {
Iter {
base: self.value_map.iter(),
}
}
pub fn iter_mut(&mut self) -> IterMut<'_, K1, K2, V> {
IterMut {
base: self.value_map.iter_mut(),
}
}
#[inline]
pub fn len(&self) -> usize {
self.value_map.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.value_map.is_empty()
}
#[inline]
pub fn drain(&mut self) -> Drain<'_, K1, K2, V> {
self.key_map.drain();
Drain {
base: self.value_map.drain(),
}
}
#[inline]
pub fn clear(&mut self) {
self.value_map.clear();
self.key_map.clear();
}
#[inline]
pub fn hasher(&self) -> &S {
self.value_map.hasher()
}
}
impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
where
K1: Eq + Hash,
K2: Eq + Hash,
S: BuildHasher,
{
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.value_map.reserve(additional);
self.key_map.reserve(additional);
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.value_map.try_reserve(additional)?;
self.key_map.try_reserve(additional)
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.value_map.shrink_to_fit();
self.key_map.shrink_to_fit();
}
#[inline]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.value_map.shrink_to(min_capacity);
self.key_map.shrink_to(min_capacity);
}
#[inline]
pub fn get_key1<Q: ?Sized>(&self, k1: &Q) -> Option<&V>
where
K1: Borrow<Q>,
Q: Hash + Eq,
{
match self.value_map.get(k1) {
Some((_, value)) => Some(value),
None => None,
}
}
#[inline]
pub fn get_key2<Q: ?Sized>(&self, k2: &Q) -> Option<&V>
where
K2: Borrow<Q>,
Q: Hash + Eq,
{
match self.key_map.get(k2) {
Some(k1) => match self.value_map.get(k1) {
Some((_, value)) => Some(value),
None => None,
},
None => None,
}
}
#[inline]
pub fn get_keys<Q1: ?Sized, Q2: ?Sized>(&self, k1: &Q1, k2: &Q2) -> Option<&V>
where
K1: Borrow<Q1>,
K2: Borrow<Q2>,
Q1: Hash + Eq,
Q2: Hash + Eq,
{
match self.value_map.get_key_value(k1) {
Some((k1_v, (k2_v, val))) => match self.key_map.get_key_value(k2) {
Some((k2_k, k1_k)) if k1_v == k1_k && k2_v == k2_k => Some(val),
_ => None,
},
None => None,
}
}
#[inline]
pub fn get_key1_value<Q: ?Sized>(&self, k1: &Q) -> Option<(&K1, &V)>
where
K1: Borrow<Q>,
Q: Hash + Eq,
{
match self.value_map.get_key_value(k1) {
Some((key_one, (_, value))) => Some((key_one, value)),
None => None,
}
}
#[inline]
pub fn get_key2_value<Q: ?Sized>(&self, k2: &Q) -> Option<(&K2, &V)>
where
K2: Borrow<Q>,
Q: Hash + Eq,
{
match self.key_map.get_key_value(k2) {
Some((key_two, key_one)) => match self.value_map.get(key_one) {
Some((_, value)) => Some((key_two, value)),
None => None,
},
None => None,
}
}
#[inline]
pub fn get_keys_value<Q1: ?Sized, Q2: ?Sized>(&self, k1: &Q1, k2: &Q2) -> Option<(&K1, &K2, &V)>
where
K1: Borrow<Q1>,
K2: Borrow<Q2>,
Q1: Hash + Eq,
Q2: Hash + Eq,
{
match self.value_map.get_key_value(k1) {
Some((k1_v, (k2_v, val))) => match self.key_map.get_key_value(k2) {
Some((k2_k, k1_k)) if k1_v == k1_k && k2_v == k2_k => Some((k1_v, k2_k, val)),
_ => None,
},
None => None,
}
}
#[inline]
pub fn contains_key1<Q: ?Sized>(&self, k1: &Q) -> bool
where
K1: Borrow<Q>,
Q: Hash + Eq,
{
self.value_map.contains_key(k1)
}
#[inline]
pub fn contains_key2<Q: ?Sized>(&self, k2: &Q) -> bool
where
K2: Borrow<Q>,
Q: Hash + Eq,
{
self.key_map.contains_key(k2)
}
#[inline]
pub fn contains_keys<Q1: ?Sized, Q2: ?Sized>(&self, k1: &Q1, k2: &Q2) -> bool
where
K1: Borrow<Q1>,
K2: Borrow<Q2>,
Q1: Hash + Eq,
Q2: Hash + Eq,
{
match self.value_map.get_key_value(k1) {
Some((k1_v, (k2_v, _))) => match self.key_map.get_key_value(k2) {
Some((k2_k, k1_k)) => k1_v == k1_k && k2_v == k2_k,
None => false,
},
None => false,
}
}
#[inline]
pub fn get_mut_key1<Q: ?Sized>(&mut self, k1: &Q) -> Option<&mut V>
where
K1: Borrow<Q>,
Q: Hash + Eq,
{
match self.value_map.get_mut(k1) {
Some((_, value)) => Some(value),
None => None,
}
}
#[inline]
pub fn get_mut_key2<Q: ?Sized>(&mut self, k2: &Q) -> Option<&mut V>
where
K2: Borrow<Q>,
Q: Hash + Eq,
{
match self.key_map.get(k2) {
Some(key) => match self.value_map.get_mut(key) {
Some((_, value)) => Some(value),
None => None,
},
None => None,
}
}
#[inline]
pub fn get_mut_keys<Q1: ?Sized, Q2: ?Sized>(&mut self, k1: &Q1, k2: &Q2) -> Option<&mut V>
where
K1: Borrow<Q1>,
K2: Borrow<Q2>,
Q1: Hash + Eq,
Q2: Hash + Eq,
{
match self.value_map.get_mut(k1) {
Some((ref k2_v, val)) => match self.key_map.get_key_value(k2) {
Some((k2_k, k1_k)) if k2_v == k2_k && k1 == k1_k.borrow() => Some(val),
_ => None,
},
None => None,
}
}
#[inline]
pub fn remove_key1<Q: ?Sized>(&mut self, k1: &Q) -> Option<V>
where
K1: Borrow<Q>,
Q: Hash + Eq,
{
match self.value_map.remove(k1) {
Some((key, value)) => {
self.key_map.remove(&key);
Some(value)
}
None => None,
}
}
#[inline]
pub fn remove_key2<Q: ?Sized>(&mut self, k2: &Q) -> Option<V>
where
K2: Borrow<Q>,
Q: Hash + Eq,
{
match self.key_map.remove(k2) {
Some(key) => match self.value_map.remove(&key) {
Some((_, value)) => Some(value),
None => None,
},
None => None,
}
}
#[inline]
pub fn remove_keys<Q1: ?Sized, Q2: ?Sized>(&mut self, k1: &Q1, k2: &Q2) -> Option<V>
where
K1: Borrow<Q1>,
K2: Borrow<Q2>,
Q1: Hash + Eq,
Q2: Hash + Eq,
{
match self.value_map.get_key_value(k1) {
Some((k1_v, (k2_v, _))) => match self.key_map.get_key_value(k2) {
Some((k2_k, k1_k)) if k1_v == k1_k && k2_v == k2_k => {
self.key_map.remove(k2);
match self.value_map.remove(k1) {
Some((_, value)) => Some(value),
None => None,
}
}
_ => None,
},
None => None,
}
}
}
impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
where
K1: Eq + Hash + Clone,
K2: Eq + Hash + Clone,
S: BuildHasher,
{
#[inline]
pub fn entry(&mut self, k1: K1, k2: K2) -> Result<Entry<'_, K1, K2, V>, EntryError<K1, K2>> {
match self.value_map.get(&k1) {
None => match self.key_map.get(&k2) {
None => {
Ok(unsafe { self.map_vacant_entry(k1, k2) })
}
Some(_) => Err(EntryError {
error: ErrorKind::VacantK1AndOccupiedK2,
keys: (k1, k2),
}),
},
Some((key2_exist, _)) => match self.key_map.get(&k2) {
Some(key1_exist) => {
return if k1 == *key1_exist && k2 == *key2_exist {
Ok(unsafe { self.map_occupied_entry(k1, k2) })
} else {
Err(EntryError {
error: ErrorKind::KeysPointsToDiffEntries,
keys: (k1, k2),
})
};
}
None => Err(EntryError {
error: ErrorKind::OccupiedK1AndVacantK2,
keys: (k1, k2),
}),
},
}
}
#[inline(always)]
unsafe fn map_occupied_entry(&mut self, k1: K1, k2: K2) -> Entry<'_, K1, K2, V> {
let raw_v = self.value_map.entry(k1);
let raw_k = self.key_map.entry(k2);
match raw_v {
hash_map::Entry::Occupied(base_v) => match raw_k {
hash_map::Entry::Occupied(base_k) => {
Entry::Occupied(OccupiedEntry { base_v, base_k })
}
_ => unreachable_unchecked(),
},
_ => unreachable_unchecked(),
}
}
#[inline(always)]
unsafe fn map_vacant_entry(&mut self, k1: K1, k2: K2) -> Entry<'_, K1, K2, V> {
let raw_v = self.value_map.entry(k1);
let raw_k = self.key_map.entry(k2);
match raw_v {
hash_map::Entry::Vacant(base_v) => match raw_k {
hash_map::Entry::Vacant(base_k) => Entry::Vacant(VacantEntry { base_v, base_k }),
_ => unreachable_unchecked(),
},
_ => unreachable_unchecked(),
}
}
#[inline]
pub fn insert_unchecked(&mut self, k1: K1, k2: K2, v: V) -> Option<V> {
self.key_map.insert(k2.clone(), k1.clone());
match self.value_map.insert(k1, (k2, v)) {
Some((_, v)) => Some(v),
None => None,
}
}
#[inline]
pub fn insert(&mut self, k1: K1, k2: K2, v: V) -> Option<Result<V, InsertError<K1, K2, V>>> {
match self.entry(k1, k2) {
Ok(entry) => match entry {
Entry::Occupied(mut entry) => {
let v = entry.insert(v);
Some(Ok(v))
}
Entry::Vacant(entry) => {
entry.insert(v);
None
}
},
Err(EntryError { error, keys }) => Some(Err(InsertError {
error,
keys,
value: v,
})),
}
}
#[inline]
pub fn try_insert(
&mut self,
k1: K1,
k2: K2,
v: V,
) -> Result<&mut V, TryInsertError<K1, K2, V>> {
match self.entry(k1, k2) {
Ok(entry) => match entry {
Entry::Occupied(entry) => {
Err(TryInsertError::Occupied(OccupiedError { entry, value: v }))
}
Entry::Vacant(entry) => Ok(entry.insert(v)),
},
Err(EntryError { error, keys }) => Err(TryInsertError::Insert(InsertError {
error,
keys,
value: v,
})),
}
}
}
#[macro_export]
macro_rules! dhashmap {
() => (DHashMap::new());
($($key1:expr, $key2:expr => $value:expr),+ $(,)?) => (
DHashMap::<_, _, _, std::collections::hash_map::RandomState>::from_iter([$(($key1, $key2, $value)),+])
);
($(($key1:expr, $key2:expr) => $value:expr),+ $(,)?) => (
DHashMap::<_, _, _, std::collections::hash_map::RandomState>::from_iter([$(($key1, $key2, $value)),+])
);
}
impl<K1, K2, V, S> PartialEq for DHashMap<K1, K2, V, S>
where
K1: Eq + Hash,
K2: Eq + Hash,
V: PartialEq,
S: BuildHasher,
{
fn eq(&self, other: &DHashMap<K1, K2, V, S>) -> bool {
let DHashMap {
value_map: lv_map,
key_map: lk_map,
} = self;
let DHashMap {
value_map: rv_map,
key_map: rk_map,
} = other;
if lv_map.len() != rv_map.len() && lk_map.len() != rk_map.len() {
return false;
}
lv_map
.iter()
.all(|(k1, tuple)| rv_map.get(k1).map_or(false, |tup| *tuple == *tup))
&& lk_map
.iter()
.all(|(k1, k2)| rk_map.get(k1).map_or(false, |k| *k2 == *k))
}
}
impl<K1, K2, V, S> Eq for DHashMap<K1, K2, V, S>
where
K1: Eq + Hash,
K2: Eq + Hash,
V: Eq,
S: BuildHasher,
{
}
impl<K1, K2, V, S> Default for DHashMap<K1, K2, V, S>
where
S: Default + Clone,
{
#[inline]
fn default() -> DHashMap<K1, K2, V, S> {
DHashMap::with_hasher(Default::default())
}
}
impl<K1, K2, Q: ?Sized, V, S> Index<&Q> for DHashMap<K1, K2, V, S>
where
K1: Eq + Hash + Borrow<Q>,
K2: Eq + Hash,
Q: Eq + Hash,
S: BuildHasher,
{
type Output = V;
#[inline]
fn index(&self, key: &Q) -> &V {
self.get_key1(key).expect("no entry found for key")
}
}
impl<K1, K2, V, const N: usize> From<[(K1, K2, V); N]>
for DHashMap<K1, K2, V, hash_map::RandomState>
where
K1: Eq + Hash + Clone,
K2: Eq + Hash + Clone,
{
fn from(arr: [(K1, K2, V); N]) -> Self {
Self::from_iter(arr)
}
}
impl<K1, K2, V, S> FromIterator<(K1, K2, V)> for DHashMap<K1, K2, V, S>
where
K1: Eq + Hash + Clone,
K2: Eq + Hash + Clone,
S: BuildHasher + Default + Clone,
{
fn from_iter<T: IntoIterator<Item = (K1, K2, V)>>(iter: T) -> DHashMap<K1, K2, V, S> {
let mut map = DHashMap::with_hasher(Default::default());
map.extend(iter);
map
}
}
impl<K1, K2, V, S> Extend<(K1, K2, V)> for DHashMap<K1, K2, V, S>
where
K1: Eq + Hash + Clone,
K2: Eq + Hash + Clone,
S: BuildHasher,
{
#[inline]
fn extend<T: IntoIterator<Item = (K1, K2, V)>>(&mut self, iter: T) {
let iter = iter.into_iter();
let reserve = if self.is_empty() {
iter.size_hint().0
} else {
(iter.size_hint().0 + 1) / 2
};
self.reserve(reserve);
iter.for_each(move |(k1, k2, v)| {
self.insert(k1, k2, v);
});
}
}
impl<'a, K1, K2, V, S> Extend<(&'a K1, &'a K2, &'a V)> for DHashMap<K1, K2, V, S>
where
K1: Eq + Hash + Copy,
K2: Eq + Hash + Copy,
V: Copy,
S: BuildHasher,
{
#[inline]
fn extend<T: IntoIterator<Item = (&'a K1, &'a K2, &'a V)>>(&mut self, iter: T) {
self.extend(iter.into_iter().map(|(&k1, &k2, &v)| (k1, k2, v)))
}
}
impl<'a, K1, K2, V, S> Extend<&'a (K1, K2, V)> for DHashMap<K1, K2, V, S>
where
K1: Eq + Hash + Copy,
K2: Eq + Hash + Copy,
V: Copy,
S: BuildHasher,
{
#[inline]
fn extend<T: IntoIterator<Item = &'a (K1, K2, V)>>(&mut self, iter: T) {
self.extend(iter.into_iter().map(|&(k1, k2, v)| (k1, k2, v)))
}
}
#[derive(Clone, Debug)]
pub struct Iter<'a, K1: 'a, K2: 'a, V: 'a> {
base: hash_map::Iter<'a, K1, (K2, V)>,
}
impl<'a, K1, K2, V> Iterator for Iter<'a, K1, K2, V> {
type Item = (&'a K1, &'a K2, &'a V);
#[inline]
fn next(&mut self) -> Option<(&'a K1, &'a K2, &'a V)> {
match self.base.next() {
Some((k1, (k2, val))) => Some((k1, k2, val)),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.base.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for Iter<'_, K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.base.len()
}
}
impl<K1, K2, V> FusedIterator for Iter<'_, K1, K2, V> {}
#[derive(Clone, Debug)]
pub struct Keys<'a, K1: 'a, K2: 'a, V: 'a> {
inner: Iter<'a, K1, K2, V>,
}
impl<'a, K1, K2, V> Iterator for Keys<'a, K1, K2, V> {
type Item = (&'a K1, &'a K2);
#[inline]
fn next(&mut self) -> Option<(&'a K1, &'a K2)> {
match self.inner.next() {
Some((k1, k2, _)) => Some((k1, k2)),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for Keys<'_, K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<K1, K2, V> FusedIterator for Keys<'_, K1, K2, V> {}
#[derive(Clone, Debug)]
pub struct Values<'a, K1: 'a, K2: 'a, V: 'a> {
inner: Iter<'a, K1, K2, V>,
}
impl<'a, K1, K2, V> Iterator for Values<'a, K1, K2, V> {
type Item = &'a V;
#[inline]
fn next(&mut self) -> Option<&'a V> {
match self.inner.next() {
Some((_, _, val)) => Some(val),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for Values<'_, K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<K1, K2, V> FusedIterator for Values<'_, K1, K2, V> {}
#[derive(Debug)]
pub struct IterMut<'a, K1: 'a, K2: 'a, V: 'a> {
base: hash_map::IterMut<'a, K1, (K2, V)>,
}
impl<'a, K1, K2, V> Iterator for IterMut<'a, K1, K2, V> {
type Item = (&'a K1, &'a K2, &'a mut V);
#[inline]
fn next(&mut self) -> Option<(&'a K1, &'a K2, &'a mut V)> {
match self.base.next() {
Some((k1, (ref k2, val))) => Some((k1, k2, val)),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.base.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for IterMut<'_, K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.base.len()
}
}
impl<K1, K2, V> FusedIterator for IterMut<'_, K1, K2, V> {}
#[derive(Debug)]
pub struct ValuesMut<'a, K1: 'a, K2: 'a, V: 'a> {
inner: IterMut<'a, K1, K2, V>,
}
impl<'a, K1, K2, V> Iterator for ValuesMut<'a, K1, K2, V> {
type Item = &'a mut V;
#[inline]
fn next(&mut self) -> Option<&'a mut V> {
match self.inner.next() {
Some((_, _, val)) => Some(val),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for ValuesMut<'_, K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<K1, K2, V> FusedIterator for ValuesMut<'_, K1, K2, V> {}
#[derive(Debug)]
pub struct Drain<'a, K1: 'a, K2: 'a, V: 'a> {
base: hash_map::Drain<'a, K1, (K2, V)>,
}
impl<'a, K1, K2, V> Iterator for Drain<'a, K1, K2, V> {
type Item = (K1, K2, V);
#[inline]
fn next(&mut self) -> Option<(K1, K2, V)> {
match self.base.next() {
Some((key_one, (key_two, value))) => Some((key_one, key_two, value)),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.base.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for Drain<'_, K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.base.len()
}
}
impl<K1, K2, V> FusedIterator for Drain<'_, K1, K2, V> {}
#[derive(Debug)]
pub struct IntoIter<K1, K2, V> {
base: hash_map::IntoIter<K1, (K2, V)>,
}
impl<K1, K2, V> Iterator for IntoIter<K1, K2, V> {
type Item = (K1, K2, V);
#[inline]
fn next(&mut self) -> Option<(K1, K2, V)> {
match self.base.next() {
Some((k1, (k2, v))) => Some((k1, k2, v)),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.base.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for IntoIter<K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.base.len()
}
}
impl<K1, K2, V> FusedIterator for IntoIter<K1, K2, V> {}
#[derive(Debug)]
pub struct IntoKeys<K1, K2, V> {
inner: IntoIter<K1, K2, V>,
}
impl<K1, K2, V> Iterator for IntoKeys<K1, K2, V> {
type Item = (K1, K2);
#[inline]
fn next(&mut self) -> Option<(K1, K2)> {
match self.inner.next() {
Some((k1, k2, _)) => Some((k1, k2)),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for IntoKeys<K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<K1, K2, V> FusedIterator for IntoKeys<K1, K2, V> {}
#[derive(Debug)]
pub struct IntoValues<K1, K2, V> {
inner: IntoIter<K1, K2, V>,
}
impl<K1, K2, V> Iterator for IntoValues<K1, K2, V> {
type Item = V;
#[inline]
fn next(&mut self) -> Option<V> {
match self.inner.next() {
Some((_, _, v)) => Some(v),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K1, K2, V> ExactSizeIterator for IntoValues<K1, K2, V> {
#[inline]
fn len(&self) -> usize {
self.inner.len()
}
}
impl<K1, K2, V> FusedIterator for IntoValues<K1, K2, V> {}
impl<'a, K1, K2, V, S> IntoIterator for &'a DHashMap<K1, K2, V, S> {
type Item = (&'a K1, &'a K2, &'a V);
type IntoIter = Iter<'a, K1, K2, V>;
fn into_iter(self) -> Iter<'a, K1, K2, V> {
self.iter()
}
}
impl<'a, K1, K2, V, S> IntoIterator for &'a mut DHashMap<K1, K2, V, S> {
type Item = (&'a K1, &'a K2, &'a mut V);
type IntoIter = IterMut<'a, K1, K2, V>;
fn into_iter(self) -> IterMut<'a, K1, K2, V> {
self.iter_mut()
}
}
impl<K1, K2, V, S> IntoIterator for DHashMap<K1, K2, V, S> {
type Item = (K1, K2, V);
type IntoIter = IntoIter<K1, K2, V>;
fn into_iter(self) -> IntoIter<K1, K2, V> {
IntoIter {
base: self.value_map.into_iter(),
}
}
}
#[derive(Debug)]
pub struct OccupiedEntry<'a, K1: 'a, K2: 'a, V: 'a> {
base_v: hash_map::OccupiedEntry<'a, K1, (K2, V)>,
base_k: hash_map::OccupiedEntry<'a, K2, K1>,
}
impl<'a, K1, K2, V> OccupiedEntry<'a, K1, K2, V> {
#[inline]
pub fn key1(&self) -> &K1 {
self.base_v.key()
}
#[inline]
pub fn key2(&self) -> &K2 {
self.base_k.key()
}
#[inline]
pub fn keys(&self) -> (&K1, &K2) {
(self.base_v.key(), self.base_k.key())
}
#[inline]
pub fn remove_entry(self) -> (K1, K2, V) {
self.base_k.remove_entry();
let (k1, (k2, v)) = self.base_v.remove_entry();
(k1, k2, v)
}
#[inline]
pub fn get(&self) -> &V {
let (_, v) = self.base_v.get();
v
}
#[inline]
pub fn get_mut(&mut self) -> &mut V {
let (_, v) = self.base_v.get_mut();
v
}
#[inline]
pub fn into_mut(self) -> &'a mut V {
let (_, v) = self.base_v.into_mut();
v
}
#[inline]
pub fn insert(&mut self, mut value: V) -> V {
let old_value = self.get_mut();
mem::swap(&mut value, old_value);
value
}
#[inline]
pub fn remove(self) -> V {
self.remove_entry().2
}
}
#[derive(Debug)]
pub struct VacantEntry<'a, K1: 'a, K2: 'a, V: 'a> {
base_v: hash_map::VacantEntry<'a, K1, (K2, V)>,
base_k: hash_map::VacantEntry<'a, K2, K1>,
}
impl<'a, K1: 'a, K2: 'a, V: 'a> VacantEntry<'a, K1, K2, V> {
#[inline]
pub fn key1(&self) -> &K1 {
self.base_v.key()
}
#[inline]
pub fn key2(&self) -> &K2 {
self.base_k.key()
}
#[inline]
pub fn keys(&self) -> (&K1, &K2) {
(self.base_v.key(), self.base_k.key())
}
#[inline]
pub fn into_keys(self) -> (K1, K2) {
(self.base_v.into_key(), self.base_k.into_key())
}
}
impl<'a, K1: 'a + Clone, K2: 'a + Clone, V: 'a> VacantEntry<'a, K1, K2, V> {
#[inline]
pub fn insert(self, value: V) -> &'a mut V {
let k2 = self.base_k.key().clone();
self.base_k.insert(self.base_v.key().clone());
let (_, v) = self.base_v.insert((k2, value));
v
}
}
#[derive(Debug)]
pub enum Entry<'a, K1: 'a, K2: 'a, V: 'a> {
Occupied(OccupiedEntry<'a, K1, K2, V>),
Vacant(VacantEntry<'a, K1, K2, V>),
}
impl<'a, K1: Clone, K2: Clone, V> Entry<'a, K1, K2, V> {
#[inline]
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default),
}
}
#[inline]
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default()),
}
}
#[inline]
pub fn or_insert_with_key1<F: FnOnce(&K1) -> V>(self, default: F) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let value = default(entry.key1());
entry.insert(value)
}
}
}
#[inline]
pub fn or_insert_with_key2<F: FnOnce(&K2) -> V>(self, default: F) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let value = default(entry.key2());
entry.insert(value)
}
}
}
#[inline]
pub fn or_insert_with_keys<F: FnOnce(&K1, &K2) -> V>(self, default: F) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let value = default(entry.key1(), entry.key2());
entry.insert(value)
}
}
}
}
impl<'a, K1, K2, V> Entry<'a, K1, K2, V> {
#[inline]
pub fn key1(&self) -> &K1 {
match *self {
Entry::Occupied(ref entry) => entry.key1(),
Entry::Vacant(ref entry) => entry.key1(),
}
}
#[inline]
pub fn key2(&self) -> &K2 {
match *self {
Entry::Occupied(ref entry) => entry.key2(),
Entry::Vacant(ref entry) => entry.key2(),
}
}
#[inline]
pub fn keys(&self) -> (&K1, &K2) {
match *self {
Entry::Occupied(ref entry) => entry.keys(),
Entry::Vacant(ref entry) => entry.keys(),
}
}
#[inline]
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut V),
{
match self {
Entry::Occupied(mut entry) => {
f(entry.get_mut());
Entry::Occupied(entry)
}
Entry::Vacant(entry) => Entry::Vacant(entry),
}
}
}
impl<'a, K1: Clone, K2: Clone, V: Default> Entry<'a, K1, K2, V> {
#[inline]
pub fn or_default(self) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(Default::default()),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ErrorKind {
VacantK1AndOccupiedK2,
OccupiedK1AndVacantK2,
KeysPointsToDiffEntries,
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let error_txt = match *self {
ErrorKind::OccupiedK1AndVacantK2 => "occupied key #1 but vacant key #2",
ErrorKind::VacantK1AndOccupiedK2 => "vacant key #1 but occupied key #2",
ErrorKind::KeysPointsToDiffEntries => {
"key #1 and key #2 exist, but point to different entries"
}
};
write!(f, "{}", error_txt)
}
}
impl std::error::Error for ErrorKind {}
#[derive(Debug, PartialEq)]
pub struct EntryError<K1, K2> {
pub error: ErrorKind,
pub keys: (K1, K2),
}
impl<K1: Debug, K2: Debug> fmt::Display for EntryError<K1, K2> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let key_txt = match self.error {
ErrorKind::VacantK1AndOccupiedK2 => format!(
"key #1 = {:?} - vacant, but key #2 = {:?} - exists",
self.keys.0, self.keys.1
),
ErrorKind::OccupiedK1AndVacantK2 => format!(
"key #1 = {:?} - exists, but key #2 = {:?} - vacant",
self.keys.0, self.keys.1
),
ErrorKind::KeysPointsToDiffEntries => format!(
"key #1 = {:?} and key #2 = {:?} point to different entries",
self.keys.0, self.keys.1
),
};
write!(f, "failed to get entry, because {}", key_txt)
}
}
impl<K1: Debug, K2: Debug> std::error::Error for EntryError<K1, K2> {}
#[derive(Debug, PartialEq)]
pub struct InsertError<K1, K2, V> {
pub error: ErrorKind,
pub keys: (K1, K2),
pub value: V,
}
impl<K1: Debug, K2: Debug, V: Debug> fmt::Display for InsertError<K1, K2, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let key_txt = match self.error {
ErrorKind::VacantK1AndOccupiedK2 => format!(
"key #1 = {:?} - vacant, but key #2 = {:?} - exists",
self.keys.0, self.keys.1
),
ErrorKind::OccupiedK1AndVacantK2 => format!(
"key #1 = {:?} - exists, but key #2 = {:?} - vacant",
self.keys.0, self.keys.1
),
ErrorKind::KeysPointsToDiffEntries => format!(
"key #1 = {:?} and key #2 = {:?} point to different entries",
self.keys.0, self.keys.1
),
};
write!(
f,
"failed to insert {:?}, because of {}",
self.value, key_txt
)
}
}
impl<K1: Debug, K2: Debug, V: Debug> std::error::Error for InsertError<K1, K2, V> {}
#[derive(Debug)]
pub struct OccupiedError<'a, K1: 'a, K2: 'a, V: 'a> {
pub entry: OccupiedEntry<'a, K1, K2, V>,
pub value: V,
}
impl<'a, K1: Debug, K2: Debug, V: Debug> fmt::Display for OccupiedError<'a, K1, K2, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"failed to insert {:?}, key #1 = {:?} and key #2 = {:?} already exist with value {:?}",
self.value,
self.entry.key1(),
self.entry.key2(),
self.entry.get(),
)
}
}
impl<'a, K1: Debug, K2: Debug, V: Debug> std::error::Error for OccupiedError<'a, K1, K2, V> {}
#[derive(Debug)]
pub enum TryInsertError<'a, K1: 'a, K2: 'a, V: 'a> {
Occupied(OccupiedError<'a, K1, K2, V>),
Insert(InsertError<K1, K2, V>),
}
impl<'a, K1: Debug, K2: Debug, V: Debug> fmt::Display for TryInsertError<'a, K1, K2, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let txt = match self {
TryInsertError::Occupied(error) => error.to_string(),
TryInsertError::Insert(error) => error.to_string(),
};
write!(f, "{}", txt)
}
}
impl<'a, K1: Debug, K2: Debug, V: Debug> std::error::Error for TryInsertError<'a, K1, K2, V> {}