Skip to main content

qubit_atomic/atomic/
atomic.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//! # Generic Atomic Wrapper
12//!
13//! Provides the public [`Atomic<T>`] wrapper for supported primitive values.
14//!
15
16use std::{
17    fmt,
18    sync::atomic::Ordering,
19};
20
21use super::atomic_integer_value::AtomicIntegerValue;
22use super::atomic_number_ops::AtomicNumberOps;
23use super::atomic_ops::AtomicOps;
24use super::atomic_value::AtomicValue;
25
26/// A high-level atomic wrapper for supported primitive value types.
27///
28/// This type is the main entry point for primitive atomic values. It hides
29/// explicit memory-ordering parameters behind crate-defined defaults while
30/// still exposing the raw backend through [`inner`](Self::inner) for advanced
31/// use cases.
32///
33/// Supported value types are:
34///
35/// - `bool`
36/// - `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`
37/// - `usize`, `isize`
38/// - `f32`, `f64`
39///
40/// The `i128` and `u128` specializations use `portable-atomic` internally
41/// because the corresponding standard-library atomic types are not yet stable.
42///
43/// # Specialization API
44///
45/// Rustdoc documents [`Atomic<T>`] as one generic type rather than generating a
46/// separate page for each concrete `T`. The following table summarizes the
47/// methods available for each specialization:
48///
49/// | Specialization | Additional methods |
50/// | --- | --- |
51/// | `Atomic<bool>` | `fetch_set`, `fetch_clear`, `fetch_not`, `fetch_and`, `fetch_or`, `fetch_xor`, `set_if_false`, `set_if_true` |
52/// | `Atomic<i8>`, `Atomic<i16>`, `Atomic<i32>`, `Atomic<i64>`, `Atomic<i128>`, `Atomic<isize>` | `fetch_add`, `fetch_sub`, `fetch_mul`, `fetch_div`, `fetch_inc`, `fetch_dec`, `fetch_*_with_ordering`, `fetch_and`, `fetch_or`, `fetch_xor`, `fetch_not`, `fetch_accumulate`, `accumulate_and_get`, `fetch_max`, `fetch_min` |
53/// | `Atomic<u8>`, `Atomic<u16>`, `Atomic<u32>`, `Atomic<u64>`, `Atomic<u128>`, `Atomic<usize>` | `fetch_add`, `fetch_sub`, `fetch_mul`, `fetch_div`, `fetch_inc`, `fetch_dec`, `fetch_*_with_ordering`, `fetch_and`, `fetch_or`, `fetch_xor`, `fetch_not`, `fetch_accumulate`, `accumulate_and_get`, `fetch_max`, `fetch_min` |
54/// | `Atomic<f32>`, `Atomic<f64>` | `fetch_add`, `fetch_sub`, `fetch_mul`, `fetch_div` |
55///
56/// All supported specializations also provide [`new`](Self::new),
57/// [`load`](Self::load), [`store`](Self::store), [`swap`](Self::swap),
58/// [`compare_set`](Self::compare_set),
59/// [`compare_set_weak`](Self::compare_set_weak),
60/// [`compare_and_exchange`](Self::compare_and_exchange),
61/// [`fetch_update`](Self::fetch_update),
62/// [`update_and_get`](Self::update_and_get),
63/// [`try_update`](Self::try_update),
64/// [`try_update_and_get`](Self::try_update_and_get), and
65/// [`inner`](Self::inner).
66///
67/// Integer arithmetic operations intentionally follow Rust atomic integer
68/// semantics and wrap on overflow and underflow. Use [`crate::AtomicCount`] or
69/// [`crate::AtomicSignedCount`] when overflow or underflow must be rejected
70/// instead of wrapping.
71///
72/// Floating-point compare-and-set/exchange operations compare raw
73/// [`to_bits`](f32::to_bits) representations, not [`PartialEq`]. This means
74/// distinct bit patterns that compare equal, such as `0.0` and `-0.0`, do not
75/// match for CAS, and NaN payloads must match exactly. Prefer
76/// [`compare_set`](Self::compare_set) or [`compare_set_weak`](Self::compare_set_weak)
77/// when the caller needs an explicit success indicator for `f32` or `f64`.
78///
79/// # Example
80///
81/// ```rust
82/// use qubit_atomic::Atomic;
83///
84/// let counter = Atomic::new(0);
85/// counter.fetch_inc();
86/// assert_eq!(counter.load(), 1);
87///
88/// let flag = Atomic::new(false);
89/// assert_eq!(flag.fetch_set(), false);
90/// assert!(flag.load());
91/// ```
92///
93/// When the value type is ambiguous (for example integer literals), specify
94/// `T` explicitly with a [turbofish] on the constructor, or by annotating the
95/// binding:
96///
97/// ```rust
98/// use qubit_atomic::Atomic;
99///
100/// let wide: Atomic<u64> = Atomic::new(0);
101/// assert_eq!(wide.load(), 0u64);
102///
103/// let narrow = Atomic::<i16>::new(0);
104/// assert_eq!(narrow.load(), 0i16);
105/// ```
106///
107/// [turbofish]: https://doc.rust-lang.org/book/appendix-02-operators.html#the-turbofish
108///
109#[doc(alias = "AtomicBool")]
110#[doc(alias = "AtomicI8")]
111#[doc(alias = "AtomicU8")]
112#[doc(alias = "AtomicI16")]
113#[doc(alias = "AtomicU16")]
114#[doc(alias = "AtomicI32")]
115#[doc(alias = "AtomicU32")]
116#[doc(alias = "AtomicI64")]
117#[doc(alias = "AtomicU64")]
118#[doc(alias = "AtomicI128")]
119#[doc(alias = "AtomicU128")]
120#[doc(alias = "AtomicIsize")]
121#[doc(alias = "AtomicUsize")]
122#[doc(alias = "AtomicF32")]
123#[doc(alias = "AtomicF64")]
124#[repr(transparent)]
125pub struct Atomic<T>
126where
127    T: AtomicValue,
128{
129    /// Primitive backend that performs the concrete atomic operations for `T`.
130    primitive: T::Primitive,
131}
132
133impl<T> Atomic<T>
134where
135    T: AtomicValue,
136{
137    /// Creates a new atomic value.
138    ///
139    /// # Parameters
140    ///
141    /// * `value` - The initial value.
142    ///
143    /// # Returns
144    ///
145    /// An atomic wrapper initialized to `value`.
146    ///
147    /// # Example
148    ///
149    /// ```rust
150    /// use qubit_atomic::Atomic;
151    ///
152    /// let atomic = Atomic::new(42);
153    /// assert_eq!(atomic.load(), 42);
154    /// ```
155    ///
156    /// To pick a concrete `T` when inference would be ambiguous (for example
157    /// `0` as `u64` vs `i32`), write `Atomic::<T>::new(...)` (turbofish) or add
158    /// a type annotation on the binding (for example `let x: Atomic<u64> = ...`):
159    ///
160    /// ```rust
161    /// use qubit_atomic::Atomic;
162    ///
163    /// let a = Atomic::<u64>::new(0);
164    /// assert_eq!(a.load(), 0u64);
165    ///
166    /// let b: Atomic<isize> = Atomic::new(0);
167    /// assert_eq!(b.load(), 0isize);
168    /// ```
169    #[inline]
170    pub fn new(value: T) -> Self {
171        Self {
172            primitive: T::new_primitive(value),
173        }
174    }
175
176    /// Loads the current value.
177    ///
178    /// Uses `Acquire` ordering by default.
179    ///
180    /// # Returns
181    ///
182    /// The current value.
183    ///
184    /// # Example
185    ///
186    /// ```rust
187    /// use qubit_atomic::Atomic;
188    ///
189    /// let atomic = Atomic::new(7);
190    /// assert_eq!(atomic.load(), 7);
191    /// ```
192    #[inline]
193    pub fn load(&self) -> T {
194        AtomicOps::load(&self.primitive)
195    }
196
197    /// Stores a new value.
198    ///
199    /// Uses `Release` ordering by default.
200    ///
201    /// # Parameters
202    ///
203    /// * `value` - The new value to store.
204    ///
205    /// # Example
206    ///
207    /// ```rust
208    /// use qubit_atomic::Atomic;
209    ///
210    /// let atomic = Atomic::new(1);
211    /// atomic.store(2);
212    /// assert_eq!(atomic.load(), 2);
213    /// ```
214    #[inline]
215    pub fn store(&self, value: T) {
216        AtomicOps::store(&self.primitive, value);
217    }
218
219    /// Swaps the current value with `value`.
220    ///
221    /// Unlike [`store`](Self::store), this returns the value that was in the
222    /// atomic immediately before the swap, in the same atomic step. Use
223    /// [`store`](Self::store) when you do not need the previous value.
224    ///
225    /// Uses `AcqRel` ordering by default.
226    ///
227    /// # Parameters
228    ///
229    /// * `value` - The new value to store.
230    ///
231    /// # Returns
232    ///
233    /// The previous value.
234    ///
235    /// # Example
236    ///
237    /// ```rust
238    /// use qubit_atomic::Atomic;
239    ///
240    /// let a = Atomic::new(100);
241    /// a.store(200);
242    /// // store has no return value; you only see the new value via load().
243    /// assert_eq!(a.load(), 200);
244    ///
245    /// let b = Atomic::new(100);
246    /// // swap returns the old value and installs the new one atomically.
247    /// assert_eq!(b.swap(200), 100);
248    /// assert_eq!(b.load(), 200);
249    /// ```
250    #[inline]
251    pub fn swap(&self, value: T) -> T {
252        AtomicOps::swap(&self.primitive, value)
253    }
254
255    /// Compares the current value with `current` and stores `new` on match.
256    ///
257    /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
258    ///
259    /// # Parameters
260    ///
261    /// * `current` - The expected current value.
262    /// * `new` - The replacement value to store when the comparison matches.
263    ///
264    /// # Returns
265    ///
266    /// `Ok(())` when the value was replaced.
267    ///
268    /// # Errors
269    ///
270    /// Returns `Err(actual)` with the observed value when the comparison
271    /// fails. In that case, `new` is not stored.
272    ///
273    /// # Example
274    ///
275    /// ```rust
276    /// use qubit_atomic::Atomic;
277    ///
278    /// let atomic = Atomic::new(1);
279    /// assert!(atomic.compare_set(1, 2).is_ok());
280    /// assert_eq!(atomic.load(), 2);
281    /// assert_eq!(atomic.compare_set(1, 3), Err(2));
282    /// ```
283    #[inline]
284    pub fn compare_set(&self, current: T, new: T) -> Result<(), T> {
285        AtomicOps::compare_set(&self.primitive, current, new)
286    }
287
288    /// Weak version of [`compare_set`](Self::compare_set).
289    ///
290    /// This operation may fail spuriously and is intended for retry loops.
291    ///
292    /// # Parameters
293    ///
294    /// * `current` - The expected current value.
295    /// * `new` - The replacement value to store when the comparison matches.
296    ///
297    /// # Returns
298    ///
299    /// `Ok(())` when the value was replaced.
300    ///
301    /// # Errors
302    ///
303    /// Returns `Err(actual)` with the observed value when the comparison
304    /// fails, including possible spurious failures. In that case, `new` is not
305    /// stored.
306    ///
307    /// # Example
308    ///
309    /// ```rust
310    /// use qubit_atomic::Atomic;
311    ///
312    /// let atomic = Atomic::new(1);
313    /// loop {
314    ///     match atomic.compare_set_weak(1, 2) {
315    ///         Ok(()) => break,
316    ///         Err(actual) => assert_eq!(actual, 1),
317    ///     }
318    /// }
319    /// assert_eq!(atomic.load(), 2);
320    /// ```
321    #[inline]
322    pub fn compare_set_weak(&self, current: T, new: T) -> Result<(), T> {
323        AtomicOps::compare_set_weak(&self.primitive, current, new)
324    }
325
326    /// Compares and exchanges the value, returning the value seen before the
327    /// operation.
328    ///
329    /// If the return value equals `current`, the exchange succeeded.
330    ///
331    /// # Parameters
332    ///
333    /// * `current` - The expected current value.
334    /// * `new` - The replacement value to store when the comparison matches.
335    ///
336    /// # Returns
337    ///
338    /// The value observed before the operation completed. If the returned
339    /// value equals `current`, the exchange succeeded; otherwise it is the
340    /// actual value that prevented the exchange.
341    ///
342    /// For `Atomic<f32>` and `Atomic<f64>`, CAS compares raw IEEE-754 bit
343    /// patterns rather than [`PartialEq`]. A returned floating-point value
344    /// comparing equal to `current` is therefore not always enough to prove
345    /// success; use [`compare_set`](Self::compare_set) for an explicit
346    /// `Ok`/`Err`, or compare [`to_bits`](f32::to_bits) values yourself.
347    ///
348    /// # Example
349    ///
350    /// ```rust
351    /// use qubit_atomic::Atomic;
352    ///
353    /// let atomic = Atomic::new(5);
354    /// assert_eq!(atomic.compare_and_exchange(5, 10), 5);
355    /// assert_eq!(atomic.load(), 10);
356    /// assert_eq!(atomic.compare_and_exchange(5, 0), 10);
357    /// ```
358    #[inline]
359    pub fn compare_and_exchange(&self, current: T, new: T) -> T {
360        AtomicOps::compare_exchange(&self.primitive, current, new)
361    }
362
363    /// Weak version of [`compare_and_exchange`](Self::compare_and_exchange).
364    ///
365    /// This operation may fail spuriously and is intended for retry loops.
366    ///
367    /// # Parameters
368    ///
369    /// * `current` - The expected current value.
370    /// * `new` - The replacement value to store when the comparison matches.
371    ///
372    /// # Returns
373    ///
374    /// `Ok(previous)` when the value was replaced, or `Err(actual)` when the
375    /// comparison failed, including possible spurious failure.
376    ///
377    /// For `Atomic<f32>` and `Atomic<f64>`, the same caveat applies to raw-bit
378    /// equality: `0.0` and `-0.0` compare equal by [`PartialEq`] but are
379    /// different CAS values. Use [`compare_set_weak`](Self::compare_set_weak)
380    /// or compare [`to_bits`](f32::to_bits) values when distinguishing success
381    /// from failure matters.
382    ///
383    /// # Example
384    ///
385    /// Weak CAS may fail spuriously; retry on `Err(actual)`.
386    ///
387    /// ```rust
388    /// use qubit_atomic::Atomic;
389    ///
390    /// let atomic = Atomic::new(5);
391    /// let mut current = 5;
392    /// loop {
393    ///     match atomic.compare_and_exchange_weak(current, 10) {
394    ///         Ok(previous) => {
395    ///             assert_eq!(previous, current);
396    ///             break;
397    ///         }
398    ///         Err(actual) => current = actual,
399    ///     }
400    /// }
401    /// assert_eq!(atomic.load(), 10);
402    /// ```
403    #[inline]
404    pub fn compare_and_exchange_weak(&self, current: T, new: T) -> Result<T, T> {
405        AtomicOps::compare_exchange_weak(&self.primitive, current, new)
406    }
407
408    /// Updates the value with a function and returns the previous value.
409    ///
410    /// The update uses a CAS loop until it succeeds. The closure may be called
411    /// more than once under contention.
412    ///
413    /// # Parameters
414    ///
415    /// * `f` - A function that maps the current value to the next value.
416    ///
417    /// # Returns
418    ///
419    /// The value before the successful update.
420    ///
421    /// # Example
422    ///
423    /// ```rust
424    /// use qubit_atomic::Atomic;
425    ///
426    /// let atomic = Atomic::new(3);
427    /// assert_eq!(atomic.fetch_update(|x| x * 2), 3);
428    /// assert_eq!(atomic.load(), 6);
429    /// ```
430    #[inline]
431    pub fn fetch_update<F>(&self, f: F) -> T
432    where
433        F: FnMut(T) -> T,
434    {
435        AtomicOps::fetch_update(&self.primitive, f)
436    }
437
438    /// Updates the value with a function and returns the new value.
439    ///
440    /// The update uses a CAS loop until it succeeds. The closure may be called
441    /// more than once under contention.
442    ///
443    /// # Parameters
444    ///
445    /// * `f` - A function that maps the current value to the next value.
446    ///
447    /// # Returns
448    ///
449    /// The value committed by the successful update.
450    ///
451    /// # Example
452    ///
453    /// ```rust
454    /// use qubit_atomic::Atomic;
455    ///
456    /// let atomic = Atomic::new(3);
457    /// assert_eq!(atomic.update_and_get(|x| x * 2), 6);
458    /// assert_eq!(atomic.load(), 6);
459    /// ```
460    #[inline]
461    pub fn update_and_get<F>(&self, f: F) -> T
462    where
463        F: FnMut(T) -> T,
464    {
465        AtomicOps::update_and_get(&self.primitive, f)
466    }
467
468    /// Conditionally updates the value with a function.
469    ///
470    /// The update uses a CAS loop until it succeeds or the closure rejects the
471    /// observed current value by returning `None`. The closure may be called
472    /// more than once under contention.
473    ///
474    /// # Parameters
475    ///
476    /// * `f` - A function that maps the current value to `Some(next)` to update
477    ///   the atomic, or `None` to leave it unchanged.
478    ///
479    /// # Returns
480    ///
481    /// `Some(old_value)` with the value before the successful update, or `None`
482    /// when `f` rejects the observed current value.
483    ///
484    /// # Example
485    ///
486    /// ```rust
487    /// use qubit_atomic::Atomic;
488    ///
489    /// let atomic = Atomic::new(3);
490    /// assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), Some(3));
491    /// assert_eq!(atomic.load(), 4);
492    /// assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), None);
493    /// assert_eq!(atomic.load(), 4);
494    /// ```
495    #[inline]
496    pub fn try_update<F>(&self, f: F) -> Option<T>
497    where
498        F: FnMut(T) -> Option<T>,
499    {
500        AtomicOps::try_update(&self.primitive, f)
501    }
502
503    /// Conditionally updates the value with a function and returns the new value.
504    ///
505    /// The update uses a CAS loop until it succeeds or the closure rejects the
506    /// observed current value by returning `None`. The closure may be called
507    /// more than once under contention.
508    ///
509    /// # Parameters
510    ///
511    /// * `f` - A function that maps the current value to `Some(next)` to update
512    ///   the atomic, or `None` to leave it unchanged.
513    ///
514    /// # Returns
515    ///
516    /// `Some(new_value)` with the value committed by the successful update, or
517    /// `None` when `f` rejects the observed current value.
518    ///
519    /// # Example
520    ///
521    /// ```rust
522    /// use qubit_atomic::Atomic;
523    ///
524    /// let atomic = Atomic::new(3);
525    /// assert_eq!(
526    ///     atomic.try_update_and_get(|x| (x % 2 == 1).then_some(x + 1)),
527    ///     Some(4),
528    /// );
529    /// assert_eq!(atomic.load(), 4);
530    /// assert_eq!(
531    ///     atomic.try_update_and_get(|x| (x % 2 == 1).then_some(x + 1)),
532    ///     None,
533    /// );
534    /// assert_eq!(atomic.load(), 4);
535    /// ```
536    #[inline]
537    pub fn try_update_and_get<F>(&self, f: F) -> Option<T>
538    where
539        F: FnMut(T) -> Option<T>,
540    {
541        AtomicOps::try_update_and_get(&self.primitive, f)
542    }
543
544    /// Returns the raw backend atomic value.
545    ///
546    /// Use this method only when the default orderings are not appropriate
547    /// and the caller needs direct access to the backend atomic storage.
548    ///
549    /// # Returns
550    ///
551    /// A shared reference to the raw backend atomic value.
552    ///
553    /// # Example
554    ///
555    /// ```rust
556    /// use qubit_atomic::Atomic;
557    /// use std::sync::atomic::Ordering;
558    ///
559    /// let atomic = Atomic::<i32>::new(0);
560    /// assert_eq!(atomic.inner().load(Ordering::Relaxed), 0);
561    /// ```
562    #[inline]
563    pub fn inner(&self) -> &T::Inner {
564        T::inner(&self.primitive)
565    }
566}
567
568impl<T> Atomic<T>
569where
570    T: AtomicValue,
571    T::Primitive: AtomicNumberOps<Value = T>,
572{
573    /// Adds `delta` to the value and returns the previous value.
574    ///
575    /// Integer atomics use relaxed ordering for this operation. Floating-point
576    /// atomics use a CAS loop. Integer addition wraps on overflow and
577    /// underflow.
578    ///
579    /// # Parameters
580    ///
581    /// * `delta` - The value to add.
582    ///
583    /// # Returns
584    ///
585    /// The value before the addition.
586    ///
587    /// # Example
588    ///
589    /// ```rust
590    /// use qubit_atomic::Atomic;
591    ///
592    /// let atomic = Atomic::new(10);
593    /// assert_eq!(atomic.fetch_add(3), 10);
594    /// assert_eq!(atomic.load(), 13);
595    /// ```
596    #[inline]
597    pub fn fetch_add(&self, delta: T) -> T {
598        AtomicNumberOps::fetch_add(&self.primitive, delta)
599    }
600
601    /// Subtracts `delta` from the value and returns the previous value.
602    ///
603    /// Integer atomics use relaxed ordering for this operation. Floating-point
604    /// atomics use a CAS loop. Integer subtraction wraps on overflow and
605    /// underflow.
606    ///
607    /// # Parameters
608    ///
609    /// * `delta` - The value to subtract.
610    ///
611    /// # Returns
612    ///
613    /// The value before the subtraction.
614    ///
615    /// # Example
616    ///
617    /// ```rust
618    /// use qubit_atomic::Atomic;
619    ///
620    /// let atomic = Atomic::new(10);
621    /// assert_eq!(atomic.fetch_sub(3), 10);
622    /// assert_eq!(atomic.load(), 7);
623    /// ```
624    #[inline]
625    pub fn fetch_sub(&self, delta: T) -> T {
626        AtomicNumberOps::fetch_sub(&self.primitive, delta)
627    }
628
629    /// Multiplies the value by `factor` and returns the previous value.
630    ///
631    /// This operation uses a CAS loop. Integer multiplication wraps on
632    /// overflow and underflow.
633    ///
634    /// # Parameters
635    ///
636    /// * `factor` - The value to multiply by.
637    ///
638    /// # Returns
639    ///
640    /// The value before the multiplication.
641    ///
642    /// # Example
643    ///
644    /// ```rust
645    /// use qubit_atomic::Atomic;
646    ///
647    /// let atomic = Atomic::new(3);
648    /// assert_eq!(atomic.fetch_mul(4), 3);
649    /// assert_eq!(atomic.load(), 12);
650    /// ```
651    #[inline]
652    pub fn fetch_mul(&self, factor: T) -> T {
653        AtomicNumberOps::fetch_mul(&self.primitive, factor)
654    }
655
656    /// Divides the value by `divisor` and returns the previous value.
657    ///
658    /// This operation uses a CAS loop. Integer division uses wrapping
659    /// semantics; for signed integers, `MIN / -1` wraps to `MIN`.
660    ///
661    /// # Parameters
662    ///
663    /// * `divisor` - The value to divide by.
664    ///
665    /// # Returns
666    ///
667    /// The value before the division.
668    ///
669    /// # Panics
670    ///
671    /// For integer specializations, panics if `divisor` is zero. Floating-point
672    /// specializations follow IEEE-754 division semantics and do not panic
673    /// solely because `divisor` is zero.
674    ///
675    /// # Example
676    ///
677    /// ```rust
678    /// use qubit_atomic::Atomic;
679    ///
680    /// let atomic = Atomic::new(20);
681    /// assert_eq!(atomic.fetch_div(4), 20);
682    /// assert_eq!(atomic.load(), 5);
683    /// ```
684    #[inline]
685    pub fn fetch_div(&self, divisor: T) -> T {
686        AtomicNumberOps::fetch_div(&self.primitive, divisor)
687    }
688}
689
690impl<T> Atomic<T>
691where
692    T: AtomicIntegerValue,
693{
694    /// Increments the value by one and returns the previous value.
695    ///
696    /// # Returns
697    ///
698    /// The value before the increment.
699    ///
700    /// # Example
701    ///
702    /// ```rust
703    /// use qubit_atomic::Atomic;
704    ///
705    /// let atomic = Atomic::new(0);
706    /// assert_eq!(atomic.fetch_inc(), 0);
707    /// assert_eq!(atomic.load(), 1);
708    /// ```
709    #[inline]
710    pub fn fetch_inc(&self) -> T {
711        T::fetch_inc(&self.primitive)
712    }
713
714    /// Increments the value by one with an explicit memory ordering and returns
715    /// the previous value.
716    ///
717    /// Arithmetic wraps on overflow, matching Rust atomic integer operations.
718    ///
719    /// # Parameters
720    ///
721    /// * `ordering` - The memory ordering used by the atomic read-modify-write
722    ///   operation.
723    ///
724    /// # Returns
725    ///
726    /// The value before the increment.
727    ///
728    /// # Example
729    ///
730    /// ```rust
731    /// use qubit_atomic::Atomic;
732    /// use std::sync::atomic::Ordering;
733    ///
734    /// let atomic = Atomic::new(0);
735    /// assert_eq!(atomic.fetch_inc_with_ordering(Ordering::AcqRel), 0);
736    /// assert_eq!(atomic.load(), 1);
737    /// ```
738    #[inline]
739    pub fn fetch_inc_with_ordering(&self, ordering: Ordering) -> T {
740        T::fetch_inc_with_ordering(&self.primitive, ordering)
741    }
742
743    /// Decrements the value by one and returns the previous value.
744    ///
745    /// # Returns
746    ///
747    /// The value before the decrement.
748    ///
749    /// # Example
750    ///
751    /// ```rust
752    /// use qubit_atomic::Atomic;
753    ///
754    /// let atomic = Atomic::new(1);
755    /// assert_eq!(atomic.fetch_dec(), 1);
756    /// assert_eq!(atomic.load(), 0);
757    /// ```
758    #[inline]
759    pub fn fetch_dec(&self) -> T {
760        T::fetch_dec(&self.primitive)
761    }
762
763    /// Decrements the value by one with an explicit memory ordering and returns
764    /// the previous value.
765    ///
766    /// Arithmetic wraps on underflow, matching Rust atomic integer operations.
767    ///
768    /// # Parameters
769    ///
770    /// * `ordering` - The memory ordering used by the atomic read-modify-write
771    ///   operation.
772    ///
773    /// # Returns
774    ///
775    /// The value before the decrement.
776    ///
777    /// # Example
778    ///
779    /// ```rust
780    /// use qubit_atomic::Atomic;
781    /// use std::sync::atomic::Ordering;
782    ///
783    /// let atomic = Atomic::new(1);
784    /// assert_eq!(atomic.fetch_dec_with_ordering(Ordering::AcqRel), 1);
785    /// assert_eq!(atomic.load(), 0);
786    /// ```
787    #[inline]
788    pub fn fetch_dec_with_ordering(&self, ordering: Ordering) -> T {
789        T::fetch_dec_with_ordering(&self.primitive, ordering)
790    }
791
792    /// Adds `delta` with an explicit memory ordering and returns the previous
793    /// value.
794    ///
795    /// Arithmetic wraps on overflow and underflow, matching Rust atomic integer
796    /// operations.
797    ///
798    /// # Parameters
799    ///
800    /// * `delta` - The value to add.
801    /// * `ordering` - The memory ordering used by the atomic read-modify-write
802    ///   operation.
803    ///
804    /// # Returns
805    ///
806    /// The value before the addition.
807    ///
808    /// # Example
809    ///
810    /// ```rust
811    /// use qubit_atomic::Atomic;
812    /// use std::sync::atomic::Ordering;
813    ///
814    /// let atomic = Atomic::new(10);
815    /// assert_eq!(atomic.fetch_add_with_ordering(5, Ordering::AcqRel), 10);
816    /// assert_eq!(atomic.load(), 15);
817    /// ```
818    #[inline]
819    pub fn fetch_add_with_ordering(&self, delta: T, ordering: Ordering) -> T {
820        T::fetch_add_with_ordering(&self.primitive, delta, ordering)
821    }
822
823    /// Subtracts `delta` with an explicit memory ordering and returns the
824    /// previous value.
825    ///
826    /// Arithmetic wraps on overflow and underflow, matching Rust atomic integer
827    /// operations.
828    ///
829    /// # Parameters
830    ///
831    /// * `delta` - The value to subtract.
832    /// * `ordering` - The memory ordering used by the atomic read-modify-write
833    ///   operation.
834    ///
835    /// # Returns
836    ///
837    /// The value before the subtraction.
838    ///
839    /// # Example
840    ///
841    /// ```rust
842    /// use qubit_atomic::Atomic;
843    /// use std::sync::atomic::Ordering;
844    ///
845    /// let atomic = Atomic::new(10);
846    /// assert_eq!(atomic.fetch_sub_with_ordering(3, Ordering::AcqRel), 10);
847    /// assert_eq!(atomic.load(), 7);
848    /// ```
849    #[inline]
850    pub fn fetch_sub_with_ordering(&self, delta: T, ordering: Ordering) -> T {
851        T::fetch_sub_with_ordering(&self.primitive, delta, ordering)
852    }
853
854    /// Applies bitwise AND and returns the previous value.
855    ///
856    /// # Parameters
857    ///
858    /// * `value` - The mask to apply.
859    ///
860    /// # Returns
861    ///
862    /// The value before the operation.
863    ///
864    /// # Example
865    ///
866    /// ```rust
867    /// use qubit_atomic::Atomic;
868    ///
869    /// let atomic = Atomic::<u8>::new(0b1111);
870    /// assert_eq!(atomic.fetch_and(0b1010), 0b1111);
871    /// assert_eq!(atomic.load(), 0b1010);
872    /// ```
873    #[inline]
874    pub fn fetch_and(&self, value: T) -> T {
875        T::fetch_and(&self.primitive, value)
876    }
877
878    /// Applies bitwise OR and returns the previous value.
879    ///
880    /// # Parameters
881    ///
882    /// * `value` - The mask to apply.
883    ///
884    /// # Returns
885    ///
886    /// The value before the operation.
887    ///
888    /// # Example
889    ///
890    /// ```rust
891    /// use qubit_atomic::Atomic;
892    ///
893    /// let atomic = Atomic::<u8>::new(0b1000);
894    /// assert_eq!(atomic.fetch_or(0b0011), 0b1000);
895    /// assert_eq!(atomic.load(), 0b1011);
896    /// ```
897    #[inline]
898    pub fn fetch_or(&self, value: T) -> T {
899        T::fetch_or(&self.primitive, value)
900    }
901
902    /// Applies bitwise XOR and returns the previous value.
903    ///
904    /// # Parameters
905    ///
906    /// * `value` - The mask to apply.
907    ///
908    /// # Returns
909    ///
910    /// The value before the operation.
911    ///
912    /// # Example
913    ///
914    /// ```rust
915    /// use qubit_atomic::Atomic;
916    ///
917    /// let atomic = Atomic::<u8>::new(0b1111);
918    /// assert_eq!(atomic.fetch_xor(0b1010), 0b1111);
919    /// assert_eq!(atomic.load(), 0b0101);
920    /// ```
921    #[inline]
922    pub fn fetch_xor(&self, value: T) -> T {
923        T::fetch_xor(&self.primitive, value)
924    }
925
926    /// Flips all bits and returns the previous value.
927    ///
928    /// # Returns
929    ///
930    /// The value before the operation.
931    ///
932    /// # Example
933    ///
934    /// ```rust
935    /// use qubit_atomic::Atomic;
936    ///
937    /// let atomic = Atomic::<i32>::new(0);
938    /// assert_eq!(atomic.fetch_not(), 0);
939    /// assert_eq!(atomic.load(), !0);
940    /// ```
941    #[inline]
942    pub fn fetch_not(&self) -> T {
943        T::fetch_not(&self.primitive)
944    }
945
946    /// Updates the value by accumulating it with `value`.
947    ///
948    /// # Parameters
949    ///
950    /// * `value` - The right-hand input to the accumulator.
951    /// * `f` - A function that combines the current value and `value`.
952    ///
953    /// # Returns
954    ///
955    /// The value before the successful update.
956    ///
957    /// The closure may be called more than once when concurrent updates cause
958    /// CAS retries.
959    ///
960    /// # Example
961    ///
962    /// ```rust
963    /// use qubit_atomic::Atomic;
964    ///
965    /// let atomic = Atomic::new(10);
966    /// assert_eq!(atomic.fetch_accumulate(5, |a, b| a + b), 10);
967    /// assert_eq!(atomic.load(), 15);
968    /// ```
969    #[inline]
970    pub fn fetch_accumulate<F>(&self, value: T, f: F) -> T
971    where
972        F: FnMut(T, T) -> T,
973    {
974        T::fetch_accumulate(&self.primitive, value, f)
975    }
976
977    /// Updates the value by accumulating it with `value` and returns the new value.
978    ///
979    /// # Parameters
980    ///
981    /// * `value` - The right-hand input to the accumulator.
982    /// * `f` - A function that combines the current value and `value`.
983    ///
984    /// # Returns
985    ///
986    /// The value committed by the successful update.
987    ///
988    /// The closure may be called more than once when concurrent updates cause
989    /// CAS retries.
990    ///
991    /// # Example
992    ///
993    /// ```rust
994    /// use qubit_atomic::Atomic;
995    ///
996    /// let atomic = Atomic::new(10);
997    /// assert_eq!(atomic.accumulate_and_get(5, |a, b| a + b), 15);
998    /// assert_eq!(atomic.load(), 15);
999    /// ```
1000    #[inline]
1001    pub fn accumulate_and_get<F>(&self, value: T, f: F) -> T
1002    where
1003        F: FnMut(T, T) -> T,
1004    {
1005        T::accumulate_and_get(&self.primitive, value, f)
1006    }
1007
1008    /// Replaces the value with the maximum of the current value and `value`.
1009    ///
1010    /// # Parameters
1011    ///
1012    /// * `value` - The value to compare with the current value.
1013    ///
1014    /// # Returns
1015    ///
1016    /// The value before the operation.
1017    ///
1018    /// # Example
1019    ///
1020    /// ```rust
1021    /// use qubit_atomic::Atomic;
1022    ///
1023    /// let atomic = Atomic::new(3);
1024    /// assert_eq!(atomic.fetch_max(10), 3);
1025    /// assert_eq!(atomic.load(), 10);
1026    /// ```
1027    #[inline]
1028    pub fn fetch_max(&self, value: T) -> T {
1029        T::fetch_max(&self.primitive, value)
1030    }
1031
1032    /// Replaces the value with the minimum of the current value and `value`.
1033    ///
1034    /// # Parameters
1035    ///
1036    /// * `value` - The value to compare with the current value.
1037    ///
1038    /// # Returns
1039    ///
1040    /// The value before the operation.
1041    ///
1042    /// # Example
1043    ///
1044    /// ```rust
1045    /// use qubit_atomic::Atomic;
1046    ///
1047    /// let atomic = Atomic::new(10);
1048    /// assert_eq!(atomic.fetch_min(3), 10);
1049    /// assert_eq!(atomic.load(), 3);
1050    /// ```
1051    #[inline]
1052    pub fn fetch_min(&self, value: T) -> T {
1053        T::fetch_min(&self.primitive, value)
1054    }
1055}
1056
1057impl Atomic<bool> {
1058    /// Stores `true` and returns the previous value.
1059    ///
1060    /// # Returns
1061    ///
1062    /// The previous value.
1063    ///
1064    /// # Example
1065    ///
1066    /// ```rust
1067    /// use qubit_atomic::Atomic;
1068    ///
1069    /// let flag = Atomic::new(false);
1070    /// assert_eq!(flag.fetch_set(), false);
1071    /// assert!(flag.load());
1072    /// ```
1073    #[inline]
1074    pub fn fetch_set(&self) -> bool {
1075        self.primitive.fetch_set()
1076    }
1077
1078    /// Stores `false` and returns the previous value.
1079    ///
1080    /// # Returns
1081    ///
1082    /// The previous value.
1083    ///
1084    /// # Example
1085    ///
1086    /// ```rust
1087    /// use qubit_atomic::Atomic;
1088    ///
1089    /// let flag = Atomic::new(true);
1090    /// assert_eq!(flag.fetch_clear(), true);
1091    /// assert!(!flag.load());
1092    /// ```
1093    #[inline]
1094    pub fn fetch_clear(&self) -> bool {
1095        self.primitive.fetch_clear()
1096    }
1097
1098    /// Negates the value and returns the previous value.
1099    ///
1100    /// # Returns
1101    ///
1102    /// The previous value.
1103    ///
1104    /// # Example
1105    ///
1106    /// ```rust
1107    /// use qubit_atomic::Atomic;
1108    ///
1109    /// let flag = Atomic::new(false);
1110    /// assert_eq!(flag.fetch_not(), false);
1111    /// assert!(flag.load());
1112    /// ```
1113    #[inline]
1114    pub fn fetch_not(&self) -> bool {
1115        self.primitive.fetch_not()
1116    }
1117
1118    /// Applies logical AND and returns the previous value.
1119    ///
1120    /// # Parameters
1121    ///
1122    /// * `value` - The value to combine with the current value.
1123    ///
1124    /// # Returns
1125    ///
1126    /// The previous value.
1127    ///
1128    /// # Example
1129    ///
1130    /// ```rust
1131    /// use qubit_atomic::Atomic;
1132    ///
1133    /// let flag = Atomic::new(true);
1134    /// assert_eq!(flag.fetch_and(false), true);
1135    /// assert!(!flag.load());
1136    /// ```
1137    #[inline]
1138    pub fn fetch_and(&self, value: bool) -> bool {
1139        self.primitive.fetch_and(value)
1140    }
1141
1142    /// Applies logical OR and returns the previous value.
1143    ///
1144    /// # Parameters
1145    ///
1146    /// * `value` - The value to combine with the current value.
1147    ///
1148    /// # Returns
1149    ///
1150    /// The previous value.
1151    ///
1152    /// # Example
1153    ///
1154    /// ```rust
1155    /// use qubit_atomic::Atomic;
1156    ///
1157    /// let flag = Atomic::new(false);
1158    /// assert_eq!(flag.fetch_or(true), false);
1159    /// assert!(flag.load());
1160    /// ```
1161    #[inline]
1162    pub fn fetch_or(&self, value: bool) -> bool {
1163        self.primitive.fetch_or(value)
1164    }
1165
1166    /// Applies logical XOR and returns the previous value.
1167    ///
1168    /// # Parameters
1169    ///
1170    /// * `value` - The value to combine with the current value.
1171    ///
1172    /// # Returns
1173    ///
1174    /// The previous value.
1175    ///
1176    /// # Example
1177    ///
1178    /// ```rust
1179    /// use qubit_atomic::Atomic;
1180    ///
1181    /// let flag = Atomic::new(true);
1182    /// assert_eq!(flag.fetch_xor(true), true);
1183    /// assert!(!flag.load());
1184    /// ```
1185    #[inline]
1186    pub fn fetch_xor(&self, value: bool) -> bool {
1187        self.primitive.fetch_xor(value)
1188    }
1189
1190    /// Stores `new` only when the current value is `false`.
1191    ///
1192    /// # Parameters
1193    ///
1194    /// * `new` - The replacement value.
1195    ///
1196    /// # Returns
1197    ///
1198    /// `Ok(())` if the value was replaced.
1199    ///
1200    /// # Errors
1201    ///
1202    /// Returns `Err(true)` if the observed current value was already `true`.
1203    /// In that case, `new` is not stored.
1204    ///
1205    /// # Example
1206    ///
1207    /// ```rust
1208    /// use qubit_atomic::Atomic;
1209    ///
1210    /// let flag = Atomic::new(false);
1211    /// assert!(flag.set_if_false(true).is_ok());
1212    /// assert!(flag.load());
1213    /// assert!(flag.set_if_false(false).is_err());
1214    /// ```
1215    #[inline]
1216    pub fn set_if_false(&self, new: bool) -> Result<(), bool> {
1217        self.primitive.set_if_false(new)
1218    }
1219
1220    /// Stores `new` only when the current value is `true`.
1221    ///
1222    /// # Parameters
1223    ///
1224    /// * `new` - The replacement value.
1225    ///
1226    /// # Returns
1227    ///
1228    /// `Ok(())` if the value was replaced.
1229    ///
1230    /// # Errors
1231    ///
1232    /// Returns `Err(false)` if the observed current value was already `false`.
1233    /// In that case, `new` is not stored.
1234    ///
1235    /// # Example
1236    ///
1237    /// ```rust
1238    /// use qubit_atomic::Atomic;
1239    ///
1240    /// let flag = Atomic::new(true);
1241    /// assert!(flag.set_if_true(false).is_ok());
1242    /// assert!(!flag.load());
1243    /// assert!(flag.set_if_true(true).is_err());
1244    /// ```
1245    #[inline]
1246    pub fn set_if_true(&self, new: bool) -> Result<(), bool> {
1247        self.primitive.set_if_true(new)
1248    }
1249}
1250
1251impl<T> Default for Atomic<T>
1252where
1253    T: AtomicValue + Default,
1254{
1255    /// Creates an atomic with [`Default::default`] as the initial value.
1256    ///
1257    /// # Example
1258    ///
1259    /// ```rust
1260    /// use qubit_atomic::Atomic;
1261    ///
1262    /// let atomic = Atomic::<i32>::default();
1263    /// assert_eq!(atomic.load(), 0);
1264    /// ```
1265    #[inline]
1266    fn default() -> Self {
1267        Self::new(T::default())
1268    }
1269}
1270
1271impl<T> From<T> for Atomic<T>
1272where
1273    T: AtomicValue,
1274{
1275    /// Converts `value` into an [`Atomic`] via [`Atomic::new`].
1276    ///
1277    /// # Example
1278    ///
1279    /// ```rust
1280    /// use qubit_atomic::Atomic;
1281    ///
1282    /// let atomic = Atomic::from(42i32);
1283    /// assert_eq!(atomic.load(), 42);
1284    /// ```
1285    #[inline]
1286    fn from(value: T) -> Self {
1287        Self::new(value)
1288    }
1289}
1290
1291impl<T> fmt::Debug for Atomic<T>
1292where
1293    T: AtomicValue + fmt::Debug,
1294{
1295    /// Formats the loaded value as `Atomic { value: ... }`.
1296    ///
1297    /// # Example
1298    ///
1299    /// ```rust
1300    /// use qubit_atomic::Atomic;
1301    ///
1302    /// let atomic = Atomic::new(7);
1303    /// assert!(format!("{:?}", atomic).contains("7"));
1304    /// ```
1305    #[inline]
1306    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1307        f.debug_struct("Atomic")
1308            .field("value", &self.load())
1309            .finish()
1310    }
1311}
1312
1313impl<T> fmt::Display for Atomic<T>
1314where
1315    T: AtomicValue + fmt::Display,
1316{
1317    /// Formats the loaded value using its [`Display`](fmt::Display) implementation.
1318    ///
1319    /// # Example
1320    ///
1321    /// ```rust
1322    /// use qubit_atomic::Atomic;
1323    ///
1324    /// let atomic = Atomic::new(42);
1325    /// assert_eq!(format!("{}", atomic), "42");
1326    /// ```
1327    #[inline]
1328    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1329        write!(f, "{}", self.load())
1330    }
1331}