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