Skip to main content

qubit_atomic/atomic/
atomic.rs

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