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