pub struct Atomic<T>where
T: AtomicValue,{ /* private fields */ }Expand description
A high-level atomic wrapper for supported primitive value types.
This type is the main entry point for primitive atomic values. It hides
explicit memory-ordering parameters behind crate-defined defaults while
still exposing the raw backend through inner for advanced
use cases.
Supported value types are:
boolu8,i8,u16,i16,u32,i32,u64,i64,u128,i128usize,isizef32,f64
The i128 and u128 specializations use portable-atomic internally
because the corresponding standard-library atomic types are not yet stable.
§Specialization API
Rustdoc documents Atomic<T> as one generic type rather than generating a
separate page for each concrete T. The following table summarizes the
methods available for each specialization:
| Specialization | Additional methods |
|---|---|
Atomic<bool> | fetch_set, fetch_clear, fetch_not, fetch_and, fetch_or, fetch_xor, set_if_false, set_if_true |
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 |
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 |
Atomic<f32>, Atomic<f64> | fetch_add, fetch_sub, fetch_mul, fetch_div |
All supported specializations also provide new,
load, store, swap,
compare_set,
compare_set_weak,
compare_and_exchange,
compare_and_exchange_weak,
fetch_update, try_update,
and inner.
Integer arithmetic operations intentionally follow Rust atomic integer
semantics and wrap on overflow and underflow. Use crate::AtomicCount or
crate::AtomicSignedCount when overflow or underflow must be rejected
instead of wrapping.
Floating-point compare-and-set/exchange operations compare raw
to_bits representations, not PartialEq. This means
distinct bit patterns that compare equal, such as 0.0 and -0.0, do not
match for CAS, and NaN payloads must match exactly. Prefer
compare_set or compare_set_weak
when the caller needs an explicit success indicator for f32 or f64.
§Example
use qubit_atomic::Atomic;
let counter = Atomic::new(0);
counter.fetch_inc();
assert_eq!(counter.load(), 1);
let flag = Atomic::new(false);
assert_eq!(flag.fetch_set(), false);
assert!(flag.load());When the value type is ambiguous (for example integer literals), specify
T explicitly with a turbofish on the constructor, or by annotating the
binding:
use qubit_atomic::Atomic;
let wide: Atomic<u64> = Atomic::new(0);
assert_eq!(wide.load(), 0u64);
let narrow = Atomic::<i16>::new(0);
assert_eq!(narrow.load(), 0i16);Implementations§
Source§impl<T> Atomic<T>where
T: AtomicValue,
impl<T> Atomic<T>where
T: AtomicValue,
Sourcepub fn new(value: T) -> Self
pub fn new(value: T) -> Self
Creates a new atomic value.
§Parameters
value- The initial value.
§Returns
An atomic wrapper initialized to value.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(42);
assert_eq!(atomic.load(), 42);To pick a concrete T when inference would be ambiguous (for example
0 as u64 vs i32), write Atomic::<T>::new(...) (turbofish) or add
a type annotation on the binding (for example let x: Atomic<u64> = ...):
use qubit_atomic::Atomic;
let a = Atomic::<u64>::new(0);
assert_eq!(a.load(), 0u64);
let b: Atomic<isize> = Atomic::new(0);
assert_eq!(b.load(), 0isize);Sourcepub fn swap(&self, value: T) -> T
pub fn swap(&self, value: T) -> T
Swaps the current value with value.
Unlike store, this returns the value that was in the
atomic immediately before the swap, in the same atomic step. Use
store when you do not need the previous value.
Uses AcqRel ordering by default.
§Parameters
value- The new value to store.
§Returns
The previous value.
§Example
use qubit_atomic::Atomic;
let a = Atomic::new(100);
a.store(200);
// store has no return value; you only see the new value via load().
assert_eq!(a.load(), 200);
let b = Atomic::new(100);
// swap returns the old value and installs the new one atomically.
assert_eq!(b.swap(200), 100);
assert_eq!(b.load(), 200);Sourcepub fn compare_set(&self, current: T, new: T) -> Result<(), T>
pub fn compare_set(&self, current: T, new: T) -> Result<(), T>
Compares the current value with current and stores new on match.
Uses AcqRel ordering on success and Acquire ordering on failure.
§Parameters
current- The expected current value.new- The replacement value to store when the comparison matches.
§Returns
Ok(()) when the value was replaced.
§Errors
Returns Err(actual) with the observed value when the comparison
fails. In that case, new is not stored.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(1);
assert!(atomic.compare_set(1, 2).is_ok());
assert_eq!(atomic.load(), 2);
assert_eq!(atomic.compare_set(1, 3), Err(2));Sourcepub fn compare_set_weak(&self, current: T, new: T) -> Result<(), T>
pub fn compare_set_weak(&self, current: T, new: T) -> Result<(), T>
Weak version of compare_set.
This operation may fail spuriously and is intended for retry loops.
§Parameters
current- The expected current value.new- The replacement value to store when the comparison matches.
§Returns
Ok(()) when the value was replaced.
§Errors
Returns Err(actual) with the observed value when the comparison
fails, including possible spurious failures. In that case, new is not
stored.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(1);
loop {
match atomic.compare_set_weak(1, 2) {
Ok(()) => break,
Err(actual) => assert_eq!(actual, 1),
}
}
assert_eq!(atomic.load(), 2);Sourcepub fn compare_and_exchange(&self, current: T, new: T) -> T
pub fn compare_and_exchange(&self, current: T, new: T) -> T
Compares and exchanges the value, returning the value seen before the operation.
If the return value equals current, the exchange succeeded.
§Parameters
current- The expected current value.new- The replacement value to store when the comparison matches.
§Returns
The value observed before the operation completed. If the returned
value equals current, the exchange succeeded; otherwise it is the
actual value that prevented the exchange.
For Atomic<f32> and Atomic<f64>, CAS compares raw IEEE-754 bit
patterns rather than PartialEq. A returned floating-point value
comparing equal to current is therefore not always enough to prove
success; use compare_set for an explicit
Ok/Err, or compare to_bits values yourself.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(5);
assert_eq!(atomic.compare_and_exchange(5, 10), 5);
assert_eq!(atomic.load(), 10);
assert_eq!(atomic.compare_and_exchange(5, 0), 10);Sourcepub fn compare_and_exchange_weak(&self, current: T, new: T) -> T
pub fn compare_and_exchange_weak(&self, current: T, new: T) -> T
Weak version of compare_and_exchange.
This operation may fail spuriously and is intended for retry loops.
§Parameters
current- The expected current value.new- The replacement value to store when the comparison matches.
§Returns
The value observed before the operation completed. Because this
operation may fail spuriously, a returned value equal to current does
not by itself prove that new was stored; use
compare_set_weak when the caller needs an
explicit success indicator.
For Atomic<f32> and Atomic<f64>, the same caveat applies to raw-bit
equality: 0.0 and -0.0 compare equal by PartialEq but are
different CAS values. Use compare_set_weak
or compare to_bits values when distinguishing success
from failure matters.
§Example
Weak CAS may fail spuriously; retry until load shows the
expected outcome (or use compare_set_weak
which reports success explicitly).
use qubit_atomic::Atomic;
let atomic = Atomic::new(5);
loop {
let _ = atomic.compare_and_exchange_weak(5, 10);
if atomic.load() == 10 {
break;
}
}Sourcepub fn fetch_update<F>(&self, f: F) -> Twhere
F: Fn(T) -> T,
pub fn fetch_update<F>(&self, f: F) -> Twhere
F: Fn(T) -> T,
Updates the value with a function and returns the previous value.
The update uses a CAS loop until it succeeds. The closure may be called more than once under contention.
§Parameters
f- A function that maps the current value to the next value.
§Returns
The value before the successful update.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(3);
assert_eq!(atomic.fetch_update(|x| x * 2), 3);
assert_eq!(atomic.load(), 6);Sourcepub fn try_update<F>(&self, f: F) -> Option<T>
pub fn try_update<F>(&self, f: F) -> Option<T>
Conditionally updates the value with a function.
The update uses a CAS loop until it succeeds or the closure rejects the
observed current value by returning None. The closure may be called
more than once under contention.
§Parameters
f- A function that maps the current value toSome(next)to update the atomic, orNoneto leave it unchanged.
§Returns
Some(old_value) with the value before the successful update, or None
when f rejects the observed current value.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(3);
assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), Some(3));
assert_eq!(atomic.load(), 4);
assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), None);
assert_eq!(atomic.load(), 4);Sourcepub fn inner(&self) -> &T::Inner
pub fn inner(&self) -> &T::Inner
Returns the raw backend atomic value.
Use this method only when the default orderings are not appropriate and the caller needs direct access to the backend atomic storage.
§Returns
A shared reference to the raw backend atomic value.
§Example
use qubit_atomic::Atomic;
use std::sync::atomic::Ordering;
let atomic = Atomic::<i32>::new(0);
assert_eq!(atomic.inner().load(Ordering::Relaxed), 0);Source§impl<T> Atomic<T>where
T: AtomicValue,
T::Primitive: AtomicNumberOps<Value = T>,
impl<T> Atomic<T>where
T: AtomicValue,
T::Primitive: AtomicNumberOps<Value = T>,
Sourcepub fn fetch_add(&self, delta: T) -> T
pub fn fetch_add(&self, delta: T) -> T
Adds delta to the value and returns the previous value.
Integer atomics use relaxed ordering for this operation. Floating-point atomics use a CAS loop. Integer addition wraps on overflow and underflow.
§Parameters
delta- The value to add.
§Returns
The value before the addition.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(10);
assert_eq!(atomic.fetch_add(3), 10);
assert_eq!(atomic.load(), 13);Sourcepub fn fetch_sub(&self, delta: T) -> T
pub fn fetch_sub(&self, delta: T) -> T
Subtracts delta from the value and returns the previous value.
Integer atomics use relaxed ordering for this operation. Floating-point atomics use a CAS loop. Integer subtraction wraps on overflow and underflow.
§Parameters
delta- The value to subtract.
§Returns
The value before the subtraction.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(10);
assert_eq!(atomic.fetch_sub(3), 10);
assert_eq!(atomic.load(), 7);Sourcepub fn fetch_mul(&self, factor: T) -> T
pub fn fetch_mul(&self, factor: T) -> T
Multiplies the value by factor and returns the previous value.
This operation uses a CAS loop. Integer multiplication wraps on overflow and underflow.
§Parameters
factor- The value to multiply by.
§Returns
The value before the multiplication.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(3);
assert_eq!(atomic.fetch_mul(4), 3);
assert_eq!(atomic.load(), 12);Sourcepub fn fetch_div(&self, divisor: T) -> T
pub fn fetch_div(&self, divisor: T) -> T
Divides the value by divisor and returns the previous value.
This operation uses a CAS loop. Integer division uses wrapping
semantics; for signed integers, MIN / -1 wraps to MIN.
§Parameters
divisor- The value to divide by.
§Returns
The value before the division.
§Panics
For integer specializations, panics if divisor is zero. Floating-point
specializations follow IEEE-754 division semantics and do not panic
solely because divisor is zero.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(20);
assert_eq!(atomic.fetch_div(4), 20);
assert_eq!(atomic.load(), 5);Source§impl<T> Atomic<T>where
T: AtomicIntegerValue,
impl<T> Atomic<T>where
T: AtomicIntegerValue,
Sourcepub fn fetch_accumulate<F>(&self, value: T, f: F) -> Twhere
F: Fn(T, T) -> T,
pub fn fetch_accumulate<F>(&self, value: T, f: F) -> Twhere
F: Fn(T, T) -> T,
Updates the value by accumulating it with value.
§Parameters
value- The right-hand input to the accumulator.f- A function that combines the current value andvalue.
§Returns
The value before the successful update.
The closure may be called more than once when concurrent updates cause CAS retries.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(10);
assert_eq!(atomic.fetch_accumulate(5, |a, b| a + b), 10);
assert_eq!(atomic.load(), 15);Sourcepub fn fetch_max(&self, value: T) -> T
pub fn fetch_max(&self, value: T) -> T
Replaces the value with the maximum of the current value and value.
§Parameters
value- The value to compare with the current value.
§Returns
The value before the operation.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(3);
assert_eq!(atomic.fetch_max(10), 3);
assert_eq!(atomic.load(), 10);Sourcepub fn fetch_min(&self, value: T) -> T
pub fn fetch_min(&self, value: T) -> T
Replaces the value with the minimum of the current value and value.
§Parameters
value- The value to compare with the current value.
§Returns
The value before the operation.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::new(10);
assert_eq!(atomic.fetch_min(3), 10);
assert_eq!(atomic.load(), 3);Source§impl Atomic<bool>
impl Atomic<bool>
Sourcepub fn fetch_clear(&self) -> bool
pub fn fetch_clear(&self) -> bool
Sourcepub fn set_if_false(&self, new: bool) -> Result<(), bool>
pub fn set_if_false(&self, new: bool) -> Result<(), bool>
Stores new only when the current value is false.
§Parameters
new- The replacement value.
§Returns
Ok(()) if the value was replaced.
§Errors
Returns Err(true) if the observed current value was already true.
In that case, new is not stored.
§Example
use qubit_atomic::Atomic;
let flag = Atomic::new(false);
assert!(flag.set_if_false(true).is_ok());
assert!(flag.load());
assert!(flag.set_if_false(false).is_err());Sourcepub fn set_if_true(&self, new: bool) -> Result<(), bool>
pub fn set_if_true(&self, new: bool) -> Result<(), bool>
Stores new only when the current value is true.
§Parameters
new- The replacement value.
§Returns
Ok(()) if the value was replaced.
§Errors
Returns Err(false) if the observed current value was already false.
In that case, new is not stored.
§Example
use qubit_atomic::Atomic;
let flag = Atomic::new(true);
assert!(flag.set_if_true(false).is_ok());
assert!(!flag.load());
assert!(flag.set_if_true(true).is_err());Trait Implementations§
Source§impl<T> Default for Atomic<T>where
T: AtomicValue + Default,
impl<T> Default for Atomic<T>where
T: AtomicValue + Default,
Source§fn default() -> Self
fn default() -> Self
Creates an atomic with Default::default as the initial value.
§Example
use qubit_atomic::Atomic;
let atomic = Atomic::<i32>::default();
assert_eq!(atomic.load(), 0);