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}