1#![no_std]
14
15#[cfg(feature = "std")]
16extern crate std;
17
18use core::hash::{Hash, Hasher};
19
20pub trait Same {
48 fn same(&self, other: &Self) -> bool;
50}
51
52pub trait RefHash {
57 fn ref_hash<H: Hasher>(&self, hasher: &mut H);
59}
60
61impl<'a, T> Same for &'a T {
62 fn same(&self, other: &Self) -> bool {
63 let a: *const T = *self;
64 let b: *const T = *other;
65
66 a == b
67 }
68}
69
70#[cfg(feature = "std")]
71impl<T> Same for std::rc::Rc<T> {
72 fn same(&self, other: &Self) -> bool {
73 std::rc::Rc::ptr_eq(self, other)
74 }
75}
76
77#[cfg(feature = "std")]
78impl<T> Same for std::sync::Arc<T> {
79 fn same(&self, other: &Self) -> bool {
80 std::sync::Arc::ptr_eq(self, other)
81 }
82}
83
84impl<'a, T> RefHash for &'a T {
85 fn ref_hash<H: Hasher>(&self, hasher: &mut H) {
86 let ptr: *const T = *self;
87
88 ptr.hash(hasher);
89 }
90}
91
92#[cfg(feature = "std")]
93impl<T> RefHash for std::rc::Rc<T> {
94 fn ref_hash<H: Hasher>(&self, hasher: &mut H) {
95 (&**self).ref_hash(hasher);
96 }
97}
98
99#[cfg(feature = "std")]
100impl<T> RefHash for std::sync::Arc<T> {
101 fn ref_hash<H: Hasher>(&self, hasher: &mut H) {
102 (&**self).ref_hash(hasher);
103 }
104}
105
106pub struct RefCmp<T: Same>(pub T);
131
132impl<T: Same> Eq for RefCmp<T> {}
133impl<T: Same> PartialEq for RefCmp<T> {
134 fn eq(&self, other: &Self) -> bool {
135 self.0.same(&other.0)
136 }
137}
138
139impl<T: Same + RefHash> Hash for RefCmp<T> {
140 fn hash<H: Hasher>(&self, hasher: &mut H) {
141 self.0.ref_hash(hasher);
142 }
143}
144
145impl<T: Same> core::ops::Deref for RefCmp<T> {
146 type Target = T;
147
148 fn deref(&self) -> &Self::Target {
149 &self.0
150 }
151}
152
153impl<U, T: Same + AsRef<U>> AsRef<U> for RefCmp<T> {
154 fn as_ref(&self) -> &U {
155 self.0.as_ref()
156 }
157}
158
159impl<T: Same> core::borrow::Borrow<T> for RefCmp<T> {
160 fn borrow(&self) -> &T {
161 &self.0
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use ::Same;
168 use ::RefCmp;
169
170 #[test]
171 fn refs() {
172 let a = 42;
173 let b = 42;
174
175 let a_ref = &a;
176 let a_ref_again = &a;
177 let b_ref = &b;
178
179 assert!(a_ref.same(&a_ref_again));
180 assert!(!a_ref.same(&b_ref));
181
182 let mut hash_set = ::std::collections::HashSet::new();
183 assert!(hash_set.insert(RefCmp(a_ref)));
184 assert!(!hash_set.insert(RefCmp(a_ref_again)));
185 assert!(hash_set.insert(RefCmp(b_ref)));
186 }
187
188 #[test]
189 fn rcs() {
190 let a = ::std::rc::Rc::new(42);
191 let a_cloned = a.clone();
192 let b = ::std::rc::Rc::new(42);
193
194 assert!(a.same(&a_cloned));
195 assert!(!a.same(&b));
196
197 let mut hash_set = ::std::collections::HashSet::new();
198 assert!(hash_set.insert(RefCmp(a)));
199 assert!(!hash_set.insert(RefCmp(a_cloned)));
200 assert!(hash_set.insert(RefCmp(b)));
201 }
202
203 #[test]
204 fn arcs() {
205 let a = ::std::sync::Arc::new(42);
206 let a_cloned = a.clone();
207 let b = ::std::sync::Arc::new(42);
208
209 assert!(a.same(&a_cloned));
210 assert!(!a.same(&b));
211
212 let mut hash_set = ::std::collections::HashSet::new();
213 assert!(hash_set.insert(RefCmp(a)));
214 assert!(!hash_set.insert(RefCmp(a_cloned)));
215 assert!(hash_set.insert(RefCmp(b)));
216 }
217}