datafusion_expr/
ptr_eq.rs1use std::fmt::Debug;
19use std::hash::{Hash, Hasher};
20use std::ops::Deref;
21use std::sync::Arc;
22
23pub fn arc_ptr_eq<T: ?Sized>(a: &Arc<T>, b: &Arc<T>) -> bool {
27 std::ptr::eq(Arc::as_ptr(a), Arc::as_ptr(b))
28}
29
30pub fn arc_ptr_hash<T: ?Sized>(a: &Arc<T>, hasher: &mut impl Hasher) {
34 std::ptr::hash(Arc::as_ptr(a), hasher)
35}
36
37#[derive(Clone)]
42#[allow(private_bounds)] pub struct PtrEq<Ptr: PointerType>(Ptr);
44
45impl<T> PartialEq for PtrEq<Arc<T>>
46where
47 T: ?Sized,
48{
49 fn eq(&self, other: &Self) -> bool {
50 arc_ptr_eq(&self.0, &other.0)
51 }
52}
53impl<T> Eq for PtrEq<Arc<T>> where T: ?Sized {}
54
55impl<T> Hash for PtrEq<Arc<T>>
56where
57 T: ?Sized,
58{
59 fn hash<H: Hasher>(&self, state: &mut H) {
60 arc_ptr_hash(&self.0, state);
61 }
62}
63
64impl<Ptr> From<Ptr> for PtrEq<Ptr>
65where
66 Ptr: PointerType,
67{
68 fn from(ptr: Ptr) -> Self {
69 PtrEq(ptr)
70 }
71}
72
73impl<T> From<PtrEq<Arc<T>>> for Arc<T>
74where
75 T: ?Sized,
76{
77 fn from(wrapper: PtrEq<Arc<T>>) -> Self {
78 wrapper.0
79 }
80}
81
82impl<Ptr> Debug for PtrEq<Ptr>
83where
84 Ptr: PointerType + Debug,
85{
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 self.0.fmt(f)
88 }
89}
90
91impl<Ptr> Deref for PtrEq<Ptr>
92where
93 Ptr: PointerType,
94{
95 type Target = Ptr;
96
97 fn deref(&self) -> &Self::Target {
98 &self.0
99 }
100}
101
102trait PointerType {}
103impl<T> PointerType for Arc<T> where T: ?Sized {}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108 use std::hash::DefaultHasher;
109
110 #[test]
111 pub fn test_ptr_eq_wrapper() {
112 let a = Arc::new("Hello".to_string());
113 let b = Arc::new(a.deref().clone());
114 let c = Arc::new("world".to_string());
115
116 let wrapper = PtrEq(Arc::clone(&a));
117 assert_eq!(wrapper, wrapper);
118
119 assert_eq!(PtrEq(Arc::clone(&a)), PtrEq(Arc::clone(&a)));
121 assert_eq!(hash(PtrEq(Arc::clone(&a))), hash(PtrEq(Arc::clone(&a))));
122
123 assert_ne!(PtrEq(Arc::clone(&a)), PtrEq(Arc::clone(&b)));
125
126 assert_ne!(PtrEq(Arc::clone(&a)), PtrEq(Arc::clone(&c)));
128 }
129
130 fn hash<T: Hash>(value: T) -> u64 {
131 let hasher = &mut DefaultHasher::new();
132 value.hash(hasher);
133 hasher.finish()
134 }
135}