Skip to main content

qubit_atomic/atomic/
arc_atomic_count.rs

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