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