Skip to main content

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