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
274impl<K, V, const N: usize> From<[(K::Strong, V); N]> for PtrWeakKeyHashMap<K, V, RandomState>
275where
276 K: WeakElement,
277 K::Strong: Deref,
278{
279 fn from(value: [(K::Strong, V); N]) -> Self {
284 Self::from_iter(value)
285 }
286}
287
288impl<K, V, S> Extend<(K::Strong, V)> for PtrWeakKeyHashMap<K, V, S>
289where
290 K: WeakElement,
291 K::Strong: Deref,
292 S: BuildHasher,
293{
294 fn extend<T: IntoIterator<Item = (K::Strong, V)>>(&mut self, iter: T) {
295 self.0.extend(iter);
296 }
297}
298
299impl<'a, K, V, S> Extend<(&'a K::Strong, &'a V)> for PtrWeakKeyHashMap<K, V, S>
300where
301 K: 'a + WeakElement,
302 K::Strong: Clone + Deref,
303 V: 'a + Clone,
304 S: BuildHasher,
305{
306 fn extend<T: IntoIterator<Item = (&'a K::Strong, &'a V)>>(&mut self, iter: T) {
307 self.0.extend(iter);
308 }
309}
310
311impl<K, V: Debug, S> Debug for PtrWeakKeyHashMap<K, V, S>
312where
313 K: WeakElement,
314 K::Strong: Debug,
315{
316 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317 self.0.fmt(f)
318 }
319}
320
321impl<K: WeakElement, V, S> IntoIterator for PtrWeakKeyHashMap<K, V, S> {
322 type Item = (K::Strong, V);
323 type IntoIter = IntoIter<ByPtr<K>, V>;
324
325 fn into_iter(self) -> Self::IntoIter {
329 self.0.into_iter()
330 }
331}
332
333impl<'a, K: WeakElement, V, S> IntoIterator for &'a PtrWeakKeyHashMap<K, V, S> {
334 type Item = (K::Strong, &'a V);
335 type IntoIter = Iter<'a, ByPtr<K>, V>;
336
337 fn into_iter(self) -> Self::IntoIter {
341 (&self.0).into_iter()
342 }
343}
344
345impl<'a, K: WeakElement, V, S> IntoIterator for &'a mut PtrWeakKeyHashMap<K, V, S> {
346 type Item = (K::Strong, &'a mut V);
347 type IntoIter = IterMut<'a, ByPtr<K>, V>;
348
349 fn into_iter(self) -> Self::IntoIter {
353 (&mut self.0).into_iter()
354 }
355}
356
357#[cfg(test)]
358mod test {
359 #![allow(clippy::print_stderr)]
360
361 use super::{Entry, PtrWeakKeyHashMap};
362 use crate::{
363 compat::{
364 eprintln, format,
365 rc::{Rc, Weak},
366 Vec,
367 },
368 tests::util::VecDebugAsMap,
369 };
370
371 crate::tests::common::empty_constructor_tests! {PtrWeakKeyHashMap<Weak<u32>, u32>}
372
373 #[test]
382 fn insert_and_check() {
383 let mut rcs: Vec<Rc<u32>> = Vec::new();
384
385 for i in 0..200 {
386 rcs.push(Rc::new(i));
387 }
388
389 let mut weakmap: PtrWeakKeyHashMap<Weak<u32>, f32> = PtrWeakKeyHashMap::new();
390
391 for item in rcs.iter().cloned() {
392 let f = *item as f32 + 0.1;
393 weakmap.insert(item, f);
394 }
395
396 let mut count = 0;
397
398 for item in &rcs {
399 assert!(weakmap.contains_key(item));
400
401 match weakmap.entry(Rc::clone(item)) {
402 Entry::Occupied(_) => count += 1,
403 Entry::Vacant(_) => eprintln!("PointerWeakKeyHashMap: missing: {}", *item),
404 }
405 }
406
407 assert_eq!(count, rcs.len());
408 }
409
410 #[test]
411 fn debug_map() {
412 let rcs: Vec<Rc<u32>> = (0..20).map(Rc::new).collect();
413 let map: PtrWeakKeyHashMap<Weak<u32>, u32> =
414 rcs.iter().map(|n| (n.clone(), **n * 7)).collect();
415 let vec: VecDebugAsMap<_, _> = map.iter().collect();
416 assert_eq!(format!("{map:?}"), format!("{vec:?}"));
417 }
418
419 #[test]
420 fn is_submap() {
421 let mut rcs: Vec<Rc<u32>> = (0..50).map(|_| Rc::new(0)).collect();
422 let weakmap: PtrWeakKeyHashMap<Weak<u32>, u32> =
423 rcs.iter().take(25).map(|n| (n.clone(), **n)).collect();
424 let mut weakmap2 = weakmap.clone();
425
426 assert!(weakmap.is_submap(&weakmap2));
427 assert!(weakmap2.is_submap(&weakmap));
428
429 weakmap2.extend(rcs.iter().skip(25).map(|n| (n.clone(), **n)));
430 assert!(weakmap.is_submap(&weakmap2));
431 assert!(!weakmap2.is_submap(&weakmap));
432 assert!(weakmap.domain_is_subset(&weakmap2));
433 assert!(!weakmap2.domain_is_subset(&weakmap));
434
435 weakmap2.insert(rcs[0].clone(), 12);
436 assert!(!weakmap.is_submap(&weakmap2));
437 assert!(!weakmap2.is_submap(&weakmap));
438 assert!(weakmap.submap_with(&weakmap2, |_v1, _v2| true));
439 assert!(!weakmap2.submap_with(&weakmap, |_v1, _v2| true));
440
441 let _ = rcs.remove(0);
442 assert!(weakmap.is_submap(&weakmap2));
443 }
444}