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}