Skip to main content

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