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}