Skip to main content

weak_table/
weak_weak_hash_map.rs

1//! A hash map where the keys and values are both held by weak pointers, and keys are compared by
2//! value.
3
4use super::traits::*;
5use super::*;
6use crate::common::*;
7
8pub use super::WeakWeakHashMap;
9
10/// Represents an entry in the table which may be occupied or vacant.
11#[allow(clippy::exhaustive_enums)]
12pub enum Entry<'a, K: 'a + WeakKey, V: 'a + WeakElement> {
13    /// An occupied entry.
14    Occupied(OccupiedEntry<'a, K, V>),
15    /// A vacant entry.
16    Vacant(VacantEntry<'a, K, V>),
17}
18
19/// An occupied entry, which can be removed, modified, or viewed.
20pub struct OccupiedEntry<'a, K: 'a + WeakKey, V: 'a + WeakElement>(
21    inner::OccupiedEntry<'a, inner::WeakK<K>, inner::WeakV<V>>,
22);
23
24/// A vacant entry, which can be inserted in or viewed.
25pub struct VacantEntry<'a, K: 'a + WeakKey, V: 'a + WeakElement>(
26    inner::VacantEntry<'a, inner::WeakK<K>, inner::WeakV<V>>,
27);
28
29/// An iterator over the keys and values of the weak hash map.
30#[derive(Clone, Debug)]
31pub struct Iter<'a, K: 'a, V: 'a>(inner::Iter<'a, inner::WeakK<K>, inner::WeakV<V>>);
32
33impl<'a, K: WeakElement, V: WeakElement> Iterator for Iter<'a, K, V> {
34    type Item = (K::Strong, V::Strong);
35
36    fn next(&mut self) -> Option<Self::Item> {
37        self.0.next()
38    }
39
40    fn size_hint(&self) -> (usize, Option<usize>) {
41        self.0.size_hint()
42    }
43}
44
45/// An iterator over the keys of the weak hash map.
46#[derive(Clone, Debug)]
47pub struct Keys<'a, K: 'a, V: 'a>(Iter<'a, K, V>);
48
49impl<'a, K: WeakElement, V: WeakElement> Iterator for Keys<'a, K, V> {
50    type Item = K::Strong;
51
52    fn next(&mut self) -> Option<Self::Item> {
53        self.0.next().map(|(k, _)| k)
54    }
55
56    fn size_hint(&self) -> (usize, Option<usize>) {
57        self.0.size_hint()
58    }
59}
60
61/// An iterator over the values of the weak hash map.
62#[derive(Clone, Debug)]
63pub struct Values<'a, K: 'a, V: 'a>(Iter<'a, K, V>);
64
65impl<'a, K: WeakElement, V: WeakElement> Iterator for Values<'a, K, V> {
66    type Item = V::Strong;
67
68    fn next(&mut self) -> Option<Self::Item> {
69        self.0.next().map(|(_, v)| v)
70    }
71
72    fn size_hint(&self) -> (usize, Option<usize>) {
73        self.0.size_hint()
74    }
75}
76
77#[derive(Debug)]
78/// An iterator that consumes the values of a weak hash map, leaving it empty.
79///
80/// Once this iterator is dropped, all values are removed from the map,
81/// whether the iterator itself was drained or not.
82pub struct Drain<'a, K: 'a, V: 'a>(inner::Drain<'a, inner::WeakK<K>, inner::WeakV<V>>);
83
84impl<'a, K: WeakElement, V: WeakElement> Iterator for Drain<'a, K, V> {
85    type Item = (K::Strong, V::Strong);
86
87    fn next(&mut self) -> Option<Self::Item> {
88        self.0.next()
89    }
90
91    fn size_hint(&self) -> (usize, Option<usize>) {
92        self.0.size_hint()
93    }
94}
95
96/// An iterator that consumes a weak hash map, leaving it empty.
97pub struct IntoIter<K, V>(inner::IntoIter<inner::WeakK<K>, inner::WeakV<V>>);
98
99impl<K: WeakElement, V: WeakElement> Iterator for IntoIter<K, V> {
100    type Item = (K::Strong, V::Strong);
101
102    fn next(&mut self) -> Option<Self::Item> {
103        self.0.next()
104    }
105
106    fn size_hint(&self) -> (usize, Option<usize>) {
107        self.0.size_hint()
108    }
109}
110
111into_kv_types!(K::Strong, V::Strong where {K: WeakElement, V:WeakElement});
112universal_hashless_members! {
113    WeakWeakHashMap ("`WeakWeakHashMap", a "map") inner::Table::new {K,V}
114}
115
116impl<K: WeakKey, V: WeakElement, S: BuildHasher> WeakWeakHashMap<K, V, S> {
117    universal_key_independent_members! {"mappings"}
118
119    /// Gets the requested entry.
120    ///
121    /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is
122    /// `self.capacity()` and *q* is the length of the probe sequences
123    /// in `other`)
124    pub fn entry(&mut self, key: K::Strong) -> Entry<'_, K, V> {
125        match self.0.entry(key) {
126            inner::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry(occupied)),
127            inner::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry(vacant)),
128        }
129    }
130
131    /// Returns a reference to the value corresponding to the key.
132    ///
133    /// Returns `None` if no matching key is found.
134    ///
135    /// expected *O*(1) time; worst-case *O*(*p*) time
136    pub fn get<Q>(&self, key: &Q) -> Option<V::Strong>
137    where
138        Q: ?Sized + Hash + Eq,
139        K::Key: Borrow<Q>,
140    {
141        Some(self.0.find(key)?.1)
142    }
143
144    /// Returns the strong reference to the key, if present.
145    ///
146    /// expected *O*(1) time; worst-case *O*(*p*) time
147    pub fn get_key<Q>(&self, key: &Q) -> Option<K::Strong>
148    where
149        Q: ?Sized + Hash + Eq,
150        K::Key: Borrow<Q>,
151    {
152        Some(self.0.find(key)?.0)
153    }
154
155    /// Returns strong references to both the key and the value, if present.
156    ///
157    /// expected *O*(1) time; worst-case *O*(*p*) time
158    pub fn get_both<Q>(&self, key: &Q) -> Option<(K::Strong, V::Strong)>
159    where
160        Q: ?Sized + Hash + Eq,
161        K::Key: Borrow<Q>,
162    {
163        self.0.find(key)
164    }
165
166    /// Returns true if the map contains the specified key.
167    ///
168    /// expected *O*(1) time; worst-case *O*(*p*) time
169    pub fn contains_key<Q>(&self, key: &Q) -> bool
170    where
171        Q: ?Sized + Hash + Eq,
172        K::Key: Borrow<Q>,
173    {
174        self.0.find(key).is_some()
175    }
176
177    /// Unconditionally inserts the value, returning the old value if already present.
178    ///
179    /// Unlike `std::collections::HashMap`, this replaces the key even if occupied.
180    ///
181    /// expected *O*(1) time; worst-case *O*(*p*) time
182    pub fn insert(&mut self, key: K::Strong, value: V::Strong) -> Option<V::Strong> {
183        match self.entry(key) {
184            Entry::Occupied(mut occupied) => Some(occupied.insert(value)),
185            Entry::Vacant(vacant) => {
186                vacant.insert(value);
187                None
188            }
189        }
190    }
191
192    /// Removes the entry with the given key, if it exists, and returns the value.
193    ///
194    /// expected *O*(1) time; worst-case *O*(*p*) time
195    pub fn remove<Q>(&mut self, key: &Q) -> Option<V::Strong>
196    where
197        Q: ?Sized + Hash + Eq,
198        K::Key: Borrow<Q>,
199    {
200        self.0.find_entry(key).map(|occupied| occupied.remove().1)
201    }
202
203    /// Removes the entry with the given key, if it exists, and returns both the
204    /// key and value.
205    ///
206    /// expected *O*(1) time; worst-case *O*(*p*) time
207    pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K::Strong, V::Strong)>
208    where
209        Q: ?Sized + Hash + Eq,
210        K::Key: Borrow<Q>,
211    {
212        Some(self.0.find_entry(key)?.remove())
213    }
214
215    /// Removes all mappings not satisfying the given predicate.
216    ///
217    /// Also removes any expired mappings.
218    ///
219    /// *O*(*n*) time
220    pub fn retain<F>(&mut self, mut f: F)
221    where
222        F: FnMut(K::Strong, V::Strong) -> bool,
223    {
224        // TODO: It would be better to use a retain method on Table, but I've
225        // run into lifetime issues there. See "TODO retain" in inner/table.rs
226        self.0.table.retain(|(k, v)| {
227            if let (Some(k), Some(v)) = (k.val.view(), v.val.view()) {
228                f(k, v)
229            } else {
230                false
231            }
232        });
233    }
234
235    /// Is this map a submap of the other, using the given value comparison.
236    ///
237    /// In particular, all the keys of `self` must be in `other` and the values must compare
238    /// `true` with `value_equal`.
239    ///
240    /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is
241    /// `self.capacity()` and *q* is the length of the probe sequences
242    /// in `other`)
243    pub fn is_submap_with<F, S1, V1>(
244        &self,
245        other: &WeakWeakHashMap<K, V1, S1>,
246        mut value_equal: F,
247    ) -> bool
248    where
249        V1: WeakElement,
250        F: FnMut(V::Strong, V1::Strong) -> bool,
251        S1: BuildHasher,
252    {
253        for (key, value1) in self {
254            if let Some(value2) = K::with_key(&key, |k| other.get(k)) {
255                if !value_equal(value1, value2) {
256                    return false;
257                }
258            } else {
259                return false;
260            }
261        }
262
263        true
264    }
265
266    /// Is `self` a submap of `other`?
267    ///
268    /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is
269    /// `self.capacity()` and *q* is the length of the probe sequences
270    /// in `other`)
271    pub fn is_submap<V1, S1>(&self, other: &WeakWeakHashMap<K, V1, S1>) -> bool
272    where
273        V1: WeakElement,
274        V::Strong: PartialEq<V1::Strong>,
275        S1: BuildHasher,
276    {
277        self.is_submap_with(other, |v, v1| v == v1)
278    }
279
280    /// Are the keys of `self` a subset of the keys of `other`?
281    ///
282    /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is
283    /// `self.capacity()` and *q* is the length of the probe sequences
284    /// in `other`)
285    pub fn domain_is_subset<V1, S1>(&self, other: &WeakWeakHashMap<K, V1, S1>) -> bool
286    where
287        V1: WeakElement,
288        S1: BuildHasher,
289    {
290        self.is_submap_with(other, |_, _| true)
291    }
292}
293
294impl<K, V, V1, S, S1> PartialEq<WeakWeakHashMap<K, V1, S1>> for WeakWeakHashMap<K, V, S>
295where
296    K: WeakKey,
297    V: WeakElement,
298    V1: WeakElement,
299    V::Strong: PartialEq<V1::Strong>,
300    S: BuildHasher,
301    S1: BuildHasher,
302{
303    fn eq(&self, other: &WeakWeakHashMap<K, V1, S1>) -> bool {
304        self.is_submap(other) && other.domain_is_subset(self)
305    }
306}
307
308impl<K: WeakKey, V: WeakElement, S: BuildHasher> Eq for WeakWeakHashMap<K, V, S> where V::Strong: Eq {}
309
310impl<K, V, S> iter::FromIterator<(K::Strong, V::Strong)> for WeakWeakHashMap<K, V, S>
311where
312    K: WeakKey,
313    V: WeakElement,
314    S: BuildHasher + Default,
315{
316    fn from_iter<T: IntoIterator<Item = (K::Strong, V::Strong)>>(iter: T) -> Self {
317        let iter = iter.into_iter();
318        let min_size = iter.size_hint().0;
319        let mut result = WeakWeakHashMap::with_capacity_and_hasher(min_size, Default::default());
320        result.extend(iter);
321        result
322    }
323}
324
325impl<K: WeakKey, V: WeakElement, const N: usize> From<[(K::Strong, V::Strong); N]>
326    for WeakWeakHashMap<K, V, RandomState>
327{
328    /// Converts an array of key-value pairs into a map.
329    ///
330    /// If any entries in the array have equal keys,
331    /// all but one of the corresponding values will be dropped.
332    fn from(value: [(K::Strong, V::Strong); N]) -> Self {
333        Self::from_iter(value)
334    }
335}
336
337impl<K, V, S> Extend<(K::Strong, V::Strong)> for WeakWeakHashMap<K, V, S>
338where
339    K: WeakKey,
340    V: WeakElement,
341    S: BuildHasher,
342{
343    fn extend<T: IntoIterator<Item = (K::Strong, V::Strong)>>(&mut self, iter: T) {
344        let iter = iter.into_iter();
345        let min_size = iter.size_hint().0;
346        self.reserve(min_size);
347        for (key, value) in iter {
348            self.insert(key, value);
349        }
350    }
351}
352
353impl<'a, K: WeakKey, V: WeakElement> Entry<'a, K, V> {
354    /// Ensures a value is in the entry by inserting a default value
355    /// if empty, and returns a mutable reference to the value in the
356    /// entry.
357    ///
358    /// *O*(1) time
359    pub fn or_insert(self, default: V::Strong) -> V::Strong {
360        self.or_insert_with(|| default)
361    }
362
363    /// Ensures a value is in the entry by inserting the result of the
364    /// `default` function if empty, and returns a strong reference to
365    /// the value in the entry.
366    ///
367    /// *O*(1) time
368    pub fn or_insert_with<F: FnOnce() -> V::Strong>(self, default: F) -> V::Strong {
369        match self {
370            Entry::Occupied(occupied) => occupied.get_strong(),
371            Entry::Vacant(vacant) => vacant.insert(default()),
372        }
373    }
374
375    /// Ensures that a value is in the entry by inserting the result of calling the
376    /// `default` function on this entry's key if the function is empty, and
377    /// returns a strong reference to the value in the entry.
378    pub fn or_insert_with_key<F>(self, default: F) -> V::Strong
379    where
380        F: FnOnce(&K::Strong) -> V::Strong,
381    {
382        match self {
383            Entry::Occupied(occupied) => occupied.get_strong(),
384            Entry::Vacant(vacant) => {
385                let value = default(vacant.key());
386                vacant.insert(value)
387            }
388        }
389    }
390
391    /// Returns a reference to this entry's key.
392    ///
393    /// *O*(1) time
394    pub fn key(&self) -> &K::Strong {
395        match *self {
396            Entry::Occupied(ref occupied) => occupied.key(),
397            Entry::Vacant(ref vacant) => vacant.key(),
398        }
399    }
400
401    /// Inserts a value into this entry, and returns an [`OccupiedEntry`].
402    ///
403    /// *O*(1) time
404    pub fn insert_entry(self, value: V::Strong) -> OccupiedEntry<'a, K, V> {
405        match self {
406            Entry::Occupied(mut occupied) => {
407                occupied.insert(value);
408                occupied
409            }
410            Entry::Vacant(vacant) => vacant.insert_entry(value),
411        }
412    }
413}
414
415impl<'a, K: WeakKey, V: WeakElement> OccupiedEntry<'a, K, V> {
416    /// Gets a reference to the key held by the entry.
417    ///
418    /// *O*(1) time
419    pub fn key(&self) -> &K::Strong {
420        self.0.get().0
421    }
422
423    /// Takes ownership of the key and value, removing them from the map.
424    ///
425    /// expected *O*(1) time; worst-case *O*(*p*) time
426    pub fn remove_entry(self) -> (K::Strong, V::Strong) {
427        self.0.remove()
428    }
429
430    /// Gets a reference to the value in the entry.
431    ///
432    /// *O*(1) time
433    pub fn get(&self) -> &V::Strong {
434        self.0.get().1
435    }
436
437    /// Gets a clone of the reference to the value in the entry.
438    ///
439    /// *O*(1) time
440    pub fn get_strong(&self) -> V::Strong {
441        V::clone(self.get())
442    }
443
444    /// Replaces the value in the entry with the given value.
445    ///
446    /// Returns the previous value.
447    ///
448    /// *O*(1) time
449    pub fn insert(&mut self, value: V::Strong) -> V::Strong {
450        self.0.insert(value)
451    }
452
453    /// Removes the entry, returning the value.
454    ///
455    /// expected *O*(1) time; worst-case *O*(*p*) time
456    pub fn remove(self) -> V::Strong {
457        self.remove_entry().1
458    }
459}
460
461impl<'a, K: WeakKey, V: WeakElement> VacantEntry<'a, K, V> {
462    /// Gets a reference to the key that would be used when inserting a
463    /// value through the `VacantEntry`.
464    ///
465    /// *O*(1) time
466    pub fn key(&self) -> &K::Strong {
467        self.0.key()
468    }
469
470    /// Returns an owned reference to the key.
471    ///
472    /// *O*(1) time
473    pub fn into_key(self) -> K::Strong {
474        self.0.into_key()
475    }
476
477    /// Inserts the key and value into the map, returning the same value.
478    ///
479    /// *O*(1) time
480    pub fn insert(self, value: V::Strong) -> V::Strong {
481        V::clone(self.0.insert(value).get().1)
482    }
483
484    /// Inserts the key and value into the map, returning an `OccupiedEntry`.
485    ///
486    /// *O*(1) time
487    pub fn insert_entry(self, value: V::Strong) -> OccupiedEntry<'a, K, V> {
488        OccupiedEntry(self.0.insert(value))
489    }
490}
491
492impl<K: WeakElement, V: WeakElement, S> Debug for WeakWeakHashMap<K, V, S>
493where
494    K::Strong: Debug,
495    V::Strong: Debug,
496{
497    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
498        f.debug_map().entries(self.iter()).finish()
499    }
500}
501
502debug_for_entry! {where {
503    K: WeakKey,
504    K::Strong: Debug,
505    V: WeakElement,
506    V::Strong: Debug
507}}
508
509impl<K: WeakElement, V: WeakElement, S> IntoIterator for WeakWeakHashMap<K, V, S> {
510    type Item = (K::Strong, V::Strong);
511    type IntoIter = IntoIter<K, V>;
512
513    /// Creates an owning iterator from `self`.
514    ///
515    /// *O*(1) time (and *O*(*n*) time to dispose of the result)
516    fn into_iter(self) -> Self::IntoIter {
517        IntoIter(self.0.into_iter())
518    }
519}
520
521impl<'a, K: WeakElement, V: WeakElement, S> IntoIterator for &'a WeakWeakHashMap<K, V, S> {
522    type Item = (K::Strong, V::Strong);
523    type IntoIter = Iter<'a, K, V>;
524
525    /// Creates a borrowing iterator from `self`.
526    ///
527    /// *O*(1) time
528    fn into_iter(self) -> Self::IntoIter {
529        Iter(self.0.iter())
530    }
531}
532
533impl<K: WeakElement, V: WeakElement, S> WeakWeakHashMap<K, V, S> {
534    /// Gets an iterator over the keys and values.
535    ///
536    /// *O*(1) time
537    pub fn iter(&self) -> Iter<'_, K, V> {
538        self.into_iter()
539    }
540
541    /// Gets an iterator over the keys.
542    ///
543    /// *O*(1) time
544    pub fn keys(&self) -> Keys<'_, K, V> {
545        Keys(self.iter())
546    }
547
548    /// Gets an iterator over the values.
549    ///
550    /// *O*(1) time
551    pub fn values(&self) -> Values<'_, K, V> {
552        Values(self.iter())
553    }
554
555    /// Gets a draining iterator, which removes all the values but retains the storage.
556    ///
557    /// *O*(1) time (and *O*(*n*) time to dispose of the result)
558    pub fn drain(&mut self) -> Drain<'_, K, V> {
559        Drain(self.0.drain())
560    }
561
562    into_kv_methods! {}
563
564    /// Gets an iterator that removes and returns elements matching a given predicate.
565    ///
566    /// Expired elements are also removed.
567    ///
568    /// If this iterator is dropped before it is completed, then no further
569    /// elements are removed.
570    /// (This is in contrast to the behavior of [`drain`](Self::drain)).
571    ///
572    /// *O*(1) time
573    pub fn extract_if<'a, F>(&'a mut self, mut f: F) -> ExtractIf<'a, K, V, F>
574    where
575        F: FnMut(K::Strong, V::Strong) -> bool + 'a,
576    {
577        ExtractIf {
578            inner: self.0.extract_if(move |e| {
579                if let (Some(k), Some(v)) = (e.0.val.view(), e.1.val.view()) {
580                    f(k, v)
581                } else {
582                    true
583                }
584            }),
585            _phantom: PhantomData,
586        }
587    }
588}
589
590/// An iterator that removes members that match a given predicate.
591pub struct ExtractIf<'a, K: WeakElement, V: WeakElement, F> {
592    /// The underlying iterator.
593    inner: inner::ExtractIf<'a, inner::WeakK<K>, inner::WeakV<V>>,
594    /// A marker so that F does not appear unused.
595    _phantom: PhantomData<F>,
596}
597
598impl<'a, K: WeakElement, V: WeakElement, F> Iterator for ExtractIf<'a, K, V, F> {
599    type Item = (K::Strong, V::Strong);
600
601    fn next(&mut self) -> Option<Self::Item> {
602        self.inner.next()
603    }
604    fn size_hint(&self) -> (usize, Option<usize>) {
605        self.inner.size_hint()
606    }
607}
608
609#[cfg(test)]
610mod test {
611    use super::WeakWeakHashMap;
612    use crate::{
613        compat::{
614            format,
615            rc::{Rc, Weak},
616            Vec,
617        },
618        tests::util::VecDebugAsMap,
619    };
620
621    crate::tests::common::empty_constructor_tests! {WeakWeakHashMap<Weak<u32>, Weak<u32>>}
622
623    #[test]
624    fn debug_map() {
625        let rcs: Vec<Rc<u32>> = (0..20).map(Rc::new).collect();
626        let map: WeakWeakHashMap<Weak<u32>, Weak<u32>> =
627            rcs.iter().map(|n| (n.clone(), n.clone())).collect();
628        let vec: VecDebugAsMap<_, _> = map.iter().collect();
629        assert_eq!(format!("{map:?}"), format!("{vec:?}"));
630    }
631
632    #[test]
633    fn is_submap() {
634        let mut rcs: Vec<Rc<u32>> = (0..50).map(Rc::new).collect();
635        let weakmap: WeakWeakHashMap<Weak<u32>, Weak<u32>> = rcs
636            .iter()
637            .take(25)
638            .map(|n| (n.clone(), n.clone()))
639            .collect();
640        let mut weakmap2 = weakmap.clone();
641
642        assert!(weakmap.is_submap(&weakmap2));
643        assert!(weakmap2.is_submap(&weakmap));
644
645        weakmap2.extend(rcs.iter().skip(25).map(|n| (n.clone(), n.clone())));
646        assert!(weakmap.is_submap(&weakmap2));
647        assert!(!weakmap2.is_submap(&weakmap));
648
649        weakmap2.insert(rcs[0].clone(), rcs[12].clone());
650        assert!(!weakmap.is_submap(&weakmap2));
651        assert!(!weakmap2.is_submap(&weakmap));
652
653        let _ = rcs.remove(0);
654        assert!(weakmap.is_submap(&weakmap2));
655    }
656
657    #[test]
658    fn entry_methods() {
659        let rcs: Vec<Rc<u32>> = (0..5).map(Rc::new).collect();
660        let mut weakmap: WeakWeakHashMap<Weak<u32>, Weak<u32>> =
661            rcs.iter().map(|n| (n.clone(), n.clone())).collect();
662
663        let seven = Rc::new(7);
664        let fourteen = Rc::new(14);
665        let ptr = weakmap.entry(seven.clone()).or_insert(fourteen.clone());
666        assert_eq!(*ptr, 14);
667
668        let twelve = Rc::new(12);
669        let e = weakmap.entry(twelve.clone());
670        if let super::Entry::Vacant(v) = e {
671            let t2 = v.into_key();
672            assert_eq!(*t2, 12);
673        } else {
674            panic!();
675        }
676        assert!(!weakmap.contains_key(&12));
677    }
678
679    #[test]
680    fn or_insert_with() {
681        let rcs: Vec<Rc<u32>> = (0..5).map(Rc::new).collect();
682        let mut weakmap: WeakWeakHashMap<Weak<u32>, Weak<u32>> =
683            rcs.iter().map(|n| (n.clone(), n.clone())).collect();
684        let seven = Rc::new(7);
685        let eight = Rc::new(8);
686        let fourteen = Rc::new(14);
687        let sixteen = Rc::new(16);
688
689        // Absent key case:
690        let ptr: Rc<u32> = weakmap
691            .entry(seven.clone())
692            .or_insert_with(|| fourteen.clone());
693        assert_eq!(*ptr, 14);
694        let ptr: Rc<u32> = weakmap.entry(eight.clone()).or_insert_with_key(|k| {
695            assert_eq!(**k, 8);
696            sixteen.clone()
697        });
698        assert_eq!(*ptr, 16);
699
700        // Present key case:
701        let one = Rc::new(1);
702        let ptr: Rc<u32> = weakmap
703            .entry(one.clone())
704            .or_insert_with(|| fourteen.clone());
705
706        assert_eq!(*ptr, 1);
707        let ptr: Rc<u32> = weakmap.entry(one.clone()).or_insert_with_key(|k| {
708            assert_eq!(**k, 8);
709            sixteen.clone()
710        });
711        assert_eq!(*ptr, 1);
712    }
713
714    #[test]
715    fn entry_insert_entry() {
716        let rcs: Vec<Rc<u32>> = (0..5).map(Rc::new).collect();
717        let mut weakmap: WeakWeakHashMap<Weak<u32>, Weak<u32>> =
718            rcs.iter().map(|n| (n.clone(), n.clone())).collect();
719
720        let one = Rc::new(1);
721        let ten = Rc::new(10);
722        let n1001 = Rc::new(1001);
723        let n1010 = Rc::new(1010);
724
725        let e1: super::OccupiedEntry<'_, Weak<u32>, Weak<u32>> =
726            weakmap.entry(one.clone()).insert_entry(n1001.clone());
727        assert_eq!(e1.key(), &one);
728        assert_eq!(e1.get(), &n1001);
729
730        let e2: super::OccupiedEntry<'_, Weak<u32>, Weak<u32>> =
731            weakmap.entry(ten.clone()).insert_entry(n1010.clone());
732        assert_eq!(e2.key(), &ten);
733        assert_eq!(e2.get(), &n1010);
734
735        assert_eq!(weakmap.get(&1), Some(n1001));
736        assert_eq!(weakmap.get(&10), Some(n1010));
737    }
738
739    #[test]
740    fn vacant_insert_entry() {
741        let mut weakmap: WeakWeakHashMap<Weak<u32>, Weak<u32>> = Default::default();
742        let five = Rc::new(5);
743        let n500 = Rc::new(500);
744
745        let super::Entry::Vacant(e) = weakmap.entry(five.clone()) else {
746            panic!("Not vacant");
747        };
748        let e: super::OccupiedEntry<'_, Weak<u32>, Weak<u32>> = e.insert_entry(n500.clone());
749        assert_eq!(e.get(), &n500);
750    }
751}