1use crate::common::*;
5use crate::compat::*;
6
7use super::by_ptr::*;
8use super::traits::*;
9use super::weak_weak_hash_map as base;
10
11pub use super::weak_weak_hash_map::{
12 Drain, Entry, ExtractIf, IntoIter, IntoKeys, IntoValues, Iter, Keys, Values,
13};
14pub use super::PtrWeakWeakHashMap;
15
16universal_hashless_members! {
17 PtrWeakWeakHashMap
18 ("`PtrWeakWeakHashMap", a "map")
19 crate::WeakWeakHashMap::with_capacity_and_hasher
20 {K, V}
21}
22
23impl<K: WeakElement, V: WeakElement, S: BuildHasher> PtrWeakWeakHashMap<K, V, S>
24where
25 K::Strong: Deref,
26{
27 universal_key_independent_members! {"mappings"}
28
29 pub fn entry(&mut self, key: K::Strong) -> Entry<'_, ByPtr<K>, V> {
33 self.0.entry(key)
34 }
35
36 pub fn get(&self, key: &K::Strong) -> Option<V::Strong> {
42 self.0.get(&(key.deref() as *const _))
43 }
44
45 pub fn contains_key(&self, key: &K::Strong) -> bool {
49 self.0.contains_key(&(key.deref() as *const _))
50 }
51
52 pub fn insert(&mut self, key: K::Strong, value: V::Strong) -> Option<V::Strong> {
57 self.0.insert(key, value)
58 }
59
60 pub fn remove(&mut self, key: &K::Strong) -> Option<V::Strong> {
64 self.0.remove(&(key.deref() as *const _))
65 }
66
67 pub fn retain<F>(&mut self, f: F)
73 where
74 F: FnMut(K::Strong, V::Strong) -> bool,
75 {
76 self.0.retain(f);
77 }
78
79 pub fn submap_with<F, S1, V1>(
88 &self,
89 other: &PtrWeakWeakHashMap<K, V1, S1>,
90 value_equal: F,
91 ) -> bool
92 where
93 F: FnMut(V::Strong, V1::Strong) -> bool,
94 V1: WeakElement,
95 S1: BuildHasher,
96 {
97 self.0.is_submap_with(&other.0, value_equal)
98 }
99
100 pub fn is_submap<V1, S1>(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool
106 where
107 V1: WeakElement,
108 V::Strong: PartialEq<V1::Strong>,
109 S1: BuildHasher,
110 {
111 self.0.is_submap(&other.0)
112 }
113
114 pub fn domain_is_subset<V1, S1>(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool
120 where
121 V1: WeakElement,
122 S1: BuildHasher,
123 {
124 self.0.domain_is_subset(&other.0)
125 }
126}
127
128impl<K: WeakElement, V: WeakElement, S> PtrWeakWeakHashMap<K, V, S>
129where
130 K::Strong: Deref,
131{
132 pub fn iter(&self) -> Iter<'_, ByPtr<K>, V> {
136 self.0.iter()
137 }
138
139 pub fn keys(&self) -> Keys<'_, ByPtr<K>, V> {
143 self.0.keys()
144 }
145
146 pub fn values(&self) -> Values<'_, ByPtr<K>, V> {
150 self.0.values()
151 }
152
153 pub fn drain(&mut self) -> Drain<'_, ByPtr<K>, V> {
157 self.0.drain()
158 }
159
160 ptr_into_kv_methods! {}
161
162 pub fn extract_if<'a, F>(&'a mut self, f: F) -> ExtractIf<'a, ByPtr<K>, V, F>
172 where
173 F: FnMut(K::Strong, V::Strong) -> bool + 'a,
174 {
175 self.0.extract_if(f)
176 }
177}
178
179impl<K, V, V1, S, S1> PartialEq<PtrWeakWeakHashMap<K, V1, S1>> for PtrWeakWeakHashMap<K, V, S>
180where
181 K: WeakElement,
182 K::Strong: Deref,
183 V: WeakElement,
184 V1: WeakElement,
185 V::Strong: PartialEq<V1::Strong>,
186 S: BuildHasher,
187 S1: BuildHasher,
188{
189 fn eq(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool {
190 self.0 == other.0
191 }
192}
193
194impl<K: WeakElement, V: WeakElement, S: BuildHasher> Eq for PtrWeakWeakHashMap<K, V, S>
195where
196 K::Strong: Deref,
197 V::Strong: Eq,
198{
199}
200
201impl<K, V, S> FromIterator<(K::Strong, V::Strong)> for PtrWeakWeakHashMap<K, V, S>
202where
203 K: WeakElement,
204 K::Strong: Deref,
205 V: WeakElement,
206 S: BuildHasher + Default,
207{
208 fn from_iter<T: IntoIterator<Item = (K::Strong, V::Strong)>>(iter: T) -> Self {
209 PtrWeakWeakHashMap(base::WeakWeakHashMap::<ByPtr<K>, V, S>::from_iter(iter))
210 }
211}
212
213#[cfg(any(test, feature = "std", feature = "ahash"))]
214impl<K, V, const N: usize> From<[(K::Strong, V::Strong); N]>
215 for PtrWeakWeakHashMap<K, V, RandomState>
216where
217 K: WeakElement,
218 K::Strong: Deref,
219 V: WeakElement,
220{
221 fn from(value: [(K::Strong, V::Strong); N]) -> Self {
226 Self::from_iter(value)
227 }
228}
229
230impl<K, V, S> Extend<(K::Strong, V::Strong)> for PtrWeakWeakHashMap<K, V, S>
231where
232 K: WeakElement,
233 K::Strong: Deref,
234 V: WeakElement,
235 S: BuildHasher,
236{
237 fn extend<T: IntoIterator<Item = (K::Strong, V::Strong)>>(&mut self, iter: T) {
238 self.0.extend(iter);
239 }
240}
241
242impl<K, V, S> Debug for PtrWeakWeakHashMap<K, V, S>
243where
244 K: WeakElement,
245 K::Strong: Debug,
246 V: WeakElement,
247 V::Strong: Debug,
248{
249 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
250 self.0.fmt(f)
251 }
252}
253
254impl<K: WeakElement, V: WeakElement, S> IntoIterator for PtrWeakWeakHashMap<K, V, S> {
255 type Item = (K::Strong, V::Strong);
256 type IntoIter = IntoIter<ByPtr<K>, V>;
257
258 fn into_iter(self) -> Self::IntoIter {
262 self.0.into_iter()
263 }
264}
265
266impl<'a, K: WeakElement, V: WeakElement, S> IntoIterator for &'a PtrWeakWeakHashMap<K, V, S> {
267 type Item = (K::Strong, V::Strong);
268 type IntoIter = Iter<'a, ByPtr<K>, V>;
269
270 fn into_iter(self) -> Self::IntoIter {
274 (&self.0).into_iter()
275 }
276}
277
278#[cfg(test)]
279mod test {
280 #![allow(clippy::print_stderr)]
281 #![cfg_attr(feature = "ahash", allow(deprecated))]
283
284 use super::{Entry, PtrWeakWeakHashMap};
285 use crate::{
286 compat::{
287 eprintln, format,
288 rc::{Rc, Weak},
289 Vec,
290 },
291 tests::util::VecDebugAsMap,
292 };
293
294 crate::tests::common::empty_constructor_tests! {PtrWeakWeakHashMap<Weak<u32>, Weak<u32>>}
295
296 #[test]
305 fn insert_and_check() {
306 let mut rcs: Vec<(Rc<u32>, Rc<f32>)> = Vec::new();
307
308 for i in 0..200 {
309 rcs.push((Rc::new(i), Rc::new(i as f32 + 0.1)));
310 }
311
312 let mut weakmap: PtrWeakWeakHashMap<Weak<u32>, Weak<f32>> = PtrWeakWeakHashMap::new();
313
314 for (key, value) in rcs.iter().cloned() {
315 weakmap.insert(key, value);
316 }
318
319 let mut count = 0;
320
321 for (key, value) in &rcs {
322 assert!(weakmap.contains_key(key));
323
324 match weakmap.entry(Rc::clone(key)) {
325 Entry::Occupied(occ) => {
326 assert_eq!(occ.get(), value);
327 count += 1;
328 }
329 Entry::Vacant(_) => {
330 eprintln!("PointerWeakWeakHashMap: missing: {}", *key);
331 }
332 }
333 }
334
335 assert_eq!(count, rcs.len());
336 }
337
338 #[test]
339 fn debug_map() {
340 let rcs: Vec<Rc<u32>> = (0..20).map(Rc::new).collect();
341 let map: PtrWeakWeakHashMap<Weak<u32>, Weak<u32>> =
342 rcs.iter().map(|n| (n.clone(), n.clone())).collect();
343 let vec: VecDebugAsMap<_, _> = map.iter().collect();
344 assert_eq!(format!("{map:?}"), format!("{vec:?}"));
345 }
346
347 #[test]
348 fn is_submap() {
349 let mut zero_rcs: Vec<Rc<u32>> = (0..50).map(|_| Rc::new(0)).collect();
350 let rcs: Vec<Rc<u32>> = (0..50).map(Rc::new).collect();
351
352 let weakmap: PtrWeakWeakHashMap<Weak<u32>, Weak<u32>> = zero_rcs
353 .iter()
354 .zip(rcs.iter())
355 .take(25)
356 .map(|(k, v)| (k.clone(), v.clone()))
357 .collect();
358 let mut weakmap2 = weakmap.clone();
359
360 assert!(weakmap.is_submap(&weakmap2));
361 assert!(weakmap2.is_submap(&weakmap));
362
363 weakmap2.extend(
364 zero_rcs
365 .iter()
366 .zip(rcs.iter())
367 .skip(25)
368 .map(|(k, v)| (k.clone(), v.clone())),
369 );
370 assert!(weakmap.is_submap(&weakmap2));
371 assert!(!weakmap2.is_submap(&weakmap));
372 assert!(weakmap.domain_is_subset(&weakmap2));
373 assert!(!weakmap2.domain_is_subset(&weakmap));
374
375 weakmap2.insert(zero_rcs[0].clone(), rcs[12].clone());
376 assert!(!weakmap.is_submap(&weakmap2));
377 assert!(!weakmap2.is_submap(&weakmap));
378 assert!(weakmap.submap_with(&weakmap2, |_v1, _v2| true));
379 assert!(!weakmap2.submap_with(&weakmap, |_v1, _v2| true));
380
381 let _ = zero_rcs.remove(0);
382 assert!(weakmap.is_submap(&weakmap2));
383 }
384}