Skip to main content

qubit_atomic/atomic/
arc_atomic_count.rs

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