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}