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