qubit_atomic/atomic/atomic.rs
1// =============================================================================
2// Copyright (c) 2025 - 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9//! # Generic Atomic Wrapper
10//!
11//! Provides the public [`Atomic<T>`] wrapper for supported primitive values.
12
13use std::{
14 fmt,
15 sync::atomic::Ordering,
16};
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/// Native lock-free support is target-dependent, and the backend fallback may
40/// use locks on targets without suitable atomic instructions.
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_*_with_ordering`, `fetch_and`, `fetch_or`, `fetch_xor`, `fetch_not`, `fetch_accumulate`, `accumulate_and_get`, `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_*_with_ordering`, `fetch_and`, `fetch_or`, `fetch_xor`, `fetch_not`, `fetch_accumulate`, `accumulate_and_get`, `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/// [`fetch_update`](Self::fetch_update),
61/// [`update_and_get`](Self::update_and_get),
62/// [`try_update`](Self::try_update),
63/// [`try_update_and_get`](Self::try_update_and_get), and
64/// [`inner`](Self::inner).
65///
66/// Integer arithmetic operations intentionally follow Rust atomic integer
67/// semantics and wrap on overflow and underflow. Use [`crate::AtomicCount`] or
68/// [`crate::AtomicSignedCount`] when overflow or underflow must be rejected
69/// instead of wrapping.
70///
71/// Floating-point compare-and-set/exchange operations compare raw
72/// [`to_bits`](f32::to_bits) representations, not [`PartialEq`]. This means
73/// distinct bit patterns that compare equal, such as `0.0` and `-0.0`, do not
74/// match for CAS, and NaN payloads must match exactly. Prefer
75/// [`compare_set`](Self::compare_set) or
76/// [`compare_set_weak`](Self::compare_set_weak) when the caller needs an
77/// explicit success indicator for `f32` or `f64`.
78///
79/// # Examples
80///
81/// ```rust
82/// use qubit_atomic::Atomic;
83///
84/// let counter = Atomic::new(0);
85/// counter.fetch_inc();
86/// assert_eq!(counter.load(), 1);
87///
88/// let flag = Atomic::new(false);
89/// assert_eq!(flag.fetch_set(), false);
90/// assert!(flag.load());
91/// ```
92///
93/// When the value type is ambiguous (for example integer literals), specify
94/// `T` explicitly with a [turbofish] on the constructor, or by annotating the
95/// binding:
96///
97/// ```rust
98/// use qubit_atomic::Atomic;
99///
100/// let wide: Atomic<u64> = Atomic::new(0);
101/// assert_eq!(wide.load(), 0u64);
102///
103/// let narrow = Atomic::<i16>::new(0);
104/// assert_eq!(narrow.load(), 0i16);
105/// ```
106///
107/// [turbofish]: https://doc.rust-lang.org/book/appendix-02-operators.html#the-turbofish
108#[doc(alias = "AtomicBool")]
109#[doc(alias = "AtomicI8")]
110#[doc(alias = "AtomicU8")]
111#[doc(alias = "AtomicI16")]
112#[doc(alias = "AtomicU16")]
113#[doc(alias = "AtomicI32")]
114#[doc(alias = "AtomicU32")]
115#[doc(alias = "AtomicI64")]
116#[doc(alias = "AtomicU64")]
117#[doc(alias = "AtomicI128")]
118#[doc(alias = "AtomicU128")]
119#[doc(alias = "AtomicIsize")]
120#[doc(alias = "AtomicUsize")]
121#[doc(alias = "AtomicF32")]
122#[doc(alias = "AtomicF64")]
123#[repr(transparent)]
124pub struct Atomic<T>
125where
126 T: AtomicValue,
127{
128 /// Primitive backend that performs the concrete atomic operations for `T`.
129 primitive: T::Primitive,
130}
131
132impl<T> Atomic<T>
133where
134 T: AtomicValue,
135{
136 /// Creates a new atomic value.
137 ///
138 /// # Parameters
139 ///
140 /// * `value` - The initial value.
141 ///
142 /// # Returns
143 ///
144 /// An atomic wrapper initialized to `value`.
145 ///
146 /// # Examples
147 ///
148 /// ```rust
149 /// use qubit_atomic::Atomic;
150 ///
151 /// let atomic = Atomic::new(42);
152 /// assert_eq!(atomic.load(), 42);
153 /// ```
154 ///
155 /// To pick a concrete `T` when inference would be ambiguous (for example
156 /// `0` as `u64` vs `i32`), write `Atomic::<T>::new(...)` (turbofish) or add
157 /// a type annotation on the binding (for example `let x: Atomic<u64> =
158 /// ...`):
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 /// # Examples
185 ///
186 /// ```rust
187 /// use qubit_atomic::Atomic;
188 ///
189 /// let atomic = Atomic::new(7);
190 /// assert_eq!(atomic.load(), 7);
191 /// ```
192 #[must_use]
193 #[inline(always)]
194 pub fn load(&self) -> T {
195 AtomicOps::load(&self.primitive)
196 }
197
198 /// Stores a new value.
199 ///
200 /// Uses `Release` ordering by default.
201 ///
202 /// # Parameters
203 ///
204 /// * `value` - The new value to store.
205 ///
206 /// # Examples
207 ///
208 /// ```rust
209 /// use qubit_atomic::Atomic;
210 ///
211 /// let atomic = Atomic::new(1);
212 /// atomic.store(2);
213 /// assert_eq!(atomic.load(), 2);
214 /// ```
215 #[inline(always)]
216 pub fn store(&self, value: T) {
217 AtomicOps::store(&self.primitive, value);
218 }
219
220 /// Swaps the current value with `value`.
221 ///
222 /// Unlike [`store`](Self::store), this returns the value that was in the
223 /// atomic immediately before the swap, in the same atomic step. Use
224 /// [`store`](Self::store) when you do not need the previous value.
225 ///
226 /// Uses `AcqRel` ordering by default.
227 ///
228 /// # Parameters
229 ///
230 /// * `value` - The new value to store.
231 ///
232 /// # Returns
233 ///
234 /// The previous value.
235 ///
236 /// # Examples
237 ///
238 /// ```rust
239 /// use qubit_atomic::Atomic;
240 ///
241 /// let a = Atomic::new(100);
242 /// a.store(200);
243 /// // store has no return value; you only see the new value via load().
244 /// assert_eq!(a.load(), 200);
245 ///
246 /// let b = Atomic::new(100);
247 /// // swap returns the old value and installs the new one atomically.
248 /// assert_eq!(b.swap(200), 100);
249 /// assert_eq!(b.load(), 200);
250 /// ```
251 #[must_use]
252 #[inline(always)]
253 pub fn swap(&self, value: T) -> T {
254 AtomicOps::swap(&self.primitive, value)
255 }
256
257 /// Compares the current value with `current` and stores `new` on match.
258 ///
259 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
260 ///
261 /// # Parameters
262 ///
263 /// * `current` - The expected current value.
264 /// * `new` - The replacement value to store when the comparison matches.
265 ///
266 /// # Returns
267 ///
268 /// `Ok(())` when the value was replaced.
269 ///
270 /// # Errors
271 ///
272 /// Returns `Err(actual)` with the observed value when the comparison
273 /// fails. In that case, `new` is not stored.
274 ///
275 /// # Examples
276 ///
277 /// ```rust
278 /// use qubit_atomic::Atomic;
279 ///
280 /// let atomic = Atomic::new(1);
281 /// assert!(atomic.compare_set(1, 2).is_ok());
282 /// assert_eq!(atomic.load(), 2);
283 /// assert_eq!(atomic.compare_set(1, 3), Err(2));
284 /// ```
285 #[inline(always)]
286 pub fn compare_set(&self, current: T, new: T) -> Result<(), T> {
287 AtomicOps::compare_set(&self.primitive, current, new)
288 }
289
290 /// Weak version of [`compare_set`](Self::compare_set).
291 ///
292 /// This operation may fail spuriously and is intended for retry loops.
293 ///
294 /// # Parameters
295 ///
296 /// * `current` - The expected current value.
297 /// * `new` - The replacement value to store when the comparison matches.
298 ///
299 /// # Returns
300 ///
301 /// `Ok(())` when the value was replaced.
302 ///
303 /// # Errors
304 ///
305 /// Returns `Err(actual)` with the observed value when the comparison
306 /// fails, including possible spurious failures. In that case, `new` is not
307 /// stored.
308 ///
309 /// # Examples
310 ///
311 /// ```rust
312 /// use qubit_atomic::Atomic;
313 ///
314 /// let atomic = Atomic::new(1);
315 /// loop {
316 /// match atomic.compare_set_weak(1, 2) {
317 /// Ok(()) => break,
318 /// Err(actual) => assert_eq!(actual, 1),
319 /// }
320 /// }
321 /// assert_eq!(atomic.load(), 2);
322 /// ```
323 #[inline(always)]
324 pub fn compare_set_weak(&self, current: T, new: T) -> Result<(), T> {
325 AtomicOps::compare_set_weak(&self.primitive, current, new)
326 }
327
328 /// Compares and exchanges the value, returning the value seen before the
329 /// operation.
330 ///
331 /// If the return value equals `current`, the exchange succeeded.
332 ///
333 /// # Parameters
334 ///
335 /// * `current` - The expected current value.
336 /// * `new` - The replacement value to store when the comparison matches.
337 ///
338 /// # Returns
339 ///
340 /// The value observed before the operation completed. If the returned
341 /// value equals `current`, the exchange succeeded; otherwise it is the
342 /// actual value that prevented the exchange.
343 ///
344 /// For `Atomic<f32>` and `Atomic<f64>`, CAS compares raw IEEE-754 bit
345 /// patterns rather than [`PartialEq`]. A returned floating-point value
346 /// comparing equal to `current` is therefore not always enough to prove
347 /// success; use [`compare_set`](Self::compare_set) for an explicit
348 /// `Ok`/`Err`, or compare [`to_bits`](f32::to_bits) values yourself.
349 ///
350 /// # Examples
351 ///
352 /// ```rust
353 /// use qubit_atomic::Atomic;
354 ///
355 /// let atomic = Atomic::new(5);
356 /// assert_eq!(atomic.compare_and_exchange(5, 10), 5);
357 /// assert_eq!(atomic.load(), 10);
358 /// assert_eq!(atomic.compare_and_exchange(5, 0), 10);
359 /// ```
360 #[must_use]
361 #[inline(always)]
362 pub fn compare_and_exchange(&self, current: T, new: T) -> T {
363 AtomicOps::compare_exchange(&self.primitive, current, new)
364 }
365
366 /// Weak version of [`compare_and_exchange`](Self::compare_and_exchange).
367 ///
368 /// This operation may fail spuriously and is intended for retry loops.
369 ///
370 /// # Parameters
371 ///
372 /// * `current` - The expected current value.
373 /// * `new` - The replacement value to store when the comparison matches.
374 ///
375 /// # Returns
376 ///
377 /// `Ok(previous)` when the value was replaced, or `Err(actual)` when the
378 /// comparison failed, including possible spurious failure.
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 /// # Examples
387 ///
388 /// Weak CAS may fail spuriously; retry on `Err(actual)`.
389 ///
390 /// ```rust
391 /// use qubit_atomic::Atomic;
392 ///
393 /// let atomic = Atomic::new(5);
394 /// let mut current = 5;
395 /// loop {
396 /// match atomic.compare_and_exchange_weak(current, 10) {
397 /// Ok(previous) => {
398 /// assert_eq!(previous, current);
399 /// break;
400 /// }
401 /// Err(actual) => current = actual,
402 /// }
403 /// }
404 /// assert_eq!(atomic.load(), 10);
405 /// ```
406 #[inline(always)]
407 pub fn compare_and_exchange_weak(
408 &self,
409 current: T,
410 new: T,
411 ) -> Result<T, T> {
412 AtomicOps::compare_exchange_weak(&self.primitive, current, new)
413 }
414
415 /// Updates the value with a function and returns the previous value.
416 ///
417 /// The update uses a CAS loop until it succeeds. The closure may be called
418 /// more than once under contention.
419 ///
420 /// # Parameters
421 ///
422 /// * `f` - A function that maps the current value to the next value.
423 ///
424 /// # Returns
425 ///
426 /// The value before the successful update.
427 ///
428 /// # Examples
429 ///
430 /// ```rust
431 /// use qubit_atomic::Atomic;
432 ///
433 /// let atomic = Atomic::new(3);
434 /// assert_eq!(atomic.fetch_update(|x| x * 2), 3);
435 /// assert_eq!(atomic.load(), 6);
436 /// ```
437 #[inline(always)]
438 pub fn fetch_update<F>(&self, f: F) -> T
439 where
440 F: FnMut(T) -> T,
441 {
442 AtomicOps::fetch_update(&self.primitive, f)
443 }
444
445 /// Updates the value with a function and returns the new value.
446 ///
447 /// The update uses a CAS loop until it succeeds. The closure may be called
448 /// more than once under contention.
449 ///
450 /// # Parameters
451 ///
452 /// * `f` - A function that maps the current value to the next value.
453 ///
454 /// # Returns
455 ///
456 /// The value committed by the successful update.
457 ///
458 /// # Examples
459 ///
460 /// ```rust
461 /// use qubit_atomic::Atomic;
462 ///
463 /// let atomic = Atomic::new(3);
464 /// assert_eq!(atomic.update_and_get(|x| x * 2), 6);
465 /// assert_eq!(atomic.load(), 6);
466 /// ```
467 #[inline(always)]
468 pub fn update_and_get<F>(&self, f: F) -> T
469 where
470 F: FnMut(T) -> T,
471 {
472 AtomicOps::update_and_get(&self.primitive, f)
473 }
474
475 /// Conditionally updates the value with a function.
476 ///
477 /// The update uses a CAS loop until it succeeds or the closure rejects the
478 /// observed current value by returning `None`. The closure may be called
479 /// more than once under contention.
480 ///
481 /// # Parameters
482 ///
483 /// * `f` - A function that maps the current value to `Some(next)` to update
484 /// the atomic, or `None` to leave it unchanged.
485 ///
486 /// # Returns
487 ///
488 /// `Some(old_value)` with the value before the successful update, or `None`
489 /// when `f` rejects the observed current value.
490 ///
491 /// # Examples
492 ///
493 /// ```rust
494 /// use qubit_atomic::Atomic;
495 ///
496 /// let atomic = Atomic::new(3);
497 /// assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), Some(3));
498 /// assert_eq!(atomic.load(), 4);
499 /// assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), None);
500 /// assert_eq!(atomic.load(), 4);
501 /// ```
502 #[inline(always)]
503 pub fn try_update<F>(&self, f: F) -> Option<T>
504 where
505 F: FnMut(T) -> Option<T>,
506 {
507 AtomicOps::try_update(&self.primitive, f)
508 }
509
510 /// Conditionally updates the value with a function and returns the new
511 /// value.
512 ///
513 /// The update uses a CAS loop until it succeeds or the closure rejects the
514 /// observed current value by returning `None`. The closure may be called
515 /// more than once under contention.
516 ///
517 /// # Parameters
518 ///
519 /// * `f` - A function that maps the current value to `Some(next)` to update
520 /// the atomic, or `None` to leave it unchanged.
521 ///
522 /// # Returns
523 ///
524 /// `Some(new_value)` with the value committed by the successful update, or
525 /// `None` when `f` rejects the observed current value.
526 ///
527 /// # Examples
528 ///
529 /// ```rust
530 /// use qubit_atomic::Atomic;
531 ///
532 /// let atomic = Atomic::new(3);
533 /// assert_eq!(
534 /// atomic.try_update_and_get(|x| (x % 2 == 1).then_some(x + 1)),
535 /// Some(4),
536 /// );
537 /// assert_eq!(atomic.load(), 4);
538 /// assert_eq!(
539 /// atomic.try_update_and_get(|x| (x % 2 == 1).then_some(x + 1)),
540 /// None,
541 /// );
542 /// assert_eq!(atomic.load(), 4);
543 /// ```
544 #[inline(always)]
545 pub fn try_update_and_get<F>(&self, f: F) -> Option<T>
546 where
547 F: FnMut(T) -> Option<T>,
548 {
549 AtomicOps::try_update_and_get(&self.primitive, f)
550 }
551
552 /// Returns the raw backend atomic value.
553 ///
554 /// Use this method only when the default orderings are not appropriate
555 /// and the caller needs direct access to the backend atomic storage.
556 ///
557 /// # Returns
558 ///
559 /// A shared reference to the raw backend atomic value.
560 ///
561 /// # Examples
562 ///
563 /// ```rust
564 /// use qubit_atomic::Atomic;
565 /// use std::sync::atomic::Ordering;
566 ///
567 /// let atomic = Atomic::<i32>::new(0);
568 /// assert_eq!(atomic.inner().load(Ordering::Relaxed), 0);
569 /// ```
570 #[must_use]
571 #[inline(always)]
572 pub fn inner(&self) -> &T::Inner {
573 T::inner(&self.primitive)
574 }
575}
576
577impl<T> Atomic<T>
578where
579 T: AtomicValue,
580 T::Primitive: AtomicNumberOps<Value = T>,
581{
582 /// Adds `delta` to the value and returns the previous value.
583 ///
584 /// Integer atomics use relaxed ordering for this operation. Floating-point
585 /// atomics use a CAS loop. Integer addition wraps on overflow and
586 /// underflow.
587 ///
588 /// # Parameters
589 ///
590 /// * `delta` - The value to add.
591 ///
592 /// # Returns
593 ///
594 /// The value before the addition.
595 ///
596 /// # Examples
597 ///
598 /// ```rust
599 /// use qubit_atomic::Atomic;
600 ///
601 /// let atomic = Atomic::new(10);
602 /// assert_eq!(atomic.fetch_add(3), 10);
603 /// assert_eq!(atomic.load(), 13);
604 /// ```
605 #[inline(always)]
606 pub fn fetch_add(&self, delta: T) -> T {
607 AtomicNumberOps::fetch_add(&self.primitive, delta)
608 }
609
610 /// Subtracts `delta` from the value and returns the previous value.
611 ///
612 /// Integer atomics use relaxed ordering for this operation. Floating-point
613 /// atomics use a CAS loop. Integer subtraction wraps on overflow and
614 /// underflow.
615 ///
616 /// # Parameters
617 ///
618 /// * `delta` - The value to subtract.
619 ///
620 /// # Returns
621 ///
622 /// The value before the subtraction.
623 ///
624 /// # Examples
625 ///
626 /// ```rust
627 /// use qubit_atomic::Atomic;
628 ///
629 /// let atomic = Atomic::new(10);
630 /// assert_eq!(atomic.fetch_sub(3), 10);
631 /// assert_eq!(atomic.load(), 7);
632 /// ```
633 #[inline(always)]
634 pub fn fetch_sub(&self, delta: T) -> T {
635 AtomicNumberOps::fetch_sub(&self.primitive, delta)
636 }
637
638 /// Multiplies the value by `factor` and returns the previous value.
639 ///
640 /// This operation uses a CAS loop. Integer multiplication wraps on
641 /// overflow and underflow.
642 ///
643 /// # Parameters
644 ///
645 /// * `factor` - The value to multiply by.
646 ///
647 /// # Returns
648 ///
649 /// The value before the multiplication.
650 ///
651 /// # Examples
652 ///
653 /// ```rust
654 /// use qubit_atomic::Atomic;
655 ///
656 /// let atomic = Atomic::new(3);
657 /// assert_eq!(atomic.fetch_mul(4), 3);
658 /// assert_eq!(atomic.load(), 12);
659 /// ```
660 #[inline(always)]
661 pub fn fetch_mul(&self, factor: T) -> T {
662 AtomicNumberOps::fetch_mul(&self.primitive, factor)
663 }
664
665 /// Divides the value by `divisor` and returns the previous value.
666 ///
667 /// This operation uses a CAS loop. Integer division uses wrapping
668 /// semantics; for signed integers, `MIN / -1` wraps to `MIN`.
669 ///
670 /// # Parameters
671 ///
672 /// * `divisor` - The value to divide by.
673 ///
674 /// # Returns
675 ///
676 /// The value before the division.
677 ///
678 /// # Panics
679 ///
680 /// For integer specializations, panics if `divisor` is zero. Floating-point
681 /// specializations follow IEEE-754 division semantics and do not panic
682 /// solely because `divisor` is zero.
683 ///
684 /// # Examples
685 ///
686 /// ```rust
687 /// use qubit_atomic::Atomic;
688 ///
689 /// let atomic = Atomic::new(20);
690 /// assert_eq!(atomic.fetch_div(4), 20);
691 /// assert_eq!(atomic.load(), 5);
692 /// ```
693 #[inline(always)]
694 pub fn fetch_div(&self, divisor: T) -> T {
695 AtomicNumberOps::fetch_div(&self.primitive, divisor)
696 }
697}
698
699impl<T> Atomic<T>
700where
701 T: AtomicIntegerValue,
702{
703 /// Increments the value by one and returns the previous value.
704 ///
705 /// # Returns
706 ///
707 /// The value before the increment.
708 ///
709 /// # Examples
710 ///
711 /// ```rust
712 /// use qubit_atomic::Atomic;
713 ///
714 /// let atomic = Atomic::new(0);
715 /// assert_eq!(atomic.fetch_inc(), 0);
716 /// assert_eq!(atomic.load(), 1);
717 /// ```
718 #[inline(always)]
719 pub fn fetch_inc(&self) -> T {
720 T::fetch_inc(&self.primitive)
721 }
722
723 /// Increments the value by one with an explicit memory ordering and returns
724 /// the previous value.
725 ///
726 /// Arithmetic wraps on overflow, matching Rust atomic integer operations.
727 ///
728 /// # Parameters
729 ///
730 /// * `ordering` - The memory ordering used by the atomic read-modify-write
731 /// operation.
732 ///
733 /// # Returns
734 ///
735 /// The value before the increment.
736 ///
737 /// # Examples
738 ///
739 /// ```rust
740 /// use qubit_atomic::Atomic;
741 /// use std::sync::atomic::Ordering;
742 ///
743 /// let atomic = Atomic::new(0);
744 /// assert_eq!(atomic.fetch_inc_with_ordering(Ordering::AcqRel), 0);
745 /// assert_eq!(atomic.load(), 1);
746 /// ```
747 #[inline(always)]
748 pub fn fetch_inc_with_ordering(&self, ordering: Ordering) -> T {
749 T::fetch_inc_with_ordering(&self.primitive, ordering)
750 }
751
752 /// Decrements the value by one and returns the previous value.
753 ///
754 /// # Returns
755 ///
756 /// The value before the decrement.
757 ///
758 /// # Examples
759 ///
760 /// ```rust
761 /// use qubit_atomic::Atomic;
762 ///
763 /// let atomic = Atomic::new(1);
764 /// assert_eq!(atomic.fetch_dec(), 1);
765 /// assert_eq!(atomic.load(), 0);
766 /// ```
767 #[inline(always)]
768 pub fn fetch_dec(&self) -> T {
769 T::fetch_dec(&self.primitive)
770 }
771
772 /// Decrements the value by one with an explicit memory ordering and returns
773 /// the previous value.
774 ///
775 /// Arithmetic wraps on underflow, matching Rust atomic integer operations.
776 ///
777 /// # Parameters
778 ///
779 /// * `ordering` - The memory ordering used by the atomic read-modify-write
780 /// operation.
781 ///
782 /// # Returns
783 ///
784 /// The value before the decrement.
785 ///
786 /// # Examples
787 ///
788 /// ```rust
789 /// use qubit_atomic::Atomic;
790 /// use std::sync::atomic::Ordering;
791 ///
792 /// let atomic = Atomic::new(1);
793 /// assert_eq!(atomic.fetch_dec_with_ordering(Ordering::AcqRel), 1);
794 /// assert_eq!(atomic.load(), 0);
795 /// ```
796 #[inline(always)]
797 pub fn fetch_dec_with_ordering(&self, ordering: Ordering) -> T {
798 T::fetch_dec_with_ordering(&self.primitive, ordering)
799 }
800
801 /// Adds `delta` with an explicit memory ordering and returns the previous
802 /// value.
803 ///
804 /// Arithmetic wraps on overflow and underflow, matching Rust atomic integer
805 /// operations.
806 ///
807 /// # Parameters
808 ///
809 /// * `delta` - The value to add.
810 /// * `ordering` - The memory ordering used by the atomic read-modify-write
811 /// operation.
812 ///
813 /// # Returns
814 ///
815 /// The value before the addition.
816 ///
817 /// # Examples
818 ///
819 /// ```rust
820 /// use qubit_atomic::Atomic;
821 /// use std::sync::atomic::Ordering;
822 ///
823 /// let atomic = Atomic::new(10);
824 /// assert_eq!(atomic.fetch_add_with_ordering(5, Ordering::AcqRel), 10);
825 /// assert_eq!(atomic.load(), 15);
826 /// ```
827 #[inline(always)]
828 pub fn fetch_add_with_ordering(&self, delta: T, ordering: Ordering) -> T {
829 T::fetch_add_with_ordering(&self.primitive, delta, ordering)
830 }
831
832 /// Subtracts `delta` with an explicit memory ordering and returns the
833 /// previous value.
834 ///
835 /// Arithmetic wraps on overflow and underflow, matching Rust atomic integer
836 /// operations.
837 ///
838 /// # Parameters
839 ///
840 /// * `delta` - The value to subtract.
841 /// * `ordering` - The memory ordering used by the atomic read-modify-write
842 /// operation.
843 ///
844 /// # Returns
845 ///
846 /// The value before the subtraction.
847 ///
848 /// # Examples
849 ///
850 /// ```rust
851 /// use qubit_atomic::Atomic;
852 /// use std::sync::atomic::Ordering;
853 ///
854 /// let atomic = Atomic::new(10);
855 /// assert_eq!(atomic.fetch_sub_with_ordering(3, Ordering::AcqRel), 10);
856 /// assert_eq!(atomic.load(), 7);
857 /// ```
858 #[inline(always)]
859 pub fn fetch_sub_with_ordering(&self, delta: T, ordering: Ordering) -> T {
860 T::fetch_sub_with_ordering(&self.primitive, delta, ordering)
861 }
862
863 /// Applies bitwise AND and returns the previous value.
864 ///
865 /// # Parameters
866 ///
867 /// * `value` - The mask to apply.
868 ///
869 /// # Returns
870 ///
871 /// The value before the operation.
872 ///
873 /// # Examples
874 ///
875 /// ```rust
876 /// use qubit_atomic::Atomic;
877 ///
878 /// let atomic = Atomic::<u8>::new(0b1111);
879 /// assert_eq!(atomic.fetch_and(0b1010), 0b1111);
880 /// assert_eq!(atomic.load(), 0b1010);
881 /// ```
882 #[inline(always)]
883 pub fn fetch_and(&self, value: T) -> T {
884 T::fetch_and(&self.primitive, value)
885 }
886
887 /// Applies bitwise OR and returns the previous value.
888 ///
889 /// # Parameters
890 ///
891 /// * `value` - The mask to apply.
892 ///
893 /// # Returns
894 ///
895 /// The value before the operation.
896 ///
897 /// # Examples
898 ///
899 /// ```rust
900 /// use qubit_atomic::Atomic;
901 ///
902 /// let atomic = Atomic::<u8>::new(0b1000);
903 /// assert_eq!(atomic.fetch_or(0b0011), 0b1000);
904 /// assert_eq!(atomic.load(), 0b1011);
905 /// ```
906 #[inline(always)]
907 pub fn fetch_or(&self, value: T) -> T {
908 T::fetch_or(&self.primitive, value)
909 }
910
911 /// Applies bitwise XOR and returns the previous value.
912 ///
913 /// # Parameters
914 ///
915 /// * `value` - The mask to apply.
916 ///
917 /// # Returns
918 ///
919 /// The value before the operation.
920 ///
921 /// # Examples
922 ///
923 /// ```rust
924 /// use qubit_atomic::Atomic;
925 ///
926 /// let atomic = Atomic::<u8>::new(0b1111);
927 /// assert_eq!(atomic.fetch_xor(0b1010), 0b1111);
928 /// assert_eq!(atomic.load(), 0b0101);
929 /// ```
930 #[inline(always)]
931 pub fn fetch_xor(&self, value: T) -> T {
932 T::fetch_xor(&self.primitive, value)
933 }
934
935 /// Flips all bits and returns the previous value.
936 ///
937 /// # Returns
938 ///
939 /// The value before the operation.
940 ///
941 /// # Examples
942 ///
943 /// ```rust
944 /// use qubit_atomic::Atomic;
945 ///
946 /// let atomic = Atomic::<i32>::new(0);
947 /// assert_eq!(atomic.fetch_not(), 0);
948 /// assert_eq!(atomic.load(), !0);
949 /// ```
950 #[inline(always)]
951 pub fn fetch_not(&self) -> T {
952 T::fetch_not(&self.primitive)
953 }
954
955 /// Updates the value by accumulating it with `value`.
956 ///
957 /// # Parameters
958 ///
959 /// * `value` - The right-hand input to the accumulator.
960 /// * `f` - A function that combines the current value and `value`.
961 ///
962 /// # Returns
963 ///
964 /// The value before the successful update.
965 ///
966 /// The closure may be called more than once when concurrent updates cause
967 /// CAS retries.
968 ///
969 /// # Examples
970 ///
971 /// ```rust
972 /// use qubit_atomic::Atomic;
973 ///
974 /// let atomic = Atomic::new(10);
975 /// assert_eq!(atomic.fetch_accumulate(5, |a, b| a + b), 10);
976 /// assert_eq!(atomic.load(), 15);
977 /// ```
978 #[inline(always)]
979 pub fn fetch_accumulate<F>(&self, value: T, f: F) -> T
980 where
981 F: FnMut(T, T) -> T,
982 {
983 T::fetch_accumulate(&self.primitive, value, f)
984 }
985
986 /// Updates the value by accumulating it with `value` and returns the new
987 /// value.
988 ///
989 /// # Parameters
990 ///
991 /// * `value` - The right-hand input to the accumulator.
992 /// * `f` - A function that combines the current value and `value`.
993 ///
994 /// # Returns
995 ///
996 /// The value committed by the successful update.
997 ///
998 /// The closure may be called more than once when concurrent updates cause
999 /// CAS retries.
1000 ///
1001 /// # Examples
1002 ///
1003 /// ```rust
1004 /// use qubit_atomic::Atomic;
1005 ///
1006 /// let atomic = Atomic::new(10);
1007 /// assert_eq!(atomic.accumulate_and_get(5, |a, b| a + b), 15);
1008 /// assert_eq!(atomic.load(), 15);
1009 /// ```
1010 #[inline(always)]
1011 pub fn accumulate_and_get<F>(&self, value: T, f: F) -> T
1012 where
1013 F: FnMut(T, T) -> T,
1014 {
1015 T::accumulate_and_get(&self.primitive, value, f)
1016 }
1017
1018 /// Replaces the value with the maximum of the current value and `value`.
1019 ///
1020 /// # Parameters
1021 ///
1022 /// * `value` - The value to compare with the current value.
1023 ///
1024 /// # Returns
1025 ///
1026 /// The value before the operation.
1027 ///
1028 /// # Examples
1029 ///
1030 /// ```rust
1031 /// use qubit_atomic::Atomic;
1032 ///
1033 /// let atomic = Atomic::new(3);
1034 /// assert_eq!(atomic.fetch_max(10), 3);
1035 /// assert_eq!(atomic.load(), 10);
1036 /// ```
1037 #[inline(always)]
1038 pub fn fetch_max(&self, value: T) -> T {
1039 T::fetch_max(&self.primitive, value)
1040 }
1041
1042 /// Replaces the value with the minimum of the current value and `value`.
1043 ///
1044 /// # Parameters
1045 ///
1046 /// * `value` - The value to compare with the current value.
1047 ///
1048 /// # Returns
1049 ///
1050 /// The value before the operation.
1051 ///
1052 /// # Examples
1053 ///
1054 /// ```rust
1055 /// use qubit_atomic::Atomic;
1056 ///
1057 /// let atomic = Atomic::new(10);
1058 /// assert_eq!(atomic.fetch_min(3), 10);
1059 /// assert_eq!(atomic.load(), 3);
1060 /// ```
1061 #[inline(always)]
1062 pub fn fetch_min(&self, value: T) -> T {
1063 T::fetch_min(&self.primitive, value)
1064 }
1065}
1066
1067impl Atomic<bool> {
1068 /// Stores `true` and returns the previous value.
1069 ///
1070 /// # Returns
1071 ///
1072 /// The previous value.
1073 ///
1074 /// # Examples
1075 ///
1076 /// ```rust
1077 /// use qubit_atomic::Atomic;
1078 ///
1079 /// let flag = Atomic::new(false);
1080 /// assert_eq!(flag.fetch_set(), false);
1081 /// assert!(flag.load());
1082 /// ```
1083 #[inline(always)]
1084 pub fn fetch_set(&self) -> bool {
1085 self.primitive.fetch_set()
1086 }
1087
1088 /// Stores `false` and returns the previous value.
1089 ///
1090 /// # Returns
1091 ///
1092 /// The previous value.
1093 ///
1094 /// # Examples
1095 ///
1096 /// ```rust
1097 /// use qubit_atomic::Atomic;
1098 ///
1099 /// let flag = Atomic::new(true);
1100 /// assert_eq!(flag.fetch_clear(), true);
1101 /// assert!(!flag.load());
1102 /// ```
1103 #[inline(always)]
1104 pub fn fetch_clear(&self) -> bool {
1105 self.primitive.fetch_clear()
1106 }
1107
1108 /// Negates the value and returns the previous value.
1109 ///
1110 /// # Returns
1111 ///
1112 /// The previous value.
1113 ///
1114 /// # Examples
1115 ///
1116 /// ```rust
1117 /// use qubit_atomic::Atomic;
1118 ///
1119 /// let flag = Atomic::new(false);
1120 /// assert_eq!(flag.fetch_not(), false);
1121 /// assert!(flag.load());
1122 /// ```
1123 #[inline(always)]
1124 pub fn fetch_not(&self) -> bool {
1125 self.primitive.fetch_not()
1126 }
1127
1128 /// Applies logical AND and returns the previous value.
1129 ///
1130 /// # Parameters
1131 ///
1132 /// * `value` - The value to combine with the current value.
1133 ///
1134 /// # Returns
1135 ///
1136 /// The previous value.
1137 ///
1138 /// # Examples
1139 ///
1140 /// ```rust
1141 /// use qubit_atomic::Atomic;
1142 ///
1143 /// let flag = Atomic::new(true);
1144 /// assert_eq!(flag.fetch_and(false), true);
1145 /// assert!(!flag.load());
1146 /// ```
1147 #[inline(always)]
1148 pub fn fetch_and(&self, value: bool) -> bool {
1149 self.primitive.fetch_and(value)
1150 }
1151
1152 /// Applies logical OR and returns the previous value.
1153 ///
1154 /// # Parameters
1155 ///
1156 /// * `value` - The value to combine with the current value.
1157 ///
1158 /// # Returns
1159 ///
1160 /// The previous value.
1161 ///
1162 /// # Examples
1163 ///
1164 /// ```rust
1165 /// use qubit_atomic::Atomic;
1166 ///
1167 /// let flag = Atomic::new(false);
1168 /// assert_eq!(flag.fetch_or(true), false);
1169 /// assert!(flag.load());
1170 /// ```
1171 #[inline(always)]
1172 pub fn fetch_or(&self, value: bool) -> bool {
1173 self.primitive.fetch_or(value)
1174 }
1175
1176 /// Applies logical XOR and returns the previous value.
1177 ///
1178 /// # Parameters
1179 ///
1180 /// * `value` - The value to combine with the current value.
1181 ///
1182 /// # Returns
1183 ///
1184 /// The previous value.
1185 ///
1186 /// # Examples
1187 ///
1188 /// ```rust
1189 /// use qubit_atomic::Atomic;
1190 ///
1191 /// let flag = Atomic::new(true);
1192 /// assert_eq!(flag.fetch_xor(true), true);
1193 /// assert!(!flag.load());
1194 /// ```
1195 #[inline(always)]
1196 pub fn fetch_xor(&self, value: bool) -> bool {
1197 self.primitive.fetch_xor(value)
1198 }
1199
1200 /// Stores `new` only when the current value is `false`.
1201 ///
1202 /// # Parameters
1203 ///
1204 /// * `new` - The replacement value.
1205 ///
1206 /// # Returns
1207 ///
1208 /// `Ok(())` if the value was replaced.
1209 ///
1210 /// # Errors
1211 ///
1212 /// Returns `Err(true)` if the observed current value was already `true`.
1213 /// In that case, `new` is not stored.
1214 ///
1215 /// # Examples
1216 ///
1217 /// ```rust
1218 /// use qubit_atomic::Atomic;
1219 ///
1220 /// let flag = Atomic::new(false);
1221 /// assert!(flag.set_if_false(true).is_ok());
1222 /// assert!(flag.load());
1223 /// assert!(flag.set_if_false(false).is_err());
1224 /// ```
1225 #[inline(always)]
1226 pub fn set_if_false(&self, new: bool) -> Result<(), bool> {
1227 self.primitive.set_if_false(new)
1228 }
1229
1230 /// Stores `new` only when the current value is `true`.
1231 ///
1232 /// # Parameters
1233 ///
1234 /// * `new` - The replacement value.
1235 ///
1236 /// # Returns
1237 ///
1238 /// `Ok(())` if the value was replaced.
1239 ///
1240 /// # Errors
1241 ///
1242 /// Returns `Err(false)` if the observed current value was already `false`.
1243 /// In that case, `new` is not stored.
1244 ///
1245 /// # Examples
1246 ///
1247 /// ```rust
1248 /// use qubit_atomic::Atomic;
1249 ///
1250 /// let flag = Atomic::new(true);
1251 /// assert!(flag.set_if_true(false).is_ok());
1252 /// assert!(!flag.load());
1253 /// assert!(flag.set_if_true(true).is_err());
1254 /// ```
1255 #[inline(always)]
1256 pub fn set_if_true(&self, new: bool) -> Result<(), bool> {
1257 self.primitive.set_if_true(new)
1258 }
1259}
1260
1261impl<T> Default for Atomic<T>
1262where
1263 T: AtomicValue + Default,
1264{
1265 /// Creates an atomic with [`Default::default`] as the initial value.
1266 ///
1267 /// # Examples
1268 ///
1269 /// ```rust
1270 /// use qubit_atomic::Atomic;
1271 ///
1272 /// let atomic = Atomic::<i32>::default();
1273 /// assert_eq!(atomic.load(), 0);
1274 /// ```
1275 #[inline(always)]
1276 fn default() -> Self {
1277 Self::new(T::default())
1278 }
1279}
1280
1281impl<T> From<T> for Atomic<T>
1282where
1283 T: AtomicValue,
1284{
1285 /// Converts `value` into an [`Atomic`] via [`Atomic::new`].
1286 ///
1287 /// # Examples
1288 ///
1289 /// ```rust
1290 /// use qubit_atomic::Atomic;
1291 ///
1292 /// let atomic = Atomic::from(42i32);
1293 /// assert_eq!(atomic.load(), 42);
1294 /// ```
1295 #[inline(always)]
1296 fn from(value: T) -> Self {
1297 Self::new(value)
1298 }
1299}
1300
1301impl<T> fmt::Debug for Atomic<T>
1302where
1303 T: AtomicValue + fmt::Debug,
1304{
1305 /// Formats the loaded value as `Atomic { value: ... }`.
1306 ///
1307 /// # Examples
1308 ///
1309 /// ```rust
1310 /// use qubit_atomic::Atomic;
1311 ///
1312 /// let atomic = Atomic::new(7);
1313 /// assert!(format!("{:?}", atomic).contains("7"));
1314 /// ```
1315 #[inline]
1316 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1317 f.debug_struct("Atomic")
1318 .field("value", &self.load())
1319 .finish()
1320 }
1321}
1322
1323impl<T> fmt::Display for Atomic<T>
1324where
1325 T: AtomicValue + fmt::Display,
1326{
1327 /// Formats the loaded value using its [`Display`](fmt::Display)
1328 /// implementation.
1329 ///
1330 /// # Examples
1331 ///
1332 /// ```rust
1333 /// use qubit_atomic::Atomic;
1334 ///
1335 /// let atomic = Atomic::new(42);
1336 /// assert_eq!(format!("{}", atomic), "42");
1337 /// ```
1338 #[inline]
1339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1340 write!(f, "{}", self.load())
1341 }
1342}