fallacy_arc/
arc.rs

1//! A thread-safe reference-counting pointer.
2
3use crate::Weak;
4use fallacy_alloc::AllocError;
5use std::alloc::Layout;
6use std::fmt;
7use std::hash::Hash;
8use std::ops::Deref;
9use std::sync::Arc as StdArc;
10
11/// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically
12/// Reference Counted'.
13///
14/// The type `Arc<T>` provides shared ownership cod
15/// of a value of type `T`,
16/// allocated in the heap. Invoking `clone` on `Arc` produces
17/// a new `Arc` instance, which points to the same allocation on the heap as the
18/// source `Arc`, while increasing a reference count. When the last `Arc`
19/// pointer to a given allocation is destroyed, the value stored in that allocation (often
20/// referred to as "inner value") is also dropped.
21#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
22#[repr(transparent)]
23pub struct Arc<T: ?Sized>(StdArc<T>);
24
25impl<T> Arc<T> {
26    /// Constructs a new `Arc<T>`, returning an error if allocation fails.
27    #[inline]
28    pub fn try_new(data: T) -> Result<Arc<T>, AllocError> {
29        Ok(Arc(
30            StdArc::try_new(data).map_err(|_| AllocError::new(Layout::new::<T>()))?
31        ))
32    }
33}
34
35impl<T: ?Sized> Arc<T> {
36    #[inline]
37    pub fn into_std(self) -> StdArc<T> {
38        self.0
39    }
40
41    #[inline]
42    pub fn from_std(a: StdArc<T>) -> Self {
43        Arc(a)
44    }
45
46    /// Creates a new [`Weak`] pointer to this allocation.
47    #[must_use = "this returns a new `Weak` pointer, \
48                  without modifying the original `Arc`"]
49    #[inline]
50    pub fn downgrade(this: &Self) -> Weak<T> {
51        Weak::from_std(StdArc::downgrade(&this.0))
52    }
53
54    /// Gets the number of [`Weak`] pointers to this allocation.
55    ///
56    /// # Safety
57    ///
58    /// This method by itself is safe, but using it correctly requires extra care.
59    /// Another thread can change the weak count at any time,
60    /// including potentially between calling this method and acting on the result.
61    #[must_use]
62    #[inline]
63    pub fn weak_count(this: &Self) -> usize {
64        StdArc::weak_count(&this.0)
65    }
66
67    /// Gets the number of strong (`Arc`) pointers to this allocation.
68    ///
69    /// # Safety
70    ///
71    /// This method by itself is safe, but using it correctly requires extra care.
72    /// Another thread can change the strong count at any time,
73    /// including potentially between calling this method and acting on the result.
74    #[must_use]
75    #[inline]
76    pub fn strong_count(this: &Self) -> usize {
77        StdArc::strong_count(&this.0)
78    }
79
80    /// Returns `true` if the two `Arc`s point to the same allocation
81    /// (in a vein similar to [`std::ptr::eq`]).
82    #[must_use]
83    #[inline]
84    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
85        StdArc::ptr_eq(&this.0, &other.0)
86    }
87}
88
89impl<T: ?Sized> Deref for Arc<T> {
90    type Target = T;
91
92    #[inline]
93    fn deref(&self) -> &T {
94        self.0.deref()
95    }
96}
97
98impl<T: ?Sized> AsRef<T> for Arc<T> {
99    #[inline]
100    fn as_ref(&self) -> &T {
101        self.0.as_ref()
102    }
103}
104
105impl<T: ?Sized + fmt::Display> fmt::Display for Arc<T> {
106    #[inline]
107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108        fmt::Display::fmt(&self.0, f)
109    }
110}
111
112impl<T: ?Sized + fmt::Debug> fmt::Debug for Arc<T> {
113    #[inline]
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        fmt::Debug::fmt(&self.0, f)
116    }
117}
118
119impl<T: ?Sized> fmt::Pointer for Arc<T> {
120    #[inline]
121    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122        fmt::Pointer::fmt(&self.0, f)
123    }
124}
125
126#[cfg(feature = "serde")]
127mod serde {
128    use crate::Arc;
129    use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
130
131    impl<T> Serialize for Arc<T>
132    where
133        T: ?Sized + Serialize,
134    {
135        #[inline]
136        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
137        where
138            S: Serializer,
139        {
140            (**self).serialize(serializer)
141        }
142    }
143
144    impl<'de, T> Deserialize<'de> for Arc<T>
145    where
146        T: Deserialize<'de>,
147    {
148        #[inline]
149        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
150        where
151            D: Deserializer<'de>,
152        {
153            let val = Deserialize::deserialize(deserializer)?;
154            Arc::try_new(val).map_err(D::Error::custom)
155        }
156    }
157}