1use crate::common::*;
4use crate::compat::*;
5
6use super::by_ptr::*;
7use super::traits::*;
8use super::weak_key_hash_map as base;
9
10pub use super::weak_key_hash_map::{
11 Drain, Entry, ExtractIf, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, ValuesMut,
12};
13pub use super::PtrWeakKeyHashMap;
14
15universal_hashless_members! {
16 PtrWeakKeyHashMap
17 ("`PtrWeakKeyHashMap", a "map")
18 crate::WeakKeyHashMap::with_capacity_and_hasher
19 {K, V}
20}
21
22impl<K: WeakElement, V, S: BuildHasher> PtrWeakKeyHashMap<K, V, S>
23where
24 K::Strong: Deref,
25{
26 universal_key_independent_members! {"mappings"}
27
28 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> {
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 get_mut(&mut self, key: &K::Strong) -> Option<&mut V> {
58 let p = key.deref() as *const _;
59 self.0.get_mut(&p)
60 }
61
62 pub fn get_disjoint_mut<const N: usize>(&mut self, ks: [&K::Strong; N]) -> [Option<&mut V>; N] {
80 let ks: [*const <K::Strong as Deref>::Target; N] = ks.map(|k| (*k).deref() as *const _);
81 let ks_refs = crate::util::each_ref(&ks);
82
83 self.0
84 .0
85 .get_disjoint_mut(ks_refs)
86 .map(|ent| ent.map(|(_k, v)| v))
87 }
88
89 pub fn insert(&mut self, key: K::Strong, value: V) -> Option<V> {
94 self.0.insert(key, value)
95 }
96
97 pub fn remove(&mut self, key: &K::Strong) -> Option<V> {
101 self.0.remove(&(key.deref() as *const _))
102 }
103
104 pub fn retain<F>(&mut self, f: F)
110 where
111 F: FnMut(K::Strong, &mut V) -> bool,
112 {
113 self.0.retain(f);
114 }
115
116 pub fn submap_with<F, S1, V1>(
125 &self,
126 other: &PtrWeakKeyHashMap<K, V1, S1>,
127 value_equal: F,
128 ) -> bool
129 where
130 F: FnMut(&V, &V1) -> bool,
131 S1: BuildHasher,
132 {
133 self.0.is_submap_with(&other.0, value_equal)
134 }
135
136 pub fn is_submap<V1, S1>(&self, other: &PtrWeakKeyHashMap<K, V1, S1>) -> bool
142 where
143 V: PartialEq<V1>,
144 S1: BuildHasher,
145 {
146 self.0.is_submap(&other.0)
147 }
148
149 pub fn domain_is_subset<V1, S1>(&self, other: &PtrWeakKeyHashMap<K, V1, S1>) -> bool
155 where
156 S1: BuildHasher,
157 {
158 self.0.domain_is_subset(&other.0)
159 }
160}
161
162impl<K: WeakElement, V, S> PtrWeakKeyHashMap<K, V, S> {
163 pub fn iter(&self) -> Iter<'_, ByPtr<K>, V> {
167 self.0.iter()
168 }
169
170 pub fn keys(&self) -> Keys<'_, ByPtr<K>, V> {
174 self.0.keys()
175 }
176
177 pub fn values(&self) -> Values<'_, ByPtr<K>, V> {
181 self.0.values()
182 }
183
184 pub fn iter_mut(&mut self) -> IterMut<'_, ByPtr<K>, V> {
188 self.0.iter_mut()
189 }
190
191 pub fn values_mut(&mut self) -> ValuesMut<'_, ByPtr<K>, V> {
195 self.0.values_mut()
196 }
197
198 pub fn drain(&mut self) -> Drain<'_, ByPtr<K>, V> {
202 self.0.drain()
203 }
204
205 ptr_into_kv_methods! {}
206
207 pub fn extract_if<'a, F>(&'a mut self, f: F) -> ExtractIf<'a, ByPtr<K>, V, F>
217 where
218 F: FnMut(K::Strong, &mut V) -> bool + 'a,
219 {
220 self.0.extract_if(f)
221 }
222}
223
224impl<K, V, V1, S, S1> PartialEq<PtrWeakKeyHashMap<K, V1, S1>> for PtrWeakKeyHashMap<K, V, S>
225where
226 K: WeakElement,
227 K::Strong: Deref,
228 V: PartialEq<V1>,
229 S: BuildHasher,
230 S1: BuildHasher,
231{
232 fn eq(&self, other: &PtrWeakKeyHashMap<K, V1, S1>) -> bool {
233 self.0 == other.0
234 }
235}
236
237impl<K: WeakElement, V: Eq, S: BuildHasher> Eq for PtrWeakKeyHashMap<K, V, S> where K::Strong: Deref {}
238
239impl<'a, K, V, S> Index<&'a K::Strong> for PtrWeakKeyHashMap<K, V, S>
240where
241 K: WeakElement,
242 K::Strong: Deref,
243 S: BuildHasher,
244{
245 type Output = V;
246
247 fn index(&self, index: &'a K::Strong) -> &Self::Output {
248 self.0.index(&(index.deref() as *const _))
249 }
250}
251
252impl<'a, K, V, S> IndexMut<&'a K::Strong> for PtrWeakKeyHashMap<K, V, S>
253where
254 K: WeakElement,
255 K::Strong: Deref,
256 S: BuildHasher,
257{
258 fn index_mut(&mut self, index: &'a K::Strong) -> &mut Self::Output {
259 self.0.index_mut(&(index.deref() as *const _))
260 }
261}
262
263impl<K, V, S> FromIterator<(K::Strong, V)> for PtrWeakKeyHashMap<K, V, S>
264where
265 K: WeakElement,
266 K::Strong: Deref,
267 S: BuildHasher + Default,
268{
269 fn from_iter<T: IntoIterator<Item = (K::Strong, V)>>(iter: T) -> Self {
270 PtrWeakKeyHashMap(base::WeakKeyHashMap::<ByPtr<K>, V, S>::from_iter(iter))
271 }
272}
273
274#[cfg(any(test, feature = "std", feature = "ahash"))]
275impl<K, V, const N: usize> From<[(K::Strong, V); N]> for PtrWeakKeyHashMap<K, V, RandomState>
276where
277 K: WeakElement,
278 K::Strong: Deref,
279{
280 fn from(value: [(K::Strong, V); N]) -> Self {
285 Self::from_iter(value)
286 }
287}
288
289impl<K, V, S> Extend<(K::Strong, V)> for PtrWeakKeyHashMap<K, V, S>
290where
291 K: WeakElement,
292 K::Strong: Deref,
293 S: BuildHasher,
294{
295 fn extend<T: IntoIterator<Item = (K::Strong, V)>>(&mut self, iter: T) {
296 self.0.extend(iter);
297 }
298}
299
300impl<'a, K, V, S> Extend<(&'a K::Strong, &'a V)> for PtrWeakKeyHashMap<K, V, S>
301where
302 K: 'a + WeakElement,
303 K::Strong: Clone + Deref,
304 V: 'a + Clone,
305 S: BuildHasher,
306{
307 fn extend<T: IntoIterator<Item = (&'a K::Strong, &'a V)>>(&mut self, iter: T) {
308 self.0.extend(iter);
309 }
310}
311
312impl<K, V: Debug, S> Debug for PtrWeakKeyHashMap<K, V, S>
313where
314 K: WeakElement,
315 K::Strong: Debug,
316{
317 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
318 self.0.fmt(f)
319 }
320}
321
322impl<K: WeakElement, V, S> IntoIterator for PtrWeakKeyHashMap<K, V, S> {
323 type Item = (K::Strong, V);
324 type IntoIter = IntoIter<ByPtr<K>, V>;
325
326 fn into_iter(self) -> Self::IntoIter {
330 self.0.into_iter()
331 }
332}
333
334impl<'a, K: WeakElement, V, S> IntoIterator for &'a PtrWeakKeyHashMap<K, V, S> {
335 type Item = (K::Strong, &'a V);
336 type IntoIter = Iter<'a, ByPtr<K>, V>;
337
338 fn into_iter(self) -> Self::IntoIter {
342 (&self.0).into_iter()
343 }
344}
345
346impl<'a, K: WeakElement, V, S> IntoIterator for &'a mut PtrWeakKeyHashMap<K, V, S> {
347 type Item = (K::Strong, &'a mut V);
348 type IntoIter = IterMut<'a, ByPtr<K>, V>;
349
350 fn into_iter(self) -> Self::IntoIter {
354 (&mut self.0).into_iter()
355 }
356}
357
358#[cfg(test)]
359mod test {
360 #![allow(clippy::print_stderr)]
361 #![cfg_attr(feature = "ahash", allow(deprecated))]
363
364 use super::{Entry, PtrWeakKeyHashMap};
365 use crate::{
366 compat::{
367 eprintln, format,
368 rc::{Rc, Weak},
369 Vec,
370 },
371 tests::util::VecDebugAsMap,
372 };
373
374 crate::tests::common::empty_constructor_tests! {PtrWeakKeyHashMap<Weak<u32>, u32>}
375
376 #[test]
385 fn insert_and_check() {
386 let mut rcs: Vec<Rc<u32>> = Vec::new();
387
388 for i in 0..200 {
389 rcs.push(Rc::new(i));
390 }
391
392 let mut weakmap: PtrWeakKeyHashMap<Weak<u32>, f32> = PtrWeakKeyHashMap::new();
393
394 for item in rcs.iter().cloned() {
395 let f = *item as f32 + 0.1;
396 weakmap.insert(item, f);
397 }
398
399 let mut count = 0;
400
401 for item in &rcs {
402 assert!(weakmap.contains_key(item));
403
404 match weakmap.entry(Rc::clone(item)) {
405 Entry::Occupied(_) => count += 1,
406 Entry::Vacant(_) => eprintln!("PointerWeakKeyHashMap: missing: {}", *item),
407 }
408 }
409
410 assert_eq!(count, rcs.len());
411 }
412
413 #[test]
414 fn debug_map() {
415 let rcs: Vec<Rc<u32>> = (0..20).map(Rc::new).collect();
416 let map: PtrWeakKeyHashMap<Weak<u32>, u32> =
417 rcs.iter().map(|n| (n.clone(), **n * 7)).collect();
418 let vec: VecDebugAsMap<_, _> = map.iter().collect();
419 assert_eq!(format!("{map:?}"), format!("{vec:?}"));
420 }
421
422 #[test]
423 fn is_submap() {
424 let mut rcs: Vec<Rc<u32>> = (0..50).map(|_| Rc::new(0)).collect();
425 let weakmap: PtrWeakKeyHashMap<Weak<u32>, u32> =
426 rcs.iter().take(25).map(|n| (n.clone(), **n)).collect();
427 let mut weakmap2 = weakmap.clone();
428
429 assert!(weakmap.is_submap(&weakmap2));
430 assert!(weakmap2.is_submap(&weakmap));
431
432 weakmap2.extend(rcs.iter().skip(25).map(|n| (n.clone(), **n)));
433 assert!(weakmap.is_submap(&weakmap2));
434 assert!(!weakmap2.is_submap(&weakmap));
435 assert!(weakmap.domain_is_subset(&weakmap2));
436 assert!(!weakmap2.domain_is_subset(&weakmap));
437
438 weakmap2.insert(rcs[0].clone(), 12);
439 assert!(!weakmap.is_submap(&weakmap2));
440 assert!(!weakmap2.is_submap(&weakmap));
441 assert!(weakmap.submap_with(&weakmap2, |_v1, _v2| true));
442 assert!(!weakmap2.submap_with(&weakmap, |_v1, _v2| true));
443
444 let _ = rcs.remove(0);
445 assert!(weakmap.is_submap(&weakmap2));
446 }
447}