use super::size_policy::*;
use super::traits::*;
use super::*;
pub use super::WeakWeakHashMap;
#[allow(clippy::exhaustive_enums)]
pub enum Entry<'a, K: 'a + WeakKey, V: 'a + WeakElement> {
Occupied(OccupiedEntry<'a, K, V>),
Vacant(VacantEntry<'a, K, V>),
}
pub struct OccupiedEntry<'a, K: 'a + WeakKey, V: 'a + WeakElement>(
inner::OccupiedEntry<'a, inner::WeakK<K>, inner::WeakV<V>>,
);
pub struct VacantEntry<'a, K: 'a + WeakKey, V: 'a + WeakElement>(
inner::VacantEntry<'a, inner::WeakK<K>, inner::WeakV<V>>,
);
#[derive(Clone, Debug)]
pub struct Iter<'a, K: 'a, V: 'a>(inner::Iter<'a, inner::WeakK<K>, inner::WeakV<V>>);
impl<'a, K: WeakElement, V: WeakElement> Iterator for Iter<'a, K, V> {
type Item = (K::Strong, V::Strong);
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
#[derive(Clone, Debug)]
pub struct Keys<'a, K: 'a, V: 'a>(Iter<'a, K, V>);
impl<'a, K: WeakElement, V: WeakElement> Iterator for Keys<'a, K, V> {
type Item = K::Strong;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
#[derive(Clone, Debug)]
pub struct Values<'a, K: 'a, V: 'a>(Iter<'a, K, V>);
impl<'a, K: WeakElement, V: WeakElement> Iterator for Values<'a, K, V> {
type Item = V::Strong;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(_, v)| v)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
#[derive(Debug)]
pub struct Drain<'a, K: 'a, V: 'a>(inner::Drain<'a, inner::WeakK<K>, inner::WeakV<V>>);
impl<'a, K: WeakElement, V: WeakElement> Iterator for Drain<'a, K, V> {
type Item = (K::Strong, V::Strong);
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
pub struct IntoIter<K, V>(inner::IntoIter<inner::WeakK<K>, inner::WeakV<V>>);
impl<K: WeakElement, V: WeakElement> Iterator for IntoIter<K, V> {
type Item = (K::Strong, V::Strong);
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl<K: WeakKey, V: WeakElement> WeakWeakHashMap<K, V, RandomState> {
pub fn new() -> Self {
Self::with_capacity(DEFAULT_INITIAL_CAPACITY)
}
pub fn with_capacity(capacity: usize) -> Self {
Self::with_capacity_and_hasher(capacity, Default::default())
}
}
impl<K: WeakKey, V: WeakElement, S: BuildHasher> WeakWeakHashMap<K, V, S> {
pub fn with_hasher(hash_builder: S) -> Self {
Self::with_capacity_and_hasher(DEFAULT_INITIAL_CAPACITY, hash_builder)
}
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
WeakWeakHashMap(inner::Table::new(capacity, hash_builder))
}
pub fn hasher(&self) -> &S {
self.0.hasher()
}
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn remove_expired(&mut self) {
self.retain(|_, _| true);
}
pub fn reserve(&mut self, additional_capacity: usize) {
self.0
.try_reserve(additional_capacity)
.expect("try_reserve failed");
}
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit();
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn load_factor(&self) -> f32 {
(self.len() as f32 + 1.0) / self.capacity() as f32
}
pub fn entry(&mut self, key: K::Strong) -> Entry<'_, K, V> {
match self.0.entry(key) {
inner::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry(occupied)),
inner::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry(vacant)),
}
}
pub fn clear(&mut self) {
self.0.clear();
}
pub fn get<Q>(&self, key: &Q) -> Option<V::Strong>
where
Q: ?Sized + Hash + Eq,
K::Key: Borrow<Q>,
{
Some(self.0.find(key)?.1)
}
pub fn get_key<Q>(&self, key: &Q) -> Option<K::Strong>
where
Q: ?Sized + Hash + Eq,
K::Key: Borrow<Q>,
{
Some(self.0.find(key)?.0)
}
pub fn get_both<Q>(&self, key: &Q) -> Option<(K::Strong, V::Strong)>
where
Q: ?Sized + Hash + Eq,
K::Key: Borrow<Q>,
{
self.0.find(key)
}
pub fn contains_key<Q>(&self, key: &Q) -> bool
where
Q: ?Sized + Hash + Eq,
K::Key: Borrow<Q>,
{
self.0.find(key).is_some()
}
pub fn insert(&mut self, key: K::Strong, value: V::Strong) -> Option<V::Strong> {
match self.entry(key) {
Entry::Occupied(mut occupied) => Some(occupied.insert(value)),
Entry::Vacant(vacant) => {
vacant.insert(value);
None
}
}
}
pub fn remove<Q>(&mut self, key: &Q) -> Option<V::Strong>
where
Q: ?Sized + Hash + Eq,
K::Key: Borrow<Q>,
{
self.0.find_entry(key).map(|occupied| occupied.remove().1)
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(K::Strong, V::Strong) -> bool,
{
self.0.table.retain(|(k, v)| {
if let (Some(k), Some(v)) = (k.val.view(), v.val.view()) {
f(k, v)
} else {
false
}
});
}
pub fn is_submap_with<F, S1, V1>(
&self,
other: &WeakWeakHashMap<K, V1, S1>,
mut value_equal: F,
) -> bool
where
V1: WeakElement,
F: FnMut(V::Strong, V1::Strong) -> bool,
S1: BuildHasher,
{
for (key, value1) in self {
if let Some(value2) = K::with_key(&key, |k| other.get(k)) {
if !value_equal(value1, value2) {
return false;
}
} else {
return false;
}
}
true
}
pub fn is_submap<V1, S1>(&self, other: &WeakWeakHashMap<K, V1, S1>) -> bool
where
V1: WeakElement,
V::Strong: PartialEq<V1::Strong>,
S1: BuildHasher,
{
self.is_submap_with(other, |v, v1| v == v1)
}
pub fn domain_is_subset<V1, S1>(&self, other: &WeakWeakHashMap<K, V1, S1>) -> bool
where
V1: WeakElement,
S1: BuildHasher,
{
self.is_submap_with(other, |_, _| true)
}
}
impl<K, V, V1, S, S1> PartialEq<WeakWeakHashMap<K, V1, S1>> for WeakWeakHashMap<K, V, S>
where
K: WeakKey,
V: WeakElement,
V1: WeakElement,
V::Strong: PartialEq<V1::Strong>,
S: BuildHasher,
S1: BuildHasher,
{
fn eq(&self, other: &WeakWeakHashMap<K, V1, S1>) -> bool {
self.is_submap(other) && other.domain_is_subset(self)
}
}
impl<K: WeakKey, V: WeakElement, S: BuildHasher> Eq for WeakWeakHashMap<K, V, S> where V::Strong: Eq {}
impl<K: WeakKey, V: WeakElement, S: BuildHasher + Default> Default for WeakWeakHashMap<K, V, S> {
fn default() -> Self {
WeakWeakHashMap::with_hasher(Default::default())
}
}
impl<K, V, S> iter::FromIterator<(K::Strong, V::Strong)> for WeakWeakHashMap<K, V, S>
where
K: WeakKey,
V: WeakElement,
S: BuildHasher + Default,
{
fn from_iter<T: IntoIterator<Item = (K::Strong, V::Strong)>>(iter: T) -> Self {
let iter = iter.into_iter();
let min_size = iter.size_hint().0;
let mut result = WeakWeakHashMap::with_capacity_and_hasher(min_size, Default::default());
result.extend(iter);
result
}
}
impl<K, V, S> Extend<(K::Strong, V::Strong)> for WeakWeakHashMap<K, V, S>
where
K: WeakKey,
V: WeakElement,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = (K::Strong, V::Strong)>>(&mut self, iter: T) {
let iter = iter.into_iter();
let min_size = iter.size_hint().0;
self.reserve(min_size);
for (key, value) in iter {
self.insert(key, value);
}
}
}
impl<'a, K: WeakKey, V: WeakElement> Entry<'a, K, V> {
pub fn or_insert(self, default: V::Strong) -> V::Strong {
self.or_insert_with(|| default)
}
pub fn or_insert_with<F: FnOnce() -> V::Strong>(self, default: F) -> V::Strong {
match self {
Entry::Occupied(occupied) => occupied.get_strong(),
Entry::Vacant(vacant) => vacant.insert(default()),
}
}
pub fn key(&self) -> &K::Strong {
match *self {
Entry::Occupied(ref occupied) => occupied.key(),
Entry::Vacant(ref vacant) => vacant.key(),
}
}
}
impl<'a, K: WeakKey, V: WeakElement> OccupiedEntry<'a, K, V> {
pub fn key(&self) -> &K::Strong {
self.0.get().0
}
pub fn remove_entry(self) -> (K::Strong, V::Strong) {
self.0.remove()
}
pub fn get(&self) -> &V::Strong {
self.0.get().1
}
pub fn get_strong(&self) -> V::Strong {
V::clone(self.get())
}
pub fn insert(&mut self, value: V::Strong) -> V::Strong {
self.0.insert(value)
}
pub fn remove(self) -> V::Strong {
self.remove_entry().1
}
}
impl<'a, K: WeakKey, V: WeakElement> VacantEntry<'a, K, V> {
pub fn key(&self) -> &K::Strong {
self.0.key()
}
pub fn into_key(self) -> K::Strong {
self.0.into_key()
}
pub fn insert(self, value: V::Strong) -> V::Strong {
V::clone(self.0.insert(value).get().1)
}
}
impl<K: WeakElement, V: WeakElement, S> Debug for WeakWeakHashMap<K, V, S>
where
K::Strong: Debug,
V::Strong: Debug,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<'a, K: WeakKey, V: WeakElement> Debug for Entry<'a, K, V>
where
K::Strong: Debug,
V::Strong: Debug,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match *self {
Entry::Occupied(ref e) => e.fmt(f),
Entry::Vacant(ref e) => e.fmt(f),
}
}
}
impl<'a, K: WeakKey, V: WeakElement> Debug for OccupiedEntry<'a, K, V>
where
K::Strong: Debug,
V::Strong: Debug,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl<'a, K: WeakKey, V: WeakElement> Debug for VacantEntry<'a, K, V>
where
K::Strong: Debug,
V::Strong: Debug,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl<K: WeakElement, V: WeakElement, S> IntoIterator for WeakWeakHashMap<K, V, S> {
type Item = (K::Strong, V::Strong);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
IntoIter(self.0.into_iter())
}
}
impl<'a, K: WeakElement, V: WeakElement, S> IntoIterator for &'a WeakWeakHashMap<K, V, S> {
type Item = (K::Strong, V::Strong);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
Iter(self.0.iter())
}
}
impl<K: WeakElement, V: WeakElement, S> WeakWeakHashMap<K, V, S> {
pub fn iter(&self) -> Iter<'_, K, V> {
self.into_iter()
}
pub fn keys(&self) -> Keys<'_, K, V> {
Keys(self.iter())
}
pub fn values(&self) -> Values<'_, K, V> {
Values(self.iter())
}
pub fn drain(&mut self) -> Drain<'_, K, V> {
Drain(self.0.drain())
}
}