1use core::borrow::Borrow;
2use core::ffi::c_void;
3use core::hash::{Hash, Hasher};
4use core::ops::Deref;
5use core::ptr;
6use core::ptr::NonNull;
7use core::sync::atomic;
8use core::{cmp::Ordering, marker::PhantomData};
9use core::{fmt, mem};
10
11use erasable::{Erasable, ErasablePtr};
12
13use super::{Arc, ArcInner, ArcRef};
14
15#[repr(transparent)]
22pub struct ArcBorrow<'a, T: ?Sized + 'a> {
23 pub(crate) p: ptr::NonNull<T>,
24 pub(crate) phantom: PhantomData<&'a T>,
25}
26
27impl<'a, T: ?Sized> Copy for ArcBorrow<'a, T> {}
28impl<'a, T: ?Sized> Clone for ArcBorrow<'a, T> {
29 #[inline]
30 fn clone(&self) -> Self {
31 *self
32 }
33}
34
35impl<'a, T: ?Sized> ArcBorrow<'a, T> {
36 #[inline]
38 pub fn clone_arc(this: Self) -> Arc<T> {
39 let arc = unsafe { Arc::from_raw(this.p.as_ptr()) };
40 mem::forget(arc.clone());
42 arc
43 }
44
45 #[inline]
48 pub fn ptr_eq(this: Self, other: Self) -> bool {
49 core::ptr::eq(this.p.as_ptr(), other.p.as_ptr())
50 }
51
52 #[inline]
55 pub fn get(&self) -> &'a T {
56 unsafe { &*(self.p.as_ptr() as *const T) }
57 }
58
59 #[inline]
61 pub fn as_arc(this: &Self) -> &Arc<T> {
62 unsafe { &*(this as *const _ as *const Arc<T>) }
63 }
64
65 #[inline]
67 pub fn into_raw(this: Self) -> *const T {
68 let arc = Self::as_arc(&this);
69 Arc::as_ptr(arc)
70 }
71
72 #[inline]
77 pub unsafe fn from_raw(raw: *const T) -> Self {
78 ArcBorrow {
79 p: NonNull::new_unchecked(raw as *mut T),
80 phantom: PhantomData,
81 }
82 }
83
84 #[inline]
86 pub fn count(this: Self) -> usize {
87 ArcBorrow::load_count(this, atomic::Ordering::Acquire)
88 }
89
90 #[inline]
92 pub fn load_count(this: Self, order: atomic::Ordering) -> usize {
93 unsafe {
94 (*(ArcInner::count_ptr(this.p.as_ptr()) as *const atomic::AtomicUsize)).load(order)
95 }
96 }
97
98 pub fn heap_ptr(self) -> *const c_void {
101 unsafe { ArcInner::count_ptr(self.p.as_ptr()) as *const c_void }
102 }
103}
104
105impl<'a, T> ArcBorrow<'a, T> {
106 #[inline]
108 pub fn as_arc_ref(this: &'a ArcBorrow<'a, T>) -> &'a ArcRef<'a, T> {
109 unsafe { &*(this as *const _ as *const ArcRef<'a, T>) }
110 }
111}
112
113impl<'a, T> Deref for ArcBorrow<'a, T> {
114 type Target = T;
115
116 #[inline]
117 fn deref(&self) -> &T {
118 self.get()
119 }
120}
121
122unsafe impl<T: ?Sized + Erasable> ErasablePtr for ArcBorrow<'_, T> {
123 #[inline]
124 fn erase(this: Self) -> erasable::ErasedPtr {
125 T::erase(unsafe { ptr::NonNull::new_unchecked(ArcBorrow::into_raw(this) as *mut _) })
126 }
127
128 #[inline]
129 unsafe fn unerase(this: erasable::ErasedPtr) -> Self {
130 ArcBorrow::from_raw(T::unerase(this).as_ptr())
131 }
132}
133
134impl<'a, 'b, T, U: PartialEq<T>> PartialEq<ArcBorrow<'a, T>> for ArcBorrow<'b, U> {
135 #[inline]
136 fn eq(&self, other: &ArcBorrow<'a, T>) -> bool {
137 *(*self) == *(*other)
138 }
139
140 #[allow(clippy::partialeq_ne_impl)]
141 #[inline]
142 fn ne(&self, other: &ArcBorrow<'a, T>) -> bool {
143 *(*self) != *(*other)
144 }
145}
146
147impl<'a, 'b, T, U: PartialOrd<T>> PartialOrd<ArcBorrow<'a, T>> for ArcBorrow<'b, U> {
148 #[inline]
149 fn partial_cmp(&self, other: &ArcBorrow<'a, T>) -> Option<Ordering> {
150 (**self).partial_cmp(&**other)
151 }
152
153 #[inline]
154 fn lt(&self, other: &ArcBorrow<'a, T>) -> bool {
155 *(*self) < *(*other)
156 }
157
158 #[inline]
159 fn le(&self, other: &ArcBorrow<'a, T>) -> bool {
160 *(*self) <= *(*other)
161 }
162
163 #[inline]
164 fn gt(&self, other: &ArcBorrow<'a, T>) -> bool {
165 *(*self) > *(*other)
166 }
167
168 #[inline]
169 fn ge(&self, other: &ArcBorrow<'a, T>) -> bool {
170 *(*self) >= *(*other)
171 }
172}
173
174impl<'a, T: Ord> Ord for ArcBorrow<'a, T> {
175 #[inline]
176 fn cmp(&self, other: &ArcBorrow<'a, T>) -> Ordering {
177 (**self).cmp(&**other)
178 }
179}
180
181impl<'a, T: Eq> Eq for ArcBorrow<'a, T> {}
182
183impl<'a, T: fmt::Display> fmt::Display for ArcBorrow<'a, T> {
184 #[inline]
185 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
186 fmt::Display::fmt(&**self, f)
187 }
188}
189
190impl<'a, T: fmt::Debug> fmt::Debug for ArcBorrow<'a, T> {
191 #[inline]
192 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
193 fmt::Debug::fmt(&**self, f)
194 }
195}
196
197impl<T: Hash> Hash for ArcBorrow<'_, T> {
198 #[inline]
199 fn hash<H: Hasher>(&self, state: &mut H) {
200 (**self).hash(state)
201 }
202}
203
204impl<T> Borrow<T> for ArcBorrow<'_, T> {
205 #[inline]
206 fn borrow(&self) -> &T {
207 self
208 }
209}
210
211impl<T> AsRef<T> for ArcBorrow<'_, T> {
212 #[inline]
213 fn as_ref(&self) -> &T {
214 self
215 }
216}
217
218#[cfg(test)]
219mod test {
220 use super::*;
221
222 #[test]
223 fn borrow_count() {
224 let mut borrows = alloc::vec::Vec::with_capacity(100);
225 let x = Arc::new(76);
226 let y = Arc::borrow_arc(&x);
227 assert_eq!(Arc::count(&x), 1);
228 assert_eq!(ArcBorrow::count(y), 1);
229 for i in 0..100 {
230 borrows.push(x.clone());
231 assert_eq!(Arc::count(&x), i + 2);
232 assert_eq!(ArcBorrow::count(y), i + 2);
233 }
234 }
235}