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
213impl<K, V, const N: usize> From<[(K::Strong, V::Strong); N]>
214 for PtrWeakWeakHashMap<K, V, RandomState>
215where
216 K: WeakElement,
217 K::Strong: Deref,
218 V: WeakElement,
219{
220 fn from(value: [(K::Strong, V::Strong); N]) -> Self {
225 Self::from_iter(value)
226 }
227}
228
229impl<K, V, S> Extend<(K::Strong, V::Strong)> for PtrWeakWeakHashMap<K, V, S>
230where
231 K: WeakElement,
232 K::Strong: Deref,
233 V: WeakElement,
234 S: BuildHasher,
235{
236 fn extend<T: IntoIterator<Item = (K::Strong, V::Strong)>>(&mut self, iter: T) {
237 self.0.extend(iter);
238 }
239}
240
241impl<K, V, S> Debug for PtrWeakWeakHashMap<K, V, S>
242where
243 K: WeakElement,
244 K::Strong: Debug,
245 V: WeakElement,
246 V::Strong: Debug,
247{
248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
249 self.0.fmt(f)
250 }
251}
252
253impl<K: WeakElement, V: WeakElement, S> IntoIterator for PtrWeakWeakHashMap<K, V, S> {
254 type Item = (K::Strong, V::Strong);
255 type IntoIter = IntoIter<ByPtr<K>, V>;
256
257 fn into_iter(self) -> Self::IntoIter {
261 self.0.into_iter()
262 }
263}
264
265impl<'a, K: WeakElement, V: WeakElement, S> IntoIterator for &'a PtrWeakWeakHashMap<K, V, S> {
266 type Item = (K::Strong, V::Strong);
267 type IntoIter = Iter<'a, ByPtr<K>, V>;
268
269 fn into_iter(self) -> Self::IntoIter {
273 (&self.0).into_iter()
274 }
275}
276
277#[cfg(test)]
278mod test {
279 #![allow(clippy::print_stderr)]
280
281 use super::{Entry, PtrWeakWeakHashMap};
282 use crate::{
283 compat::{
284 eprintln, format,
285 rc::{Rc, Weak},
286 Vec,
287 },
288 tests::util::VecDebugAsMap,
289 };
290
291 crate::tests::common::empty_constructor_tests! {PtrWeakWeakHashMap<Weak<u32>, Weak<u32>>}
292
293 #[test]
302 fn insert_and_check() {
303 let mut rcs: Vec<(Rc<u32>, Rc<f32>)> = Vec::new();
304
305 for i in 0..200 {
306 rcs.push((Rc::new(i), Rc::new(i as f32 + 0.1)));
307 }
308
309 let mut weakmap: PtrWeakWeakHashMap<Weak<u32>, Weak<f32>> = PtrWeakWeakHashMap::new();
310
311 for (key, value) in rcs.iter().cloned() {
312 weakmap.insert(key, value);
313 }
315
316 let mut count = 0;
317
318 for (key, value) in &rcs {
319 assert!(weakmap.contains_key(key));
320
321 match weakmap.entry(Rc::clone(key)) {
322 Entry::Occupied(occ) => {
323 assert_eq!(occ.get(), value);
324 count += 1;
325 }
326 Entry::Vacant(_) => {
327 eprintln!("PointerWeakWeakHashMap: missing: {}", *key);
328 }
329 }
330 }
331
332 assert_eq!(count, rcs.len());
333 }
334
335 #[test]
336 fn debug_map() {
337 let rcs: Vec<Rc<u32>> = (0..20).map(Rc::new).collect();
338 let map: PtrWeakWeakHashMap<Weak<u32>, Weak<u32>> =
339 rcs.iter().map(|n| (n.clone(), n.clone())).collect();
340 let vec: VecDebugAsMap<_, _> = map.iter().collect();
341 assert_eq!(format!("{map:?}"), format!("{vec:?}"));
342 }
343
344 #[test]
345 fn is_submap() {
346 let mut zero_rcs: Vec<Rc<u32>> = (0..50).map(|_| Rc::new(0)).collect();
347 let rcs: Vec<Rc<u32>> = (0..50).map(Rc::new).collect();
348
349 let weakmap: PtrWeakWeakHashMap<Weak<u32>, Weak<u32>> = zero_rcs
350 .iter()
351 .zip(rcs.iter())
352 .take(25)
353 .map(|(k, v)| (k.clone(), v.clone()))
354 .collect();
355 let mut weakmap2 = weakmap.clone();
356
357 assert!(weakmap.is_submap(&weakmap2));
358 assert!(weakmap2.is_submap(&weakmap));
359
360 weakmap2.extend(
361 zero_rcs
362 .iter()
363 .zip(rcs.iter())
364 .skip(25)
365 .map(|(k, v)| (k.clone(), v.clone())),
366 );
367 assert!(weakmap.is_submap(&weakmap2));
368 assert!(!weakmap2.is_submap(&weakmap));
369 assert!(weakmap.domain_is_subset(&weakmap2));
370 assert!(!weakmap2.domain_is_subset(&weakmap));
371
372 weakmap2.insert(zero_rcs[0].clone(), rcs[12].clone());
373 assert!(!weakmap.is_submap(&weakmap2));
374 assert!(!weakmap2.is_submap(&weakmap));
375 assert!(weakmap.submap_with(&weakmap2, |_v1, _v2| true));
376 assert!(!weakmap2.submap_with(&weakmap, |_v1, _v2| true));
377
378 let _ = zero_rcs.remove(0);
379 assert!(weakmap.is_submap(&weakmap2));
380 }
381}