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/// # Example
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]
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]
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]
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    #[inline]
104    pub fn as_arc(&self) -> &Arc<AtomicCount> {
105        &self.inner
106    }
107
108    /// Consumes this wrapper and returns the underlying [`Arc`].
109    ///
110    /// # Returns
111    ///
112    /// The underlying `Arc<AtomicCount>`.
113    #[inline]
114    pub fn into_arc(self) -> Arc<AtomicCount> {
115        self.inner
116    }
117
118    /// Returns the number of strong [`Arc`] owners.
119    ///
120    /// # Returns
121    ///
122    /// The current strong reference count of the shared counter.
123    #[inline]
124    pub fn strong_count(&self) -> usize {
125        Arc::strong_count(&self.inner)
126    }
127}
128
129impl Clone for ArcAtomicCount {
130    /// Clones the shared owner handle.
131    ///
132    /// # Returns
133    ///
134    /// A new wrapper pointing to the same underlying atomic counter.
135    #[inline]
136    fn clone(&self) -> Self {
137        Self {
138            inner: Arc::clone(&self.inner),
139        }
140    }
141}
142
143impl Default for ArcAtomicCount {
144    /// Creates a zero-valued shared atomic counter.
145    ///
146    /// # Returns
147    ///
148    /// A shared counter wrapper whose current value is zero.
149    #[inline]
150    fn default() -> Self {
151        Self::zero()
152    }
153}
154
155impl Deref for ArcAtomicCount {
156    type Target = AtomicCount;
157
158    /// Dereferences to the underlying [`AtomicCount`].
159    ///
160    /// # Returns
161    ///
162    /// A shared reference to the atomic counter.
163    #[inline]
164    fn deref(&self) -> &Self::Target {
165        self.inner.as_ref()
166    }
167}
168
169impl From<usize> for ArcAtomicCount {
170    /// Converts an initial counter value into a shared atomic counter.
171    ///
172    /// # Parameters
173    ///
174    /// * `value` - The initial counter value.
175    ///
176    /// # Returns
177    ///
178    /// A shared counter wrapper initialized to `value`.
179    #[inline]
180    fn from(value: usize) -> Self {
181        Self::new(value)
182    }
183}
184
185impl From<AtomicCount> for ArcAtomicCount {
186    /// Converts an atomic counter into a shared atomic counter wrapper.
187    ///
188    /// # Parameters
189    ///
190    /// * `counter` - The counter container to share.
191    ///
192    /// # Returns
193    ///
194    /// A shared counter wrapper owning `counter`.
195    #[inline]
196    fn from(counter: AtomicCount) -> Self {
197        Self::from_count(counter)
198    }
199}
200
201impl From<Arc<AtomicCount>> for ArcAtomicCount {
202    /// Converts an existing shared atomic counter into its wrapper.
203    ///
204    /// # Parameters
205    ///
206    /// * `inner` - The shared atomic counter to wrap.
207    ///
208    /// # Returns
209    ///
210    /// A wrapper around `inner`.
211    #[inline]
212    fn from(inner: Arc<AtomicCount>) -> Self {
213        Self::from_arc(inner)
214    }
215}
216
217impl fmt::Debug for ArcAtomicCount {
218    /// Formats the current counter value and sharing state for debugging.
219    ///
220    /// # Parameters
221    ///
222    /// * `f` - The formatter receiving the debug representation.
223    ///
224    /// # Returns
225    ///
226    /// A formatting result from the formatter.
227    #[inline]
228    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229        f.debug_struct("ArcAtomicCount")
230            .field("value", &self.get())
231            .field("strong_count", &self.strong_count())
232            .finish()
233    }
234}
235
236impl fmt::Display for ArcAtomicCount {
237    /// Formats the current counter value with decimal display formatting.
238    ///
239    /// # Parameters
240    ///
241    /// * `f` - The formatter receiving the displayed value.
242    ///
243    /// # Returns
244    ///
245    /// A formatting result from the formatter.
246    #[inline]
247    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
248        write!(f, "{}", self.get())
249    }
250}