Skip to main content

qubit_atomic/atomic/
arc_atomic_ref.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9
10//! # Shared Atomic Reference Wrapper
11//!
12//! Provides [`ArcAtomicRef<T>`], a convenience wrapper around
13//! `Arc<AtomicRef<T>>`.
14//!
15//! # Author
16//!
17//! Haixing Hu
18
19use std::fmt;
20use std::ops::Deref;
21use std::sync::Arc;
22
23use super::atomic_ref::AtomicRef;
24
25/// Shared-owner wrapper around [`AtomicRef<T>`].
26///
27/// This type is a convenience newtype for `Arc<AtomicRef<T>>`. Cloning an
28/// [`ArcAtomicRef`] clones the shared owner handle, so all clones operate on
29/// the same atomic reference container.
30///
31/// This is different from [`AtomicRef::clone`], which creates a new independent
32/// atomic container that initially points to the same value.
33///
34/// # Example
35///
36/// ```rust
37/// use qubit_atomic::ArcAtomicRef;
38/// use std::sync::Arc;
39///
40/// let config = ArcAtomicRef::from_value(10);
41/// let shared = config.clone();
42///
43/// shared.store(Arc::new(20));
44/// assert_eq!(*config.load(), 20);
45/// assert_eq!(config.strong_count(), 2);
46/// ```
47pub struct ArcAtomicRef<T> {
48    /// Shared owner of the underlying atomic reference container.
49    inner: Arc<AtomicRef<T>>,
50}
51
52impl<T> ArcAtomicRef<T> {
53    /// Creates a new shared atomic reference from an [`Arc<T>`].
54    ///
55    /// # Parameters
56    ///
57    /// * `value` - The initial shared value stored in the atomic reference.
58    ///
59    /// # Returns
60    ///
61    /// A shared atomic reference wrapper initialized to `value`.
62    #[inline]
63    pub fn new(value: Arc<T>) -> Self {
64        Self::from_atomic_ref(AtomicRef::new(value))
65    }
66
67    /// Creates a new shared atomic reference from an owned value.
68    ///
69    /// # Parameters
70    ///
71    /// * `value` - The owned value to store as the initial reference.
72    ///
73    /// # Returns
74    ///
75    /// A shared atomic reference wrapper initialized to `Arc::new(value)`.
76    #[inline]
77    pub fn from_value(value: T) -> Self {
78        Self::from_atomic_ref(AtomicRef::from_value(value))
79    }
80
81    /// Wraps an existing [`AtomicRef<T>`] in an [`Arc`].
82    ///
83    /// # Parameters
84    ///
85    /// * `atomic_ref` - The atomic reference container to share.
86    ///
87    /// # Returns
88    ///
89    /// A shared atomic reference wrapper owning `atomic_ref`.
90    #[inline]
91    pub fn from_atomic_ref(atomic_ref: AtomicRef<T>) -> Self {
92        Self {
93            inner: Arc::new(atomic_ref),
94        }
95    }
96
97    /// Wraps an existing shared atomic reference container.
98    ///
99    /// # Parameters
100    ///
101    /// * `inner` - The shared atomic reference container to wrap.
102    ///
103    /// # Returns
104    ///
105    /// A wrapper around `inner`.
106    #[inline]
107    pub fn from_arc(inner: Arc<AtomicRef<T>>) -> Self {
108        Self { inner }
109    }
110
111    /// Returns the underlying [`Arc`] without cloning it.
112    ///
113    /// # Returns
114    ///
115    /// A shared reference to the underlying `Arc<AtomicRef<T>>`.
116    #[inline]
117    pub fn as_arc(&self) -> &Arc<AtomicRef<T>> {
118        &self.inner
119    }
120
121    /// Consumes this wrapper and returns the underlying [`Arc`].
122    ///
123    /// # Returns
124    ///
125    /// The underlying `Arc<AtomicRef<T>>`.
126    #[inline]
127    pub fn into_arc(self) -> Arc<AtomicRef<T>> {
128        self.inner
129    }
130
131    /// Returns the number of strong [`Arc`] owners.
132    ///
133    /// # Returns
134    ///
135    /// The current strong reference count of the shared atomic reference
136    /// container.
137    #[inline]
138    pub fn strong_count(&self) -> usize {
139        Arc::strong_count(&self.inner)
140    }
141}
142
143impl<T> Clone for ArcAtomicRef<T> {
144    /// Clones the shared owner handle.
145    ///
146    /// # Returns
147    ///
148    /// A new wrapper pointing to the same underlying atomic reference
149    /// container.
150    #[inline]
151    fn clone(&self) -> Self {
152        Self {
153            inner: Arc::clone(&self.inner),
154        }
155    }
156}
157
158impl<T> Deref for ArcAtomicRef<T> {
159    type Target = AtomicRef<T>;
160
161    /// Dereferences to the underlying [`AtomicRef<T>`].
162    ///
163    /// # Returns
164    ///
165    /// A shared reference to the atomic reference container.
166    #[inline]
167    fn deref(&self) -> &Self::Target {
168        self.inner.as_ref()
169    }
170}
171
172impl<T> From<AtomicRef<T>> for ArcAtomicRef<T> {
173    /// Converts an atomic reference container into a shared wrapper.
174    ///
175    /// # Parameters
176    ///
177    /// * `atomic_ref` - The atomic reference container to share.
178    ///
179    /// # Returns
180    ///
181    /// A shared atomic reference wrapper owning `atomic_ref`.
182    #[inline]
183    fn from(atomic_ref: AtomicRef<T>) -> Self {
184        Self::from_atomic_ref(atomic_ref)
185    }
186}
187
188impl<T> From<Arc<AtomicRef<T>>> for ArcAtomicRef<T> {
189    /// Converts an existing shared atomic reference container into its wrapper.
190    ///
191    /// # Parameters
192    ///
193    /// * `inner` - The shared atomic reference container to wrap.
194    ///
195    /// # Returns
196    ///
197    /// A wrapper around `inner`.
198    #[inline]
199    fn from(inner: Arc<AtomicRef<T>>) -> Self {
200        Self::from_arc(inner)
201    }
202}
203
204impl<T: fmt::Debug> fmt::Debug for ArcAtomicRef<T> {
205    /// Formats the currently loaded reference and sharing state for debugging.
206    ///
207    /// # Parameters
208    ///
209    /// * `f` - The formatter receiving the debug representation.
210    ///
211    /// # Returns
212    ///
213    /// A formatting result from the formatter.
214    #[inline]
215    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216        f.debug_struct("ArcAtomicRef")
217            .field("value", &self.load())
218            .field("strong_count", &self.strong_count())
219            .finish()
220    }
221}
222
223impl<T: fmt::Display> fmt::Display for ArcAtomicRef<T> {
224    /// Formats the currently loaded reference with display formatting.
225    ///
226    /// # Parameters
227    ///
228    /// * `f` - The formatter receiving the displayed value.
229    ///
230    /// # Returns
231    ///
232    /// A formatting result from the formatter.
233    #[inline]
234    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235        write!(f, "{}", self.load())
236    }
237}