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