Skip to main content

qubit_atomic/atomic/
atomic.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//! # Generic Atomic Wrapper
10//!
11//! Provides the public [`Atomic<T>`] wrapper for supported primitive values.
12
13use std::{
14    fmt,
15    sync::atomic::Ordering,
16};
17
18use super::atomic_integer_value::AtomicIntegerValue;
19use super::atomic_number_ops::AtomicNumberOps;
20use super::atomic_ops::AtomicOps;
21use super::atomic_value::AtomicValue;
22
23/// A high-level atomic wrapper for supported primitive value types.
24///
25/// This type is the main entry point for primitive atomic values. It hides
26/// explicit memory-ordering parameters behind crate-defined defaults while
27/// still exposing the raw backend through [`inner`](Self::inner) for advanced
28/// use cases.
29///
30/// Supported value types are:
31///
32/// - `bool`
33/// - `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`
34/// - `usize`, `isize`
35/// - `f32`, `f64`
36///
37/// The `i128` and `u128` specializations use `portable-atomic` internally
38/// because the corresponding standard-library atomic types are not yet stable.
39/// Native lock-free support is target-dependent, and the backend fallback may
40/// use locks on targets without suitable atomic instructions.
41///
42/// # Specialization API
43///
44/// Rustdoc documents [`Atomic<T>`] as one generic type rather than generating a
45/// separate page for each concrete `T`. The following table summarizes the
46/// methods available for each specialization:
47///
48/// | Specialization | Additional methods |
49/// | --- | --- |
50/// | `Atomic<bool>` | `fetch_set`, `fetch_clear`, `fetch_not`, `fetch_and`, `fetch_or`, `fetch_xor`, `set_if_false`, `set_if_true` |
51/// | `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` |
52/// | `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` |
53/// | `Atomic<f32>`, `Atomic<f64>` | `fetch_add`, `fetch_sub`, `fetch_mul`, `fetch_div` |
54///
55/// All supported specializations also provide [`new`](Self::new),
56/// [`load`](Self::load), [`store`](Self::store), [`swap`](Self::swap),
57/// [`compare_set`](Self::compare_set),
58/// [`compare_set_weak`](Self::compare_set_weak),
59/// [`compare_and_exchange`](Self::compare_and_exchange),
60/// [`fetch_update`](Self::fetch_update),
61/// [`update_and_get`](Self::update_and_get),
62/// [`try_update`](Self::try_update),
63/// [`try_update_and_get`](Self::try_update_and_get), and
64/// [`inner`](Self::inner).
65///
66/// Integer arithmetic operations intentionally follow Rust atomic integer
67/// semantics and wrap on overflow and underflow. Use [`crate::AtomicCount`] or
68/// [`crate::AtomicSignedCount`] when overflow or underflow must be rejected
69/// instead of wrapping.
70///
71/// Floating-point compare-and-set/exchange operations compare raw
72/// [`to_bits`](f32::to_bits) representations, not [`PartialEq`]. This means
73/// distinct bit patterns that compare equal, such as `0.0` and `-0.0`, do not
74/// match for CAS, and NaN payloads must match exactly. Prefer
75/// [`compare_set`](Self::compare_set) or
76/// [`compare_set_weak`](Self::compare_set_weak) when the caller needs an
77/// 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#[doc(alias = "AtomicBool")]
109#[doc(alias = "AtomicI8")]
110#[doc(alias = "AtomicU8")]
111#[doc(alias = "AtomicI16")]
112#[doc(alias = "AtomicU16")]
113#[doc(alias = "AtomicI32")]
114#[doc(alias = "AtomicU32")]
115#[doc(alias = "AtomicI64")]
116#[doc(alias = "AtomicU64")]
117#[doc(alias = "AtomicI128")]
118#[doc(alias = "AtomicU128")]
119#[doc(alias = "AtomicIsize")]
120#[doc(alias = "AtomicUsize")]
121#[doc(alias = "AtomicF32")]
122#[doc(alias = "AtomicF64")]
123#[repr(transparent)]
124pub struct Atomic<T>
125where
126    T: AtomicValue,
127{
128    /// Primitive backend that performs the concrete atomic operations for `T`.
129    primitive: T::Primitive,
130}
131
132impl<T> Atomic<T>
133where
134    T: AtomicValue,
135{
136    /// Creates a new atomic value.
137    ///
138    /// # Parameters
139    ///
140    /// * `value` - The initial value.
141    ///
142    /// # Returns
143    ///
144    /// An atomic wrapper initialized to `value`.
145    ///
146    /// # Example
147    ///
148    /// ```rust
149    /// use qubit_atomic::Atomic;
150    ///
151    /// let atomic = Atomic::new(42);
152    /// assert_eq!(atomic.load(), 42);
153    /// ```
154    ///
155    /// To pick a concrete `T` when inference would be ambiguous (for example
156    /// `0` as `u64` vs `i32`), write `Atomic::<T>::new(...)` (turbofish) or add
157    /// a type annotation on the binding (for example `let x: Atomic<u64> =
158    /// ...`):
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(
405        &self,
406        current: T,
407        new: T,
408    ) -> Result<T, T> {
409        AtomicOps::compare_exchange_weak(&self.primitive, current, new)
410    }
411
412    /// Updates the value with a function and returns the previous value.
413    ///
414    /// The update uses a CAS loop until it succeeds. The closure may be called
415    /// more than once under contention.
416    ///
417    /// # Parameters
418    ///
419    /// * `f` - A function that maps the current value to the next value.
420    ///
421    /// # Returns
422    ///
423    /// The value before the successful update.
424    ///
425    /// # Example
426    ///
427    /// ```rust
428    /// use qubit_atomic::Atomic;
429    ///
430    /// let atomic = Atomic::new(3);
431    /// assert_eq!(atomic.fetch_update(|x| x * 2), 3);
432    /// assert_eq!(atomic.load(), 6);
433    /// ```
434    #[inline]
435    pub fn fetch_update<F>(&self, f: F) -> T
436    where
437        F: FnMut(T) -> T,
438    {
439        AtomicOps::fetch_update(&self.primitive, f)
440    }
441
442    /// Updates the value with a function and returns the new value.
443    ///
444    /// The update uses a CAS loop until it succeeds. The closure may be called
445    /// more than once under contention.
446    ///
447    /// # Parameters
448    ///
449    /// * `f` - A function that maps the current value to the next value.
450    ///
451    /// # Returns
452    ///
453    /// The value committed by the successful update.
454    ///
455    /// # Example
456    ///
457    /// ```rust
458    /// use qubit_atomic::Atomic;
459    ///
460    /// let atomic = Atomic::new(3);
461    /// assert_eq!(atomic.update_and_get(|x| x * 2), 6);
462    /// assert_eq!(atomic.load(), 6);
463    /// ```
464    #[inline]
465    pub fn update_and_get<F>(&self, f: F) -> T
466    where
467        F: FnMut(T) -> T,
468    {
469        AtomicOps::update_and_get(&self.primitive, f)
470    }
471
472    /// Conditionally updates the value with a function.
473    ///
474    /// The update uses a CAS loop until it succeeds or the closure rejects the
475    /// observed current value by returning `None`. The closure may be called
476    /// more than once under contention.
477    ///
478    /// # Parameters
479    ///
480    /// * `f` - A function that maps the current value to `Some(next)` to update
481    ///   the atomic, or `None` to leave it unchanged.
482    ///
483    /// # Returns
484    ///
485    /// `Some(old_value)` with the value before the successful update, or `None`
486    /// when `f` rejects the observed current value.
487    ///
488    /// # Example
489    ///
490    /// ```rust
491    /// use qubit_atomic::Atomic;
492    ///
493    /// let atomic = Atomic::new(3);
494    /// assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), Some(3));
495    /// assert_eq!(atomic.load(), 4);
496    /// assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), None);
497    /// assert_eq!(atomic.load(), 4);
498    /// ```
499    #[inline]
500    pub fn try_update<F>(&self, f: F) -> Option<T>
501    where
502        F: FnMut(T) -> Option<T>,
503    {
504        AtomicOps::try_update(&self.primitive, f)
505    }
506
507    /// Conditionally updates the value with a function and returns the new
508    /// value.
509    ///
510    /// The update uses a CAS loop until it succeeds or the closure rejects the
511    /// observed current value by returning `None`. The closure may be called
512    /// more than once under contention.
513    ///
514    /// # Parameters
515    ///
516    /// * `f` - A function that maps the current value to `Some(next)` to update
517    ///   the atomic, or `None` to leave it unchanged.
518    ///
519    /// # Returns
520    ///
521    /// `Some(new_value)` with the value committed by the successful update, or
522    /// `None` when `f` rejects the observed current value.
523    ///
524    /// # Example
525    ///
526    /// ```rust
527    /// use qubit_atomic::Atomic;
528    ///
529    /// let atomic = Atomic::new(3);
530    /// assert_eq!(
531    ///     atomic.try_update_and_get(|x| (x % 2 == 1).then_some(x + 1)),
532    ///     Some(4),
533    /// );
534    /// assert_eq!(atomic.load(), 4);
535    /// assert_eq!(
536    ///     atomic.try_update_and_get(|x| (x % 2 == 1).then_some(x + 1)),
537    ///     None,
538    /// );
539    /// assert_eq!(atomic.load(), 4);
540    /// ```
541    #[inline]
542    pub fn try_update_and_get<F>(&self, f: F) -> Option<T>
543    where
544        F: FnMut(T) -> Option<T>,
545    {
546        AtomicOps::try_update_and_get(&self.primitive, f)
547    }
548
549    /// Returns the raw backend atomic value.
550    ///
551    /// Use this method only when the default orderings are not appropriate
552    /// and the caller needs direct access to the backend atomic storage.
553    ///
554    /// # Returns
555    ///
556    /// A shared reference to the raw backend atomic value.
557    ///
558    /// # Example
559    ///
560    /// ```rust
561    /// use qubit_atomic::Atomic;
562    /// use std::sync::atomic::Ordering;
563    ///
564    /// let atomic = Atomic::<i32>::new(0);
565    /// assert_eq!(atomic.inner().load(Ordering::Relaxed), 0);
566    /// ```
567    #[inline]
568    pub fn inner(&self) -> &T::Inner {
569        T::inner(&self.primitive)
570    }
571}
572
573impl<T> Atomic<T>
574where
575    T: AtomicValue,
576    T::Primitive: AtomicNumberOps<Value = T>,
577{
578    /// Adds `delta` to the value and returns the previous value.
579    ///
580    /// Integer atomics use relaxed ordering for this operation. Floating-point
581    /// atomics use a CAS loop. Integer addition wraps on overflow and
582    /// underflow.
583    ///
584    /// # Parameters
585    ///
586    /// * `delta` - The value to add.
587    ///
588    /// # Returns
589    ///
590    /// The value before the addition.
591    ///
592    /// # Example
593    ///
594    /// ```rust
595    /// use qubit_atomic::Atomic;
596    ///
597    /// let atomic = Atomic::new(10);
598    /// assert_eq!(atomic.fetch_add(3), 10);
599    /// assert_eq!(atomic.load(), 13);
600    /// ```
601    #[inline]
602    pub fn fetch_add(&self, delta: T) -> T {
603        AtomicNumberOps::fetch_add(&self.primitive, delta)
604    }
605
606    /// Subtracts `delta` from the value and returns the previous value.
607    ///
608    /// Integer atomics use relaxed ordering for this operation. Floating-point
609    /// atomics use a CAS loop. Integer subtraction wraps on overflow and
610    /// underflow.
611    ///
612    /// # Parameters
613    ///
614    /// * `delta` - The value to subtract.
615    ///
616    /// # Returns
617    ///
618    /// The value before the subtraction.
619    ///
620    /// # Example
621    ///
622    /// ```rust
623    /// use qubit_atomic::Atomic;
624    ///
625    /// let atomic = Atomic::new(10);
626    /// assert_eq!(atomic.fetch_sub(3), 10);
627    /// assert_eq!(atomic.load(), 7);
628    /// ```
629    #[inline]
630    pub fn fetch_sub(&self, delta: T) -> T {
631        AtomicNumberOps::fetch_sub(&self.primitive, delta)
632    }
633
634    /// Multiplies the value by `factor` and returns the previous value.
635    ///
636    /// This operation uses a CAS loop. Integer multiplication wraps on
637    /// overflow and underflow.
638    ///
639    /// # Parameters
640    ///
641    /// * `factor` - The value to multiply by.
642    ///
643    /// # Returns
644    ///
645    /// The value before the multiplication.
646    ///
647    /// # Example
648    ///
649    /// ```rust
650    /// use qubit_atomic::Atomic;
651    ///
652    /// let atomic = Atomic::new(3);
653    /// assert_eq!(atomic.fetch_mul(4), 3);
654    /// assert_eq!(atomic.load(), 12);
655    /// ```
656    #[inline]
657    pub fn fetch_mul(&self, factor: T) -> T {
658        AtomicNumberOps::fetch_mul(&self.primitive, factor)
659    }
660
661    /// Divides the value by `divisor` and returns the previous value.
662    ///
663    /// This operation uses a CAS loop. Integer division uses wrapping
664    /// semantics; for signed integers, `MIN / -1` wraps to `MIN`.
665    ///
666    /// # Parameters
667    ///
668    /// * `divisor` - The value to divide by.
669    ///
670    /// # Returns
671    ///
672    /// The value before the division.
673    ///
674    /// # Panics
675    ///
676    /// For integer specializations, panics if `divisor` is zero. Floating-point
677    /// specializations follow IEEE-754 division semantics and do not panic
678    /// solely because `divisor` is zero.
679    ///
680    /// # Example
681    ///
682    /// ```rust
683    /// use qubit_atomic::Atomic;
684    ///
685    /// let atomic = Atomic::new(20);
686    /// assert_eq!(atomic.fetch_div(4), 20);
687    /// assert_eq!(atomic.load(), 5);
688    /// ```
689    #[inline]
690    pub fn fetch_div(&self, divisor: T) -> T {
691        AtomicNumberOps::fetch_div(&self.primitive, divisor)
692    }
693}
694
695impl<T> Atomic<T>
696where
697    T: AtomicIntegerValue,
698{
699    /// Increments the value by one and returns the previous value.
700    ///
701    /// # Returns
702    ///
703    /// The value before the increment.
704    ///
705    /// # Example
706    ///
707    /// ```rust
708    /// use qubit_atomic::Atomic;
709    ///
710    /// let atomic = Atomic::new(0);
711    /// assert_eq!(atomic.fetch_inc(), 0);
712    /// assert_eq!(atomic.load(), 1);
713    /// ```
714    #[inline]
715    pub fn fetch_inc(&self) -> T {
716        T::fetch_inc(&self.primitive)
717    }
718
719    /// Increments the value by one with an explicit memory ordering and returns
720    /// the previous value.
721    ///
722    /// Arithmetic wraps on overflow, matching Rust atomic integer operations.
723    ///
724    /// # Parameters
725    ///
726    /// * `ordering` - The memory ordering used by the atomic read-modify-write
727    ///   operation.
728    ///
729    /// # Returns
730    ///
731    /// The value before the increment.
732    ///
733    /// # Example
734    ///
735    /// ```rust
736    /// use qubit_atomic::Atomic;
737    /// use std::sync::atomic::Ordering;
738    ///
739    /// let atomic = Atomic::new(0);
740    /// assert_eq!(atomic.fetch_inc_with_ordering(Ordering::AcqRel), 0);
741    /// assert_eq!(atomic.load(), 1);
742    /// ```
743    #[inline]
744    pub fn fetch_inc_with_ordering(&self, ordering: Ordering) -> T {
745        T::fetch_inc_with_ordering(&self.primitive, ordering)
746    }
747
748    /// Decrements the value by one and returns the previous value.
749    ///
750    /// # Returns
751    ///
752    /// The value before the decrement.
753    ///
754    /// # Example
755    ///
756    /// ```rust
757    /// use qubit_atomic::Atomic;
758    ///
759    /// let atomic = Atomic::new(1);
760    /// assert_eq!(atomic.fetch_dec(), 1);
761    /// assert_eq!(atomic.load(), 0);
762    /// ```
763    #[inline]
764    pub fn fetch_dec(&self) -> T {
765        T::fetch_dec(&self.primitive)
766    }
767
768    /// Decrements the value by one with an explicit memory ordering and returns
769    /// the previous value.
770    ///
771    /// Arithmetic wraps on underflow, matching Rust atomic integer operations.
772    ///
773    /// # Parameters
774    ///
775    /// * `ordering` - The memory ordering used by the atomic read-modify-write
776    ///   operation.
777    ///
778    /// # Returns
779    ///
780    /// The value before the decrement.
781    ///
782    /// # Example
783    ///
784    /// ```rust
785    /// use qubit_atomic::Atomic;
786    /// use std::sync::atomic::Ordering;
787    ///
788    /// let atomic = Atomic::new(1);
789    /// assert_eq!(atomic.fetch_dec_with_ordering(Ordering::AcqRel), 1);
790    /// assert_eq!(atomic.load(), 0);
791    /// ```
792    #[inline]
793    pub fn fetch_dec_with_ordering(&self, ordering: Ordering) -> T {
794        T::fetch_dec_with_ordering(&self.primitive, ordering)
795    }
796
797    /// Adds `delta` with an explicit memory ordering and returns the previous
798    /// value.
799    ///
800    /// Arithmetic wraps on overflow and underflow, matching Rust atomic integer
801    /// operations.
802    ///
803    /// # Parameters
804    ///
805    /// * `delta` - The value to add.
806    /// * `ordering` - The memory ordering used by the atomic read-modify-write
807    ///   operation.
808    ///
809    /// # Returns
810    ///
811    /// The value before the addition.
812    ///
813    /// # Example
814    ///
815    /// ```rust
816    /// use qubit_atomic::Atomic;
817    /// use std::sync::atomic::Ordering;
818    ///
819    /// let atomic = Atomic::new(10);
820    /// assert_eq!(atomic.fetch_add_with_ordering(5, Ordering::AcqRel), 10);
821    /// assert_eq!(atomic.load(), 15);
822    /// ```
823    #[inline]
824    pub fn fetch_add_with_ordering(&self, delta: T, ordering: Ordering) -> T {
825        T::fetch_add_with_ordering(&self.primitive, delta, ordering)
826    }
827
828    /// Subtracts `delta` with an explicit memory ordering and returns the
829    /// previous value.
830    ///
831    /// Arithmetic wraps on overflow and underflow, matching Rust atomic integer
832    /// operations.
833    ///
834    /// # Parameters
835    ///
836    /// * `delta` - The value to subtract.
837    /// * `ordering` - The memory ordering used by the atomic read-modify-write
838    ///   operation.
839    ///
840    /// # Returns
841    ///
842    /// The value before the subtraction.
843    ///
844    /// # Example
845    ///
846    /// ```rust
847    /// use qubit_atomic::Atomic;
848    /// use std::sync::atomic::Ordering;
849    ///
850    /// let atomic = Atomic::new(10);
851    /// assert_eq!(atomic.fetch_sub_with_ordering(3, Ordering::AcqRel), 10);
852    /// assert_eq!(atomic.load(), 7);
853    /// ```
854    #[inline]
855    pub fn fetch_sub_with_ordering(&self, delta: T, ordering: Ordering) -> T {
856        T::fetch_sub_with_ordering(&self.primitive, delta, ordering)
857    }
858
859    /// Applies bitwise AND and returns the previous value.
860    ///
861    /// # Parameters
862    ///
863    /// * `value` - The mask to apply.
864    ///
865    /// # Returns
866    ///
867    /// The value before the operation.
868    ///
869    /// # Example
870    ///
871    /// ```rust
872    /// use qubit_atomic::Atomic;
873    ///
874    /// let atomic = Atomic::<u8>::new(0b1111);
875    /// assert_eq!(atomic.fetch_and(0b1010), 0b1111);
876    /// assert_eq!(atomic.load(), 0b1010);
877    /// ```
878    #[inline]
879    pub fn fetch_and(&self, value: T) -> T {
880        T::fetch_and(&self.primitive, value)
881    }
882
883    /// Applies bitwise OR and returns the previous value.
884    ///
885    /// # Parameters
886    ///
887    /// * `value` - The mask to apply.
888    ///
889    /// # Returns
890    ///
891    /// The value before the operation.
892    ///
893    /// # Example
894    ///
895    /// ```rust
896    /// use qubit_atomic::Atomic;
897    ///
898    /// let atomic = Atomic::<u8>::new(0b1000);
899    /// assert_eq!(atomic.fetch_or(0b0011), 0b1000);
900    /// assert_eq!(atomic.load(), 0b1011);
901    /// ```
902    #[inline]
903    pub fn fetch_or(&self, value: T) -> T {
904        T::fetch_or(&self.primitive, value)
905    }
906
907    /// Applies bitwise XOR and returns the previous value.
908    ///
909    /// # Parameters
910    ///
911    /// * `value` - The mask to apply.
912    ///
913    /// # Returns
914    ///
915    /// The value before the operation.
916    ///
917    /// # Example
918    ///
919    /// ```rust
920    /// use qubit_atomic::Atomic;
921    ///
922    /// let atomic = Atomic::<u8>::new(0b1111);
923    /// assert_eq!(atomic.fetch_xor(0b1010), 0b1111);
924    /// assert_eq!(atomic.load(), 0b0101);
925    /// ```
926    #[inline]
927    pub fn fetch_xor(&self, value: T) -> T {
928        T::fetch_xor(&self.primitive, value)
929    }
930
931    /// Flips all bits and returns the previous value.
932    ///
933    /// # Returns
934    ///
935    /// The value before the operation.
936    ///
937    /// # Example
938    ///
939    /// ```rust
940    /// use qubit_atomic::Atomic;
941    ///
942    /// let atomic = Atomic::<i32>::new(0);
943    /// assert_eq!(atomic.fetch_not(), 0);
944    /// assert_eq!(atomic.load(), !0);
945    /// ```
946    #[inline]
947    pub fn fetch_not(&self) -> T {
948        T::fetch_not(&self.primitive)
949    }
950
951    /// Updates the value by accumulating it with `value`.
952    ///
953    /// # Parameters
954    ///
955    /// * `value` - The right-hand input to the accumulator.
956    /// * `f` - A function that combines the current value and `value`.
957    ///
958    /// # Returns
959    ///
960    /// The value before the successful update.
961    ///
962    /// The closure may be called more than once when concurrent updates cause
963    /// CAS retries.
964    ///
965    /// # Example
966    ///
967    /// ```rust
968    /// use qubit_atomic::Atomic;
969    ///
970    /// let atomic = Atomic::new(10);
971    /// assert_eq!(atomic.fetch_accumulate(5, |a, b| a + b), 10);
972    /// assert_eq!(atomic.load(), 15);
973    /// ```
974    #[inline]
975    pub fn fetch_accumulate<F>(&self, value: T, f: F) -> T
976    where
977        F: FnMut(T, T) -> T,
978    {
979        T::fetch_accumulate(&self.primitive, value, f)
980    }
981
982    /// Updates the value by accumulating it with `value` and returns the new
983    /// value.
984    ///
985    /// # Parameters
986    ///
987    /// * `value` - The right-hand input to the accumulator.
988    /// * `f` - A function that combines the current value and `value`.
989    ///
990    /// # Returns
991    ///
992    /// The value committed by the successful update.
993    ///
994    /// The closure may be called more than once when concurrent updates cause
995    /// CAS retries.
996    ///
997    /// # Example
998    ///
999    /// ```rust
1000    /// use qubit_atomic::Atomic;
1001    ///
1002    /// let atomic = Atomic::new(10);
1003    /// assert_eq!(atomic.accumulate_and_get(5, |a, b| a + b), 15);
1004    /// assert_eq!(atomic.load(), 15);
1005    /// ```
1006    #[inline]
1007    pub fn accumulate_and_get<F>(&self, value: T, f: F) -> T
1008    where
1009        F: FnMut(T, T) -> T,
1010    {
1011        T::accumulate_and_get(&self.primitive, value, f)
1012    }
1013
1014    /// Replaces the value with the maximum of the current value and `value`.
1015    ///
1016    /// # Parameters
1017    ///
1018    /// * `value` - The value to compare with the current value.
1019    ///
1020    /// # Returns
1021    ///
1022    /// The value before the operation.
1023    ///
1024    /// # Example
1025    ///
1026    /// ```rust
1027    /// use qubit_atomic::Atomic;
1028    ///
1029    /// let atomic = Atomic::new(3);
1030    /// assert_eq!(atomic.fetch_max(10), 3);
1031    /// assert_eq!(atomic.load(), 10);
1032    /// ```
1033    #[inline]
1034    pub fn fetch_max(&self, value: T) -> T {
1035        T::fetch_max(&self.primitive, value)
1036    }
1037
1038    /// Replaces the value with the minimum of the current value and `value`.
1039    ///
1040    /// # Parameters
1041    ///
1042    /// * `value` - The value to compare with the current value.
1043    ///
1044    /// # Returns
1045    ///
1046    /// The value before the operation.
1047    ///
1048    /// # Example
1049    ///
1050    /// ```rust
1051    /// use qubit_atomic::Atomic;
1052    ///
1053    /// let atomic = Atomic::new(10);
1054    /// assert_eq!(atomic.fetch_min(3), 10);
1055    /// assert_eq!(atomic.load(), 3);
1056    /// ```
1057    #[inline]
1058    pub fn fetch_min(&self, value: T) -> T {
1059        T::fetch_min(&self.primitive, value)
1060    }
1061}
1062
1063impl Atomic<bool> {
1064    /// Stores `true` and returns the previous value.
1065    ///
1066    /// # Returns
1067    ///
1068    /// The previous value.
1069    ///
1070    /// # Example
1071    ///
1072    /// ```rust
1073    /// use qubit_atomic::Atomic;
1074    ///
1075    /// let flag = Atomic::new(false);
1076    /// assert_eq!(flag.fetch_set(), false);
1077    /// assert!(flag.load());
1078    /// ```
1079    #[inline]
1080    pub fn fetch_set(&self) -> bool {
1081        self.primitive.fetch_set()
1082    }
1083
1084    /// Stores `false` and returns the previous value.
1085    ///
1086    /// # Returns
1087    ///
1088    /// The previous value.
1089    ///
1090    /// # Example
1091    ///
1092    /// ```rust
1093    /// use qubit_atomic::Atomic;
1094    ///
1095    /// let flag = Atomic::new(true);
1096    /// assert_eq!(flag.fetch_clear(), true);
1097    /// assert!(!flag.load());
1098    /// ```
1099    #[inline]
1100    pub fn fetch_clear(&self) -> bool {
1101        self.primitive.fetch_clear()
1102    }
1103
1104    /// Negates the value and returns the previous value.
1105    ///
1106    /// # Returns
1107    ///
1108    /// The previous value.
1109    ///
1110    /// # Example
1111    ///
1112    /// ```rust
1113    /// use qubit_atomic::Atomic;
1114    ///
1115    /// let flag = Atomic::new(false);
1116    /// assert_eq!(flag.fetch_not(), false);
1117    /// assert!(flag.load());
1118    /// ```
1119    #[inline]
1120    pub fn fetch_not(&self) -> bool {
1121        self.primitive.fetch_not()
1122    }
1123
1124    /// Applies logical AND and returns the previous value.
1125    ///
1126    /// # Parameters
1127    ///
1128    /// * `value` - The value to combine with the current value.
1129    ///
1130    /// # Returns
1131    ///
1132    /// The previous value.
1133    ///
1134    /// # Example
1135    ///
1136    /// ```rust
1137    /// use qubit_atomic::Atomic;
1138    ///
1139    /// let flag = Atomic::new(true);
1140    /// assert_eq!(flag.fetch_and(false), true);
1141    /// assert!(!flag.load());
1142    /// ```
1143    #[inline]
1144    pub fn fetch_and(&self, value: bool) -> bool {
1145        self.primitive.fetch_and(value)
1146    }
1147
1148    /// Applies logical OR and returns the previous value.
1149    ///
1150    /// # Parameters
1151    ///
1152    /// * `value` - The value to combine with the current value.
1153    ///
1154    /// # Returns
1155    ///
1156    /// The previous value.
1157    ///
1158    /// # Example
1159    ///
1160    /// ```rust
1161    /// use qubit_atomic::Atomic;
1162    ///
1163    /// let flag = Atomic::new(false);
1164    /// assert_eq!(flag.fetch_or(true), false);
1165    /// assert!(flag.load());
1166    /// ```
1167    #[inline]
1168    pub fn fetch_or(&self, value: bool) -> bool {
1169        self.primitive.fetch_or(value)
1170    }
1171
1172    /// Applies logical XOR and returns the previous value.
1173    ///
1174    /// # Parameters
1175    ///
1176    /// * `value` - The value to combine with the current value.
1177    ///
1178    /// # Returns
1179    ///
1180    /// The previous value.
1181    ///
1182    /// # Example
1183    ///
1184    /// ```rust
1185    /// use qubit_atomic::Atomic;
1186    ///
1187    /// let flag = Atomic::new(true);
1188    /// assert_eq!(flag.fetch_xor(true), true);
1189    /// assert!(!flag.load());
1190    /// ```
1191    #[inline]
1192    pub fn fetch_xor(&self, value: bool) -> bool {
1193        self.primitive.fetch_xor(value)
1194    }
1195
1196    /// Stores `new` only when the current value is `false`.
1197    ///
1198    /// # Parameters
1199    ///
1200    /// * `new` - The replacement value.
1201    ///
1202    /// # Returns
1203    ///
1204    /// `Ok(())` if the value was replaced.
1205    ///
1206    /// # Errors
1207    ///
1208    /// Returns `Err(true)` if the observed current value was already `true`.
1209    /// In that case, `new` is not stored.
1210    ///
1211    /// # Example
1212    ///
1213    /// ```rust
1214    /// use qubit_atomic::Atomic;
1215    ///
1216    /// let flag = Atomic::new(false);
1217    /// assert!(flag.set_if_false(true).is_ok());
1218    /// assert!(flag.load());
1219    /// assert!(flag.set_if_false(false).is_err());
1220    /// ```
1221    #[inline]
1222    pub fn set_if_false(&self, new: bool) -> Result<(), bool> {
1223        self.primitive.set_if_false(new)
1224    }
1225
1226    /// Stores `new` only when the current value is `true`.
1227    ///
1228    /// # Parameters
1229    ///
1230    /// * `new` - The replacement value.
1231    ///
1232    /// # Returns
1233    ///
1234    /// `Ok(())` if the value was replaced.
1235    ///
1236    /// # Errors
1237    ///
1238    /// Returns `Err(false)` if the observed current value was already `false`.
1239    /// In that case, `new` is not stored.
1240    ///
1241    /// # Example
1242    ///
1243    /// ```rust
1244    /// use qubit_atomic::Atomic;
1245    ///
1246    /// let flag = Atomic::new(true);
1247    /// assert!(flag.set_if_true(false).is_ok());
1248    /// assert!(!flag.load());
1249    /// assert!(flag.set_if_true(true).is_err());
1250    /// ```
1251    #[inline]
1252    pub fn set_if_true(&self, new: bool) -> Result<(), bool> {
1253        self.primitive.set_if_true(new)
1254    }
1255}
1256
1257impl<T> Default for Atomic<T>
1258where
1259    T: AtomicValue + Default,
1260{
1261    /// Creates an atomic with [`Default::default`] as the initial value.
1262    ///
1263    /// # Example
1264    ///
1265    /// ```rust
1266    /// use qubit_atomic::Atomic;
1267    ///
1268    /// let atomic = Atomic::<i32>::default();
1269    /// assert_eq!(atomic.load(), 0);
1270    /// ```
1271    #[inline]
1272    fn default() -> Self {
1273        Self::new(T::default())
1274    }
1275}
1276
1277impl<T> From<T> for Atomic<T>
1278where
1279    T: AtomicValue,
1280{
1281    /// Converts `value` into an [`Atomic`] via [`Atomic::new`].
1282    ///
1283    /// # Example
1284    ///
1285    /// ```rust
1286    /// use qubit_atomic::Atomic;
1287    ///
1288    /// let atomic = Atomic::from(42i32);
1289    /// assert_eq!(atomic.load(), 42);
1290    /// ```
1291    #[inline]
1292    fn from(value: T) -> Self {
1293        Self::new(value)
1294    }
1295}
1296
1297impl<T> fmt::Debug for Atomic<T>
1298where
1299    T: AtomicValue + fmt::Debug,
1300{
1301    /// Formats the loaded value as `Atomic { value: ... }`.
1302    ///
1303    /// # Example
1304    ///
1305    /// ```rust
1306    /// use qubit_atomic::Atomic;
1307    ///
1308    /// let atomic = Atomic::new(7);
1309    /// assert!(format!("{:?}", atomic).contains("7"));
1310    /// ```
1311    #[inline]
1312    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1313        f.debug_struct("Atomic")
1314            .field("value", &self.load())
1315            .finish()
1316    }
1317}
1318
1319impl<T> fmt::Display for Atomic<T>
1320where
1321    T: AtomicValue + fmt::Display,
1322{
1323    /// Formats the loaded value using its [`Display`](fmt::Display)
1324    /// implementation.
1325    ///
1326    /// # Example
1327    ///
1328    /// ```rust
1329    /// use qubit_atomic::Atomic;
1330    ///
1331    /// let atomic = Atomic::new(42);
1332    /// assert_eq!(format!("{}", atomic), "42");
1333    /// ```
1334    #[inline]
1335    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1336        write!(f, "{}", self.load())
1337    }
1338}