1#![allow(clippy::ptr_eq)]
2#![cfg_attr(not(feature = "std"), no_std)]
3
4use core::cmp::Ordering;
5use core::hash::{Hash, Hasher};
6use core::ops::{Deref, DerefMut};
7
8#[cfg(feature = "std")]
9use std::borrow::Borrow;
10#[cfg(feature = "std")]
11use std::rc::Rc;
12#[cfg(feature = "std")]
13use std::sync::Arc;
14
15#[derive(Clone, Copy, Default)]
16pub struct ByAddr<T>(pub T)
17where
18 T: ?Sized + Deref;
19
20impl<T> From<T> for ByAddr<T>
21where
22 T: Deref,
23{
24 fn from(t: T) -> ByAddr<T> {
25 ByAddr(t)
26 }
27}
28
29impl<T> ByAddr<T>
30where
31 T: ?Sized + Deref,
32{
33 fn addr(&self) -> *const T::Target {
34 &*self.0
35 }
36
37 pub fn from_ref(r: &T) -> &Self {
38 unsafe { &*(r as *const T as *const Self) }
39 }
40}
41
42impl<T> PartialEq for ByAddr<T>
43where
44 T: ?Sized + Deref,
45{
46 fn eq(&self, other: &Self) -> bool {
47 self.addr() as *const () == other.addr() as *const ()
48 }
49}
50
51impl<T> Eq for ByAddr<T> where T: ?Sized + Deref {}
52
53impl<T> PartialOrd for ByAddr<T>
54where
55 T: ?Sized + Deref,
56{
57 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
58 Some((self.addr() as *const ()).cmp(&(other.addr() as *const ())))
59 }
60}
61
62impl<T> Ord for ByAddr<T>
63where
64 T: ?Sized + Deref,
65{
66 fn cmp(&self, other: &Self) -> Ordering {
67 (self.addr() as *const ()).cmp(&(other.addr() as *const ()))
68 }
69}
70
71impl<T> Hash for ByAddr<T>
72where
73 T: ?Sized + Deref,
74{
75 fn hash<H: Hasher>(&self, state: &mut H) {
76 self.addr().hash(state)
77 }
78}
79
80impl<T> Deref for ByAddr<T>
81where
82 T: ?Sized + Deref,
83{
84 type Target = T;
85
86 fn deref(&self) -> &Self::Target {
87 &self.0
88 }
89}
90
91impl<T> DerefMut for ByAddr<T>
92where
93 T: ?Sized + Deref,
94{
95 fn deref_mut(&mut self) -> &mut Self::Target {
96 &mut self.0
97 }
98}
99
100impl<T, U> AsRef<U> for ByAddr<T>
101where
102 T: ?Sized + Deref + AsRef<U>,
103{
104 fn as_ref(&self) -> &U {
105 self.0.as_ref()
106 }
107}
108
109impl<T, U> AsMut<U> for ByAddr<T>
110where
111 T: ?Sized + Deref + AsMut<U>,
112{
113 fn as_mut(&mut self) -> &mut U {
114 self.0.as_mut()
115 }
116}
117
118#[cfg(feature = "std")]
119impl<'a, T> Borrow<ByAddr<&'a T>> for ByAddr<Box<T>> {
120 fn borrow(&self) -> &ByAddr<&'a T> {
121 unsafe { &*(self.addr() as *const ByAddr<&'a T>) }
122 }
123}
124
125#[cfg(feature = "std")]
126impl<'a, T> Borrow<ByAddr<&'a T>> for ByAddr<Rc<T>> {
127 fn borrow(&self) -> &ByAddr<&'a T> {
128 unsafe { &*(self.addr() as *const ByAddr<&'a T>) }
129 }
130}
131
132#[cfg(feature = "std")]
133impl<'a, T> Borrow<ByAddr<&'a T>> for ByAddr<Arc<T>> {
134 fn borrow(&self) -> &ByAddr<&'a T> {
135 unsafe { &*(self.addr() as *const ByAddr<&'a T>) }
136 }
137}