archery/shared_pointer/
mod.rs

1use crate::shared_pointer::kind::SharedPointerKind;
2use alloc::boxed::Box;
3use core::borrow::Borrow;
4use core::cmp::Ordering;
5use core::fmt;
6use core::fmt::Debug;
7use core::fmt::Display;
8use core::fmt::Formatter;
9use core::hash::Hash;
10use core::hash::Hasher;
11use core::marker::PhantomData;
12use core::mem;
13use core::mem::ManuallyDrop;
14use core::ops::Deref;
15use core::pin::Pin;
16use core::ptr;
17
18/// Pointer to shared data with reference-counting.
19///
20/// The type parameter `P` is a [type constructor](https://en.wikipedia.org/wiki/Type_constructor)
21/// of the underlying pointer type, offering a way to abstraction over [`Rc`](alloc::rc::Rc) and
22/// [`Arc`](alloc::sync::Arc) smart pointers.
23/// This allows you to create data structures where the pointer type is parameterizable, so you can
24/// [avoid the overhead of `Arc`](alloc::sync::Arc#thread-safety)
25/// when you don’t need to share data across threads.
26///
27/// # Example
28///
29/// Declare a data structure with the pointer kind as a type parameter bounded by
30/// [`SharedPointerKind`]:
31///
32/// ```rust
33/// use archery::*;
34///
35/// struct KeyValuePair<K, V, P: SharedPointerKind> {
36///     pub key: SharedPointer<K, P>,
37///     pub value: SharedPointer<V, P>,
38/// }
39///
40/// impl<K, V, P: SharedPointerKind> KeyValuePair<K, V, P> {
41///     fn new(key: K, value: V) -> KeyValuePair<K, V, P> {
42///         KeyValuePair {
43///             key: SharedPointer::new(key),
44///             value: SharedPointer::new(value),
45///         }
46///     }
47/// }
48/// ```
49///
50/// To use it just plug-in the kind of pointer you want:
51///
52/// ```rust
53/// # use archery::*;
54/// #
55/// # struct KeyValuePair<K, V, P: SharedPointerKind> {
56/// #    pub key: SharedPointer<K, P>,
57/// #    pub value: SharedPointer<V, P>,
58/// # }
59/// #
60/// # impl<K, V, P: SharedPointerKind> KeyValuePair<K, V, P> {
61/// #     fn new(key: K, value: V) -> KeyValuePair<K, V, P> {
62/// #         KeyValuePair {
63/// #             key: SharedPointer::new(key),
64/// #             value: SharedPointer::new(value),
65/// #         }
66/// #     }
67/// # }
68/// #
69/// let pair: KeyValuePair<_, _, RcK> =
70///     KeyValuePair::new("António Variações", 1944);
71///
72/// assert_eq!(*pair.value, 1944);
73/// ```
74pub struct SharedPointer<T, P>
75where
76    P: SharedPointerKind,
77{
78    ptr: ManuallyDrop<P>,
79    _phantom_t: PhantomData<T>,
80    _phantom_no_send_sync: PhantomData<*mut ()>,
81}
82
83unsafe impl<T: Sync + Send, P: Send> Send for SharedPointer<T, P> where P: SharedPointerKind {}
84unsafe impl<T: Sync + Send, P: Sync> Sync for SharedPointer<T, P> where P: SharedPointerKind {}
85
86impl<T, P> Unpin for SharedPointer<T, P> where P: SharedPointerKind {}
87
88impl<T, P> SharedPointer<T, P>
89where
90    P: SharedPointerKind,
91{
92    #[inline(always)]
93    fn new_from_inner(ptr: P) -> SharedPointer<T, P> {
94        SharedPointer {
95            ptr: ManuallyDrop::new(ptr),
96            _phantom_t: PhantomData,
97            _phantom_no_send_sync: PhantomData,
98        }
99    }
100
101    #[inline(always)]
102    pub fn new(v: T) -> SharedPointer<T, P> {
103        SharedPointer::new_from_inner(P::new::<T>(v))
104    }
105
106    #[inline(always)]
107    pub fn pin(v: T) -> Pin<SharedPointer<T, P>> {
108        unsafe { Pin::new_unchecked(Self::new(v)) }
109    }
110
111    #[inline(always)]
112    pub fn as_ptr(this: &Self) -> *const T {
113        unsafe { this.ptr.as_ptr::<T>() }
114    }
115
116    #[inline(always)]
117    pub fn try_unwrap(mut this: SharedPointer<T, P>) -> Result<T, SharedPointer<T, P>> {
118        let ptr: P = unsafe { ManuallyDrop::take(&mut this.ptr) };
119
120        mem::forget(this);
121
122        unsafe { ptr.try_unwrap::<T>() }.map_err(SharedPointer::new_from_inner)
123    }
124
125    #[inline(always)]
126    pub fn get_mut(this: &mut SharedPointer<T, P>) -> Option<&mut T> {
127        unsafe { this.ptr.get_mut::<T>() }
128    }
129
130    #[inline(always)]
131    pub fn strong_count(this: &Self) -> usize {
132        unsafe { this.ptr.strong_count::<T>() }
133    }
134
135    #[inline(always)]
136    pub fn ptr_eq<PO: SharedPointerKind>(
137        this: &SharedPointer<T, P>,
138        other: &SharedPointer<T, PO>,
139    ) -> bool {
140        ptr::eq(this.deref(), other.deref())
141    }
142}
143
144impl<T, P> SharedPointer<T, P>
145where
146    T: Clone,
147    P: SharedPointerKind,
148{
149    #[inline(always)]
150    pub fn make_mut(this: &mut SharedPointer<T, P>) -> &mut T {
151        unsafe { this.ptr.make_mut::<T>() }
152    }
153}
154
155impl<T, P> Default for SharedPointer<T, P>
156where
157    T: Default,
158    P: SharedPointerKind,
159{
160    #[inline(always)]
161    fn default() -> SharedPointer<T, P> {
162        SharedPointer::new(Default::default())
163    }
164}
165
166impl<T, P> Deref for SharedPointer<T, P>
167where
168    P: SharedPointerKind,
169{
170    type Target = T;
171
172    #[inline(always)]
173    fn deref(&self) -> &T {
174        unsafe { self.ptr.deref().deref() }
175    }
176}
177
178impl<T, P> Borrow<T> for SharedPointer<T, P>
179where
180    P: SharedPointerKind,
181{
182    #[inline(always)]
183    fn borrow(&self) -> &T {
184        self.deref()
185    }
186}
187
188impl<T, P> AsRef<T> for SharedPointer<T, P>
189where
190    P: SharedPointerKind,
191{
192    #[inline(always)]
193    fn as_ref(&self) -> &T {
194        self.deref()
195    }
196}
197
198impl<T, P> Clone for SharedPointer<T, P>
199where
200    P: SharedPointerKind,
201{
202    #[inline(always)]
203    fn clone(&self) -> SharedPointer<T, P> {
204        SharedPointer::new_from_inner(unsafe { self.ptr.deref().clone::<T>() })
205    }
206}
207
208impl<T, P> Hash for SharedPointer<T, P>
209where
210    T: Hash,
211    P: SharedPointerKind,
212{
213    #[inline(always)]
214    fn hash<H: Hasher>(&self, state: &mut H) {
215        self.deref().hash(state);
216    }
217}
218
219impl<T, P, PO> PartialEq<SharedPointer<T, PO>> for SharedPointer<T, P>
220where
221    T: PartialEq,
222    P: SharedPointerKind,
223    PO: SharedPointerKind,
224{
225    #[inline(always)]
226    fn eq(&self, other: &SharedPointer<T, PO>) -> bool {
227        self.deref().eq(other.deref())
228    }
229
230    #[inline(always)]
231    fn ne(&self, other: &SharedPointer<T, PO>) -> bool {
232        self.deref().ne(other.deref())
233    }
234}
235
236impl<T, P> Eq for SharedPointer<T, P>
237where
238    T: Eq,
239    P: SharedPointerKind,
240{
241}
242
243impl<T, P, PO> PartialOrd<SharedPointer<T, PO>> for SharedPointer<T, P>
244where
245    T: PartialOrd,
246    P: SharedPointerKind,
247    PO: SharedPointerKind,
248{
249    #[inline(always)]
250    fn partial_cmp(&self, other: &SharedPointer<T, PO>) -> Option<Ordering> {
251        self.deref().partial_cmp(other.deref())
252    }
253
254    #[inline(always)]
255    fn lt(&self, other: &SharedPointer<T, PO>) -> bool {
256        self.deref().lt(other.deref())
257    }
258
259    #[inline(always)]
260    fn le(&self, other: &SharedPointer<T, PO>) -> bool {
261        self.deref().le(other.deref())
262    }
263
264    #[inline(always)]
265    fn gt(&self, other: &SharedPointer<T, PO>) -> bool {
266        self.deref().gt(other.deref())
267    }
268
269    #[inline(always)]
270    fn ge(&self, other: &SharedPointer<T, PO>) -> bool {
271        self.deref().ge(other.deref())
272    }
273}
274
275impl<T, P> Ord for SharedPointer<T, P>
276where
277    T: Ord,
278    P: SharedPointerKind,
279{
280    #[inline(always)]
281    fn cmp(&self, other: &SharedPointer<T, P>) -> Ordering {
282        self.deref().cmp(other.deref())
283    }
284}
285
286impl<T, P> From<T> for SharedPointer<T, P>
287where
288    P: SharedPointerKind,
289{
290    #[inline(always)]
291    fn from(other: T) -> SharedPointer<T, P> {
292        SharedPointer::new(other)
293    }
294}
295
296impl<T, P> From<Box<T>> for SharedPointer<T, P>
297where
298    P: SharedPointerKind,
299{
300    #[inline(always)]
301    fn from(v: Box<T>) -> SharedPointer<T, P> {
302        SharedPointer::new_from_inner(P::from_box(v))
303    }
304}
305
306impl<T, P> Debug for SharedPointer<T, P>
307where
308    T: Debug,
309    P: SharedPointerKind,
310{
311    #[inline(always)]
312    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
313        Debug::fmt(self.deref(), f)
314    }
315}
316
317impl<T, P> fmt::Pointer for SharedPointer<T, P>
318where
319    P: SharedPointerKind,
320{
321    #[inline(always)]
322    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
323        fmt::Pointer::fmt(&core::ptr::addr_of!(**self), f)
324    }
325}
326
327impl<T, P> Display for SharedPointer<T, P>
328where
329    T: Display,
330    P: SharedPointerKind,
331{
332    #[inline(always)]
333    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
334        Display::fmt(self.deref(), f)
335    }
336}
337
338impl<T, P> Drop for SharedPointer<T, P>
339where
340    P: SharedPointerKind,
341{
342    #[inline(always)]
343    fn drop(&mut self) {
344        unsafe {
345            self.ptr.drop::<T>();
346        }
347    }
348}
349
350pub mod kind;
351
352#[cfg(feature = "serde")]
353pub mod serde {
354    use super::*;
355    use ::serde::de::{Deserialize, Deserializer};
356    use ::serde::ser::{Serialize, Serializer};
357
358    impl<T, P> Serialize for SharedPointer<T, P>
359    where
360        T: Serialize,
361        P: SharedPointerKind,
362    {
363        fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
364            self.as_ref().serialize(serializer)
365        }
366    }
367
368    impl<'de, T, P> Deserialize<'de> for SharedPointer<T, P>
369    where
370        T: Deserialize<'de>,
371        P: SharedPointerKind,
372    {
373        fn deserialize<D: Deserializer<'de>>(
374            deserializer: D,
375        ) -> Result<SharedPointer<T, P>, D::Error> {
376            T::deserialize(deserializer).map(SharedPointer::new)
377        }
378    }
379}
380
381#[cfg(test)]
382mod test;