Skip to main content

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