1use std::collections::HashMap;
2use std::hash::Hash;
3use std::rc::Rc;
4use std::sync::Arc;
5
6pub trait Ref: Clone {
7 fn is_same_ref(&self, other: &Self) -> bool;
8 fn hash_ref(&self, hasher: &mut impl std::hash::Hasher);
9}
10
11impl<T> Ref for Rc<T> {
12 fn is_same_ref(&self, other: &Self) -> bool {
13 Rc::ptr_eq(self, other)
14 }
15 fn hash_ref(&self, hasher: &mut impl std::hash::Hasher) {
16 Rc::as_ptr(self).hash(hasher)
17 }
18}
19
20impl<T> Ref for Arc<T> {
21 fn is_same_ref(&self, other: &Self) -> bool {
22 Arc::ptr_eq(self, other)
23 }
24 fn hash_ref(&self, hasher: &mut impl std::hash::Hasher) {
25 Arc::as_ptr(self).hash(hasher)
26 }
27}
28
29impl<T> Ref for &'_ T {
30 fn is_same_ref(&self, other: &Self) -> bool {
31 std::ptr::eq(*self, *other)
32 }
33 fn hash_ref(&self, hasher: &mut impl std::hash::Hasher) {
34 (*self as *const T).hash(hasher)
35 }
36}
37
38#[derive(Clone)]
39struct RefKey<K: Ref>(K);
40
41impl<K: Ref> PartialEq for RefKey<K> {
42 fn eq(&self, other: &Self) -> bool {
43 self.0.is_same_ref(&other.0)
44 }
45}
46impl<K: Ref> Eq for RefKey<K> {}
47
48impl<K: Ref> Hash for RefKey<K> {
49 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
50 self.0.hash_ref(state)
51 }
52}
53
54pub struct RefMap<K: Ref, V>(HashMap<RefKey<K>, V>);
55
56impl<K: Ref, V: Clone> Clone for RefMap<K, V> {
57 fn clone(&self) -> Self {
58 Self(self.0.clone())
59 }
60}
61
62impl<K: Ref, V> Default for RefMap<K, V> {
63 fn default() -> Self {
64 Self::new()
65 }
66}
67
68impl<K: Ref, V> RefMap<K, V> {
69 pub fn new() -> Self {
70 Self(HashMap::new())
71 }
72 pub fn insert(&mut self, key: K, value: V) {
73 self.0.insert(RefKey(key), value);
74 }
75 pub fn get(&self, key: &K) -> Option<&V> {
76 self.0.get(&RefKey(key.clone()))
77 }
78 pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
79 self.0.get_mut(&RefKey(key))
80 }
81 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
82 self.0.iter().map(|(RefKey(key), value)| (key, value))
83 }
84 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
85 self.0.iter_mut().map(|(RefKey(key), value)| (key, value))
86 }
87}
88
89impl<K: Ref + 'static, V: 'static> IntoIterator for RefMap<K, V> {
90 type Item = (K, V);
91 type IntoIter = Box<dyn Iterator<Item = (K, V)>>; fn into_iter(self) -> Self::IntoIter {
93 Box::new(self.0.into_iter().map(|(RefKey(key), value)| (key, value)))
94 }
95}