1#![warn(missing_docs, missing_debug_implementations)]
23#![no_std]
24
25extern crate alloc;
26#[cfg(feature = "std")]
27extern crate std;
28
29#[cfg(feature = "erasable")]
30use erasable::{Erasable, ErasablePtr, ErasedPtr};
31#[cfg(feature = "std")]
32use std::{
33 io,
34 net::ToSocketAddrs,
35 panic::{RefUnwindSafe, UnwindSafe},
36};
37use {
38 alloc::{
39 rc::{self, Rc},
40 sync::{self, Arc},
41 },
42 core::{
43 borrow::Borrow,
44 cmp::Ordering,
45 fmt::{
46 self, Binary, Debug, Display, Formatter, LowerExp, LowerHex, Octal, Pointer, UpperExp,
47 UpperHex,
48 },
49 hash::{Hash, Hasher},
50 marker::PhantomData,
51 mem::ManuallyDrop,
52 ops::Deref,
53 ptr,
54 },
55};
56
57trait RawRc<T: ?Sized> {
61 type Weak;
62
63 fn as_raw(this: &Self) -> *const T;
65
66 unsafe fn clone_raw(this: *const T) -> Self;
70
71 unsafe fn downgrade_raw(this: *const T) -> Self::Weak;
72}
73
74impl<T: ?Sized> RawRc<T> for Arc<T> {
75 type Weak = sync::Weak<T>;
76
77 #[inline(always)]
78 fn as_raw(this: &Self) -> *const T {
79 Arc::into_raw(unsafe { ptr::read(this) })
81 }
82
83 #[inline(always)]
84 unsafe fn clone_raw(this: *const T) -> Self {
85 Arc::clone(&ManuallyDrop::new(Arc::from_raw(this)))
86 }
87
88 #[inline(always)]
89 unsafe fn downgrade_raw(this: *const T) -> sync::Weak<T> {
90 let this = ManuallyDrop::new(Arc::from_raw(this));
91 Arc::downgrade(&this)
92 }
93}
94
95impl<T: ?Sized> RawRc<T> for Rc<T> {
96 type Weak = rc::Weak<T>;
97
98 #[inline(always)]
99 fn as_raw(this: &Self) -> *const T {
100 Rc::into_raw(unsafe { ptr::read(this) })
102 }
103
104 #[inline(always)]
105 unsafe fn clone_raw(this: *const T) -> Self {
106 Rc::clone(&ManuallyDrop::new(Rc::from_raw(this)))
107 }
108
109 #[inline(always)]
110 unsafe fn downgrade_raw(this: *const T) -> rc::Weak<T> {
111 let this = ManuallyDrop::new(Rc::from_raw(this));
112 Rc::downgrade(&this)
113 }
114}
115
116macro_rules! doc_comment {
118 ($doc:expr, $($tt:tt)*) => {
119 #[doc = $doc]
120 $($tt)*
121 };
122}
123
124macro_rules! rc_borrow {
125 ($($(#[$m:meta])* $vis:vis struct $RcBorrow:ident = &$rc:ident::$Rc:ident;)*) => {$(
126 $(#[$m])*
127 $vis struct $RcBorrow<'a, T: ?Sized> {
128 raw: ptr::NonNull<T>,
129 marker: PhantomData<&'a $Rc<T>>
130 }
131
132 unsafe impl<'a, T: ?Sized> Send for $RcBorrow<'a, T> where &'a $Rc<T>: Send {}
134 unsafe impl<'a, T: ?Sized> Sync for $RcBorrow<'a, T> where &'a $Rc<T>: Sync {}
135
136 impl<'a, T: ?Sized> From<&'a $Rc<T>> for $RcBorrow<'a, T> {
137 fn from(v: &'a $Rc<T>) -> $RcBorrow<'a, T> {
138 let raw = <$Rc<T> as RawRc<T>>::as_raw(v);
139 $RcBorrow {
140 raw: unsafe { ptr::NonNull::new_unchecked(raw as *mut T) },
141 marker: PhantomData,
142 }
143 }
144 }
145
146 impl<'a, T: ?Sized> $RcBorrow<'a, T> {
147 $vis fn upgrade(this: Self) -> $Rc<T> {
149 unsafe { <$Rc<T> as RawRc<T>>::clone_raw(this.raw.as_ptr()) }
150 }
151
152 $vis fn to_weak(this: Self) -> $rc::Weak<T> {
154 unsafe { <$Rc<T> as RawRc<T>>::downgrade_raw(this.raw.as_ptr()) }
155 }
156
157 $vis fn downgrade(this: Self) -> &'a T {
162 unsafe { &*this.raw.as_ptr() }
163 }
164
165 $vis fn strong_count(this: Self) -> usize {
167 let rc = unsafe { ManuallyDrop::new($Rc::from_raw(Self::into_raw(this))) };
168 $Rc::strong_count(&rc)
169 }
170
171 $vis fn weak_count(this: Self) -> usize {
173 let rc = unsafe { ManuallyDrop::new($Rc::from_raw(Self::into_raw(this))) };
174 $Rc::weak_count(&rc)
175 }
176
177 $vis fn into_raw(this: Self) -> *const T {
179 ManuallyDrop::new(this).raw.as_ptr()
180 }
181
182 doc_comment! {
183 concat!("\
184Construct a new `", stringify!($RcBorrow), "` from a raw pointer.
185
186# Safety
187
188The raw pointer must have been previously returned by a call to
189`",stringify!($RcBorrow),"<U>::into_raw` or `",stringify!($Rc),"<U>::as_raw`
190where `U` must have the same size and alignment as `T`. This is trivially true
191if `U` is `T`. Note that if `U` is not `T`, this is a pointer cast (transmute)
192between the two types, and the types must be transmute-compatible."),
193 $vis unsafe fn from_raw(ptr: *const T) -> Self {
194 $RcBorrow {
195 raw: ptr::NonNull::new_unchecked(ptr as *mut T),
196 marker: PhantomData
197 }
198 }
199 }
200 }
201
202 #[cfg(feature = "erasable")]
205 unsafe impl<T: ?Sized> ErasablePtr for $RcBorrow<'_, T>
206 where
207 T: Erasable
208 {
209 #[inline(always)]
210 fn erase(this: Self) -> ErasedPtr {
211 T::erase(this.raw)
212 }
213
214 #[inline(always)]
215 unsafe fn unerase(this: ErasedPtr) -> Self {
216 $RcBorrow {
217 raw: T::unerase(this),
218 marker: PhantomData,
219 }
220 }
221 }
222
223 impl<T: ?Sized, U: ?Sized> AsRef<U> for $RcBorrow<'_, T>
224 where
225 T: AsRef<U>,
226 {
227 fn as_ref(&self) -> &U {
228 (**self).as_ref()
229 }
230 }
231
232 impl<T: ?Sized> Binary for $RcBorrow<'_, T>
233 where
234 T: Binary,
235 {
236 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
237 (**self).fmt(f)
238 }
239 }
240
241 impl<T: ?Sized> Borrow<T> for $RcBorrow<'_, T> {
242 fn borrow(&self) -> &T {
243 &**self
244 }
245 }
246
247 impl<T: ?Sized> Clone for $RcBorrow<'_, T> {
248 fn clone(&self) -> Self { *self }
249 }
250
251 impl<T: ?Sized> Copy for $RcBorrow<'_, T> {}
254
255 impl<T: ?Sized> Debug for $RcBorrow<'_, T>
256 where
257 T: Debug
258 {
259 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
260 (**self).fmt(f)
261 }
262 }
263
264 impl<T: ?Sized> Deref for $RcBorrow<'_, T> {
265 type Target = T;
266 fn deref(&self) -> &T {
267 Self::downgrade(*self)
268 }
269 }
270
271 impl<T: ?Sized> Display for $RcBorrow<'_, T>
274 where
275 T: Display,
276 {
277 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
278 (**self).fmt(f)
279 }
280 }
281
282 impl<T: ?Sized> Eq for $RcBorrow<'_, T> where T: Eq {}
283
284 impl<T: ?Sized> Hash for $RcBorrow<'_, T>
287 where
288 T: Hash,
289 {
290 fn hash<H: Hasher>(&self, state: &mut H) {
291 (**self).hash(state)
292 }
293 }
294
295 impl<T: ?Sized> LowerExp for $RcBorrow<'_, T>
296 where
297 T: LowerExp,
298 {
299 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
300 (**self).fmt(f)
301 }
302 }
303
304 impl<T: ?Sized> LowerHex for $RcBorrow<'_, T>
305 where
306 T: LowerHex,
307 {
308 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
309 (**self).fmt(f)
310 }
311 }
312
313 impl<T: ?Sized> Octal for $RcBorrow<'_, T>
314 where
315 T: Octal,
316 {
317 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
318 (**self).fmt(f)
319 }
320 }
321
322 impl<T: Ord> Ord for $RcBorrow<'_, T>
323 where
324 T: Ord,
325 {
326 fn cmp(&self, other: &Self) -> Ordering {
327 (**self).cmp(&**other)
328 }
329 }
330
331 impl<T: ?Sized, O> PartialEq<O> for $RcBorrow<'_, T>
332 where
333 O: Deref,
334 T: PartialEq<O::Target>,
335 {
336 fn eq(&self, other: &O) -> bool {
337 (**self).eq(&*other)
338 }
339 }
340
341 impl<T: ?Sized, O> PartialOrd<O> for $RcBorrow<'_, T>
342 where
343 O: Deref,
344 T: PartialOrd<O::Target>,
345 {
346 fn partial_cmp(&self, other: &O) -> Option<Ordering> {
347 (**self).partial_cmp(&*other)
348 }
349 }
350
351 impl<T: ?Sized> Pointer for $RcBorrow<'_, T>
352 where
353 T: Pointer,
354 {
355 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
356 (**self).fmt(f)
357 }
358 }
359
360 #[cfg(feature = "std")]
361 impl<T: ?Sized> ToSocketAddrs for $RcBorrow<'_, T>
362 where
363 T: ToSocketAddrs
364 {
365 type Iter = T::Iter;
366 fn to_socket_addrs(&self) -> io::Result<T::Iter> {
367 (**self).to_socket_addrs()
368 }
369 }
370
371 impl<T: ?Sized> Unpin for $RcBorrow<'_, T> {}
372
373 #[cfg(feature = "std")]
374 impl<T: ?Sized> UnwindSafe for $RcBorrow<'_, T> where T: RefUnwindSafe {}
375
376 impl<T: ?Sized> UpperExp for $RcBorrow<'_, T>
377 where
378 T: UpperExp,
379 {
380 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
381 (**self).fmt(f)
382 }
383 }
384
385 impl<T: ?Sized> UpperHex for $RcBorrow<'_, T>
386 where
387 T: UpperHex,
388 {
389 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
390 (**self).fmt(f)
391 }
392 }
393 )*}
394}
395
396rc_borrow! {
397 #[repr(transparent)]
401 pub struct ArcBorrow = &sync::Arc;
402 #[repr(transparent)]
406 pub struct RcBorrow = &rc::Rc;
407}