backdrop_arc/
offset_arc.rs1use alloc::boxed::Box;
2use core::fmt;
3use core::marker::PhantomData;
4use core::mem::ManuallyDrop;
5use core::ops::Deref;
6use core::ptr;
7
8extern crate backdrop;
9use crate::ArcInner;
10
11use self::backdrop::BackdropStrategy;
12
13use super::{Arc, ArcBorrow};
14
15#[derive(Eq)]
38#[repr(transparent)]
39pub struct OffsetArc<T, S>
40where
41 S: BackdropStrategy<Box<ArcInner<T>>>,
42{
43 pub(crate) ptr: ptr::NonNull<T>,
44 pub(crate) phantom: PhantomData<T>,
45 pub(crate) phantom_strategy: PhantomData<S>,
46}
47
48unsafe impl<T: Sync + Send, S> Send for OffsetArc<T, S> where S: BackdropStrategy<Box<ArcInner<T>>> {}
49unsafe impl<T: Sync + Send, S> Sync for OffsetArc<T, S> where S: BackdropStrategy<Box<ArcInner<T>>> {}
50
51impl<T, S> Deref for OffsetArc<T, S>
52where
53 S: BackdropStrategy<Box<ArcInner<T>>>,
54{
55 type Target = T;
56 #[inline]
57 fn deref(&self) -> &Self::Target {
58 unsafe { &*self.ptr.as_ptr() }
59 }
60}
61
62impl<T, S> Clone for OffsetArc<T, S>
63where
64 S: BackdropStrategy<Box<ArcInner<T>>>,
65{
66 #[inline]
67 fn clone(&self) -> Self {
68 Arc::into_raw_offset(self.clone_arc())
69 }
70}
71
72impl<T, S> Drop for OffsetArc<T, S>
73where
74 S: BackdropStrategy<Box<ArcInner<T>>>,
75{
76 fn drop(&mut self) {
77 let _ = Arc::<_, S>::from_raw_offset(OffsetArc {
78 ptr: self.ptr,
79 phantom: PhantomData,
80 phantom_strategy: PhantomData,
81 });
82 }
83}
84
85impl<T: fmt::Debug, S> fmt::Debug for OffsetArc<T, S>
86where
87 S: BackdropStrategy<Box<ArcInner<T>>>,
88{
89 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90 fmt::Debug::fmt(&**self, f)
91 }
92}
93
94impl<T: PartialEq, S> PartialEq for OffsetArc<T, S>
95where
96 S: BackdropStrategy<Box<ArcInner<T>>>,
97{
98 fn eq(&self, other: &OffsetArc<T, S>) -> bool {
99 *(*self) == *(*other)
100 }
101
102 #[allow(clippy::partialeq_ne_impl)]
103 fn ne(&self, other: &OffsetArc<T, S>) -> bool {
104 *(*self) != *(*other)
105 }
106}
107
108impl<T, S> OffsetArc<T, S>
109where
110 S: BackdropStrategy<Box<ArcInner<T>>>,
111{
112 #[inline]
115 pub fn with_arc<F, U>(&self, f: F) -> U
116 where
117 F: FnOnce(&Arc<T, S>) -> U,
118 {
119 let transient = unsafe { ManuallyDrop::new(Arc::from_raw(self.ptr.as_ptr())) };
121
122 f(&transient)
125 }
126
127 #[inline]
132 pub fn make_mut(&mut self) -> &mut T
133 where
134 T: Clone,
135 {
136 unsafe {
137 let this = ptr::read(self);
139 let mut arc = Arc::from_raw_offset(this);
141 let ret = Arc::make_mut(&mut arc) as *mut _;
144 ptr::write(self, Arc::into_raw_offset(arc));
147 &mut *ret
148 }
149 }
150
151 #[inline]
153 pub fn clone_arc(&self) -> Arc<T, S> {
154 OffsetArc::with_arc(self, |a| a.clone())
155 }
156
157 #[inline]
160 pub fn borrow_arc(&self) -> ArcBorrow<'_, T> {
161 ArcBorrow(&**self)
162 }
163}