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}