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