#[doc(hidden)]
#[macro_export]
macro_rules! multimap_base_impl {
($keys:ty) => {
#[must_use]
pub fn new() -> Self {
Self {
inner: <$keys>::new(),
len: 0,
}
}
#[must_use]
pub fn with_key_capacity(capacity: usize) -> Self {
Self {
inner: <$keys>::with_capacity(capacity),
len: 0,
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! multimap_base2_impl {
($keys:tt) => {
#[inline]
pub fn with_hasher(hash_builder: S) -> Self {
Self::with_key_capacity_and_hasher(0, hash_builder)
}
#[inline]
pub fn with_key_capacity_and_hasher(n: usize, hash_builder: S) -> Self {
Self {
inner: $keys::with_capacity_and_hasher(n, hash_builder),
len: 0,
}
}
#[inline]
pub fn key_capacity(&self) -> usize {
self.inner.capacity()
}
pub const fn len(&self) -> usize {
self.len
}
pub const fn is_empty(&self) -> bool {
self.len == 0
}
pub fn keys_len(&self) -> usize {
self.inner.len()
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! multimap_mutators_impl {
($keys:ty, $values:ty, $values_ctx:expr, $values_class:tt, ($($keys_ref:tt)*), ($($values_ref:tt)*)) => {
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional);
}
#[inline]
pub fn shrink_keys_to_fit(&mut self) {
self.inner.shrink_to_fit();
}
pub fn shrink_values_to_fit(&mut self) {
self.inner.iter_mut().for_each(|(_,values)| values.shrink_to_fit());
}
#[doc = concat!("Return a reference to the ", stringify!($values_class), " stored for `key`, if it is present, else `None`.")]
#[inline]
pub fn get<Q>(&self, key: &Q) -> Option<&$values>
where
Q: ?Sized,
$($keys_ref)*,
{
self.inner.get(key)
}
pub fn get_key_values<Q>(&self, key: &Q) -> Option<(&K, &$values)>
where
Q: ?Sized,
$($keys_ref)*,
{
self.inner.get_key_value(key)
}
#[inline]
pub fn contains_key<Q>(&self, key: &Q) -> bool
where
Q: ?Sized,
$($keys_ref)*,
{
self.get(key).is_some()
}
$crate::insert!($values_class $values_ctx);
#[inline]
pub fn retain<F>(&mut self, f: F)
where
F: Fn(&K, &V) -> bool
{
self.inner.retain(|k,values| {
values.retain(|x| {
let retain = f(k,x);
if !retain {
self.len -= 1;
}
retain
});
!values.is_empty()
});
}
pub fn contains<Q, R>(&self, key: &Q, value: &R) -> bool
where
Q: ?Sized,
R: ?Sized,
$($keys_ref)*,
$($values_ref)*,
{
if let Some(values) = self.inner.get(key) {
$crate::values_contains!($values_class, values, value)
} else {
false
}
}
pub const fn as_map(&self) -> &$keys {
&self.inner
}
pub fn into_map(self) -> $keys {
self.inner
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! multimap_remove_impl {
(unordered, $values:ty, $values_class:tt, ($($keys_ref:tt)*), ($($values_ref:tt)*)) => {
#[inline]
pub fn remove_key<Q>(&mut self, key: &Q) -> Option<$values>
where
Q: ?Sized,
$($keys_ref)*
{
self.inner.remove(key).map(|values| {
self.len -= values.len();
values
})
}
#[inline]
pub fn remove_key_entry<Q>(&mut self, key: &Q) -> Option<(K, $values)>
where
Q: ?Sized,
$($keys_ref)*
{
self.inner.remove_entry(key).map( |(key,values)| {
self.len -= values.len();
(key,values)
})
}
pub fn remove<Q, R>(&mut self, key: &Q, value: &R) -> Option<V>
where
Q: ?Sized,
R: ?Sized,
$($keys_ref)*,
$($values_ref)*,
{
if let Some(values) = self.inner.get_mut(key) {
let value = $crate::values_remove!(unordered, $values_class, values, value);
if value.is_some() {
if values.is_empty() {
self.inner.remove(key);
}
self.len -= 1;
}
value
} else {
None
}
}
};
(ordered, $values:ty, $values_class:tt, ($($keys_ref:tt)*), ($($values_ref:tt)*)) => {
#[inline]
pub fn swap_remove_key<Q>(&mut self, key: &Q) -> Option<$values>
where
Q: ?Sized,
$($keys_ref)*
{
self.inner.swap_remove(key).map(|values| {
self.len -= values.len();
values
})
}
#[inline]
pub fn shift_remove_key<Q>(&mut self, key: &Q) -> Option<$values>
where
Q: ?Sized,
$($keys_ref)*
{
self.inner.shift_remove(key).map(|values| {
self.len -= values.len();
values
})
}
#[inline]
pub fn swap_remove_key_entry<Q>(&mut self, key: &Q) -> Option<(K, $values)>
where
Q: ?Sized,
$($keys_ref)*
{
self.inner.swap_remove_entry(key).map( |(key,values)| {
self.len -= values.len();
(key,values)
})
}
#[inline]
pub fn shift_remove_key_entry<Q>(&mut self, key: &Q) -> Option<(K, $values)>
where
Q: ?Sized,
$($keys_ref)*
{
self.inner.shift_remove_entry(key).map( |(key,values)| {
self.len -= values.len();
(key,values)
})
}
pub fn swap_remove<Q, R>(&mut self, key: &Q, value: &R) -> Option<V>
where
Q: ?Sized,
R: ?Sized,
$($keys_ref)*,
$($values_ref)*,
{
if let Some(values) = self.inner.get_mut(key) {
let value = $crate::values_remove!(ordered, swap, $values_class, values, value);
if value.is_some() {
if values.is_empty() {
self.inner.swap_remove(key);
}
self.len -= 1;
}
value
} else {
None
}
}
pub fn shift_remove<Q, R>(&mut self, key: &Q, value: &R) -> Option<V>
where
Q: ?Sized,
R: ?Sized,
$($keys_ref)*,
$($values_ref)*,
{
if let Some(values) = self.inner.get_mut(key) {
let value = $crate::values_remove!(ordered, shift, $values_class, values, value);
if value.is_some() {
if values.is_empty() {
self.inner.shift_remove(key);
}
self.len -= 1;
}
value
} else {
None
}
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! index_multimap_impl {
($keys:ty, $values:ty, $values_ctx:expr, $values_class:tt, ($($keys_ref:tt)*), ($($values_ref:tt)*)) => {
insert_full!($values_class $values_ctx);
pub fn get_full<Q>(&self, key: &Q) -> Option<(usize, &K, &$values)>
where
Q: ?Sized,
$($keys_ref)*,
{
self.inner.get_full(key)
}
pub fn get_key_index<Q>(&self, key: &Q) -> Option<usize>
where
Q: ?Sized,
$($keys_ref)*,
{
if self.is_empty() {
None
} else {
self.inner.get_index_of(key)
}
}
pub fn get_index(&self, index: usize) -> Option<(&K, &$values)> {
if index >= self.inner.len() {
None
} else {
self.inner.get_index(index)
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! insert {
(set $values_ctx:expr) => {
#[inline]
pub fn insert(&mut self, key: K, value: V) -> bool {
if self
.inner
.entry(key)
.or_insert_with(|| $values_ctx)
.insert(value)
{
self.len += 1;
true
} else {
false
}
}
};
(vec_equal $values_ctx:expr) => {
$crate::vec_insert!($values_ctx);
};
(vec_equivalent $values_ctx:expr) => {
$crate::vec_insert!($values_ctx);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! vec_insert {
($values_ctx:expr) => {
#[inline]
pub fn insert(&mut self, key: K, value: V) {
self.inner
.entry(key)
.or_insert_with(|| $values_ctx)
.push(value);
self.len += 1;
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! insert_full {
(set $values_ctx:expr) => {
pub fn insert_full(&mut self, key: K, value: V) -> (usize, usize, bool) {
match self.inner.get_full_mut(&key) {
Some((keys_index, _, values)) => {
let (values_index, success) = values.insert_full(value);
if success {
self.len += 1;
}
(keys_index, values_index, success)
}
None => {
let mut values = $values_ctx;
values.insert(value);
let (keys_index, _) = self.inner.insert_full(key, values);
self.len += 1;
(keys_index, 0, true)
}
}
}
};
(vec $values_ctx:expr) => {
pub fn insert_full(&mut self, key: K, value: V) -> (usize, usize) {
match self.inner.get_full_mut(&key) {
Some((keys_index, _, values)) => {
let values_index = values.len();
values.push(value);
self.len += 1;
(keys_index, values_index)
}
None => {
let values = vec![value];
let (keys_index, _) = self.inner.insert_full(key, values);
self.len += 1;
(keys_index, 0)
}
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! values_contains {
(set, $values:ident, $value:ident) => {
$values.contains($value)
};
(vec_equivalent, $values:ident, $value:ident) => {
$values.iter().find(|x| $value.equivalent(x)).is_some()
};
(vec_equal, $values:ident, $value:ident) => {
$values.iter().find(|&x| $value == x.borrow()).is_some()
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! values_remove {
(ordered, swap, set, $values:ident, $value:ident) => {
$values.swap_take($value)
};
(ordered, shift, set, $values:ident, $value:ident) => {
$values.shift_take($value)
};
(ordered, shift, vec_equivalent, $values:ident, $value:ident) => {
$values
.iter()
.position(|x| $value.equivalent(x))
.map(|index| $values.remove(index)) };
(ordered, swap, vec_equivalent, $values:ident, $value:ident) => {
$values
.iter()
.position(|x| $value.equivalent(x))
.map(|index| $values.swap_remove(index))
};
(unordered, set, $values:ident, $value:ident) => {
$values.take($value)
};
(unordered, vec_equal, $values:ident, $value:ident) => {
$values
.iter()
.position(|x| $value == x.borrow())
.map(|index| $values.remove(index))
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! multimap_extend {
($type:tt, ($($generic_ids:tt)*), $inner_keys_type:tt, $inner_values_type:ty, ($($keys:tt)*), ($($values:tt)*), ($($keys_get:tt)*) )=> {
impl<$($generic_ids)*> Extend<(K, V)> for $type<$($generic_ids)*>
where
$($keys)*,
$($values)*,
S: BuildHasher + Default,
{
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iterable: I) {
let iter = iterable.into_iter();
let reserve = (iter.size_hint().0 + 1) / 2;
self.reserve(reserve);
iter.for_each(move |(k, v)| {
self.insert(k, v);
});
}
}
impl<'a, $($generic_ids)*> Extend<(&'a K, &'a V)> for $type<$($generic_ids)*>
where
$($keys)* + Copy,
$($values)* + Copy,
S: BuildHasher + Default,
{
fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iterable: I) {
self.extend(iterable.into_iter().map(|(&key, &value)| (key, value)));
}
}
impl<$($generic_ids)*> FromIterator<(K, V)> for $type<$($generic_ids)*>
where
$($keys)*,
$($values)*,
S: BuildHasher + Default,
{
fn from_iter<I: IntoIterator<Item = (K, V)>>(iterable: I) -> Self {
let iter = iterable.into_iter();
let (low, _) = iter.size_hint();
let mut map = Self::with_key_capacity_and_hasher(low, <_>::default());
map.extend(iter);
map
}
}
impl<$($generic_ids)*> From<$inner_keys_type<K,$inner_values_type,S>> for $type<$($generic_ids)*>
where
$($keys)*,
$($values)*,
S: BuildHasher + Default,
{
fn from(mut map: $inner_keys_type<K,$inner_values_type,S>) -> Self {
map.retain(|_k, v| !v.is_empty());
let len = map.iter().map(|(_k, v)| v.len()).sum();
$type { inner: map, len }
}
}
impl<$($generic_ids)*> Default for $type<$($generic_ids)*>
where
S: Default,
{
#[inline]
fn default() -> $type<$($generic_ids)*> {
$type::with_hasher(Default::default())
}
}
impl<K, Q: ?Sized, V, S> std::ops::Index<&Q> for $type<$($generic_ids)*>
where
$($keys_get)*,
$($values)*,
S: BuildHasher + Default,
{
type Output = $inner_values_type;
#[inline]
fn index(&self, key: &Q) -> &$inner_values_type {
self.get(key).expect("no entry found for key")
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! multimap_eq {
($type:tt, ($($values_generics:tt)*)) => {
impl<K, V1, S1, V2, S2> PartialEq<$type<K, V2, S2>> for $type<K, V1, S1>
where
K: Hash + Eq,
V1: $($values_generics)* + PartialEq<V2> + Borrow<V2>,
V2: $($values_generics)* + PartialEq<V1> + Borrow<V1>,
S1: BuildHasher + Default,
S2: BuildHasher + Default,
{
fn eq(&self, other: &$type<K, V2, S2>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter().all(|(key, value)| other.contains(key, value))
}
}
impl<K, V, S> Eq for $type<K, V, S>
where
K: Eq + Hash,
V: $($values_generics)*,
S: BuildHasher + Default,
{
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_iter {
($type:tt, ($($generic_ids:tt)*), $outer_iter:ty, $inner_iter:ty) => {
pub struct Iter<'a, $($generic_ids)*> where K: 'a, V: 'a{
outer: $outer_iter,
inner: Option<(&'a K, $inner_iter)>,
len: usize,
}
impl<'a, $($generic_ids)*> Iterator for Iter<'a, $($generic_ids)*> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
if let Some((current_key, inner_iter)) = &mut self.inner {
let next = inner_iter.next();
if let Some(next_value) = next {
Some((current_key, next_value))
} else {
if let Some((key, values)) = self.outer.next() {
let mut new_inner_iter = values.iter();
let v = new_inner_iter.next().unwrap();
self.inner = Some((key, new_inner_iter));
Some((key, v))
} else {
None
}
}
} else {
None
}
}
}
impl<$($generic_ids)*> ExactSizeIterator for Iter<'_, $($generic_ids)*> {
fn len(&self) -> usize {
self.len
}
}
impl<$($generic_ids)*> std::iter::FusedIterator for Iter<'_, $($generic_ids)*> {}
impl<$($generic_ids)*> Clone for Iter<'_, $($generic_ids)*> {
fn clone(&self) -> Self {
Iter {
outer: self.outer.clone(),
inner: self.inner.clone(),
len: self.len,
}
}
}
impl<$($generic_ids)*> std::fmt::Debug for Iter<'_, $($generic_ids)*>
where
K: std::fmt::Debug,
V: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
pub struct Values<'a, $($generic_ids)*>{
inner: Iter<'a, $($generic_ids)*>,
}
impl<'a, $($generic_ids)*> Iterator for Values<'a, $($generic_ids)*>
{
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map( |(_,v)| v)
}
}
impl<$($generic_ids)*> ExactSizeIterator for Values<'_, $($generic_ids)*> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<$($generic_ids)*> std::iter::FusedIterator for Values<'_, $($generic_ids)*> {}
impl<$($generic_ids)*> Clone for Values<'_, $($generic_ids)*> {
fn clone(&self) -> Self {
Values {
inner: self.inner.clone(),
}
}
}
impl<$($generic_ids)*> std::fmt::Debug for Values<'_, $($generic_ids)*>
where
V: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<K, V, S> $type<K, V, S> {
pub fn iter(&self) -> Iter<'_, $($generic_ids)*> {
let mut iter = self.inner.iter();
let inner = iter.next().map(|(k, v)| (k, v.iter()));
Iter {
outer: iter,
inner,
len: self.len,
}
}
pub fn values(&self) -> Values<'_, $($generic_ids)*> {
Values {
inner: self.iter(),
}
}
}
impl<'a, K, V, S> IntoIterator for &'a $type<K, V, S> {
type IntoIter = Iter<'a, $($generic_ids)*>;
type Item = (&'a K, &'a V);
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_keys {
($type:tt, ($($generic_ids:tt)*), $inner_iter:ty) => {
pub struct Keys<'a, $($generic_ids)*> {
inner: $inner_iter,
}
impl<'a, $($generic_ids)*> Iterator for Keys<'a, $($generic_ids)*> {
type Item = &'a K;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<$($generic_ids)*> ExactSizeIterator for Keys<'_, $($generic_ids)*> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<$($generic_ids)*> std::iter::FusedIterator for Keys<'_, $($generic_ids)*> {}
impl<$($generic_ids)*> Clone for Keys<'_, $($generic_ids)*> {
fn clone(&self) -> Self {
Keys {
inner: self.inner.clone(),
}
}
}
impl<$($generic_ids)*> std::fmt::Debug for Keys<'_, $($generic_ids)*>
where
K: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<K, V, S> $type<K, V, S> {
pub fn keys(&self) -> Keys<'_, $($generic_ids)*> {
Keys {
inner: self.inner.keys(),
}
}
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_into_iterator {
($type:tt, ($($generic_ids:tt)*), $outer_iter:ty, $inner_iter:ty) => {
#[derive(Debug)]
pub struct IntoIter<$($generic_ids)*> {
outer: $outer_iter,
inner: Option<(K, $inner_iter)>,
len: usize,
}
impl<$($generic_ids)*> Iterator for IntoIter<$($generic_ids)*>
where
K: Clone,
{
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
if let Some((current_key, inner_iter)) = &mut self.inner {
let next = inner_iter.next();
if let Some(next_value) = next {
Some((current_key.clone(), next_value))
} else {
if let Some((key, values)) = self.outer.next() {
let mut new_inner_iter = values.into_iter();
let v = new_inner_iter.next().unwrap();
self.inner = Some((key.clone(), new_inner_iter));
Some((key, v))
} else {
None
}
}
} else {
None
}
}
}
impl<$($generic_ids)*> ExactSizeIterator for IntoIter<$($generic_ids)*>
where
K: Clone,
{
fn len(&self) -> usize {
self.len
}
}
impl<$($generic_ids)*> std::iter::FusedIterator for IntoIter<$($generic_ids)*>
where
K: Clone,
{}
impl<K, V, S> IntoIterator for $type<K, V, S>
where
K: Clone,
{
type Item = (K, V);
type IntoIter = IntoIter<$($generic_ids)*>;
fn into_iter(self) -> Self::IntoIter {
let mut iter = self.inner.into_iter();
let inner = iter.next().map(|(k, v)| (k, v.into_iter()));
IntoIter {
outer: iter,
inner,
len: self.len,
}
}
}
#[derive(Debug)]
pub struct IntoValues<$($generic_ids)*> {
outer: $outer_iter,
inner: Option<$inner_iter>,
len: usize,
}
impl<$($generic_ids)*> Iterator for IntoValues<$($generic_ids)*> {
type Item = V;
fn next(&mut self) -> Option<Self::Item> {
if let Some(inner_iter) = &mut self.inner {
let next = inner_iter.next();
if let Some(next_value) = next {
Some(next_value)
} else {
if let Some((_key, values)) = self.outer.next() {
let mut new_inner_iter = values.into_iter();
let v = new_inner_iter.next().unwrap();
self.inner = Some(new_inner_iter);
Some(v)
} else {
None
}
}
} else {
None
}
}
}
impl<$($generic_ids)*> ExactSizeIterator for IntoValues<$($generic_ids)*> {
fn len(&self) -> usize {
self.len
}
}
impl<$($generic_ids)*> std::iter::FusedIterator for IntoValues<$($generic_ids)*> {}
impl<K, V, S> $type<K, V, S> {
pub fn into_values(self) -> IntoValues<$($generic_ids)*> {
let mut iter = self.inner.into_iter();
let inner = iter.next().map(|(_k, v)| v.into_iter());
IntoValues {
outer: iter,
inner,
len: self.len,
}
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_into_keys {
($type:tt, ($($generic_ids:tt)*), $inner_iter:ty) => {
#[derive(Debug)]
pub struct IntoKeys<$($generic_ids)*> {
inner: $inner_iter,
}
impl<$($generic_ids)*> Iterator for IntoKeys<$($generic_ids)*> {
type Item = K;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<$($generic_ids)*> ExactSizeIterator for IntoKeys<$($generic_ids)*> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<$($generic_ids)*> std::iter::FusedIterator for IntoKeys<$($generic_ids)*> {}
impl<K, V, S> $type<K, V, S> {
pub fn into_keys(self) -> IntoKeys<$($generic_ids)*> {
IntoKeys {
inner: self.inner.into_keys(),
}
}
}
}
}