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::{
17 fmt,
18 sync::atomic::Ordering,
19};
20
21use super::atomic_integer_value::AtomicIntegerValue;
22use super::atomic_number_ops::AtomicNumberOps;
23use super::atomic_ops::AtomicOps;
24use super::atomic_value::AtomicValue;
25
26/// A high-level atomic wrapper for supported primitive value types.
27///
28/// This type is the main entry point for primitive atomic values. It hides
29/// explicit memory-ordering parameters behind crate-defined defaults while
30/// still exposing the raw backend through [`inner`](Self::inner) for advanced
31/// use cases.
32///
33/// Supported value types are:
34///
35/// - `bool`
36/// - `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64`, `u128`, `i128`
37/// - `usize`, `isize`
38/// - `f32`, `f64`
39///
40/// The `i128` and `u128` specializations use `portable-atomic` internally
41/// because the corresponding standard-library atomic types are not yet stable.
42///
43/// # Specialization API
44///
45/// Rustdoc documents [`Atomic<T>`] as one generic type rather than generating a
46/// separate page for each concrete `T`. The following table summarizes the
47/// methods available for each specialization:
48///
49/// | Specialization | Additional methods |
50/// | --- | --- |
51/// | `Atomic<bool>` | `fetch_set`, `fetch_clear`, `fetch_not`, `fetch_and`, `fetch_or`, `fetch_xor`, `set_if_false`, `set_if_true` |
52/// | `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` |
53/// | `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` |
54/// | `Atomic<f32>`, `Atomic<f64>` | `fetch_add`, `fetch_sub`, `fetch_mul`, `fetch_div` |
55///
56/// All supported specializations also provide [`new`](Self::new),
57/// [`load`](Self::load), [`store`](Self::store), [`swap`](Self::swap),
58/// [`compare_set`](Self::compare_set),
59/// [`compare_set_weak`](Self::compare_set_weak),
60/// [`compare_and_exchange`](Self::compare_and_exchange),
61/// [`fetch_update`](Self::fetch_update),
62/// [`update_and_get`](Self::update_and_get),
63/// [`try_update`](Self::try_update),
64/// [`try_update_and_get`](Self::try_update_and_get), and
65/// [`inner`](Self::inner).
66///
67/// Integer arithmetic operations intentionally follow Rust atomic integer
68/// semantics and wrap on overflow and underflow. Use [`crate::AtomicCount`] or
69/// [`crate::AtomicSignedCount`] when overflow or underflow must be rejected
70/// instead of wrapping.
71///
72/// Floating-point compare-and-set/exchange operations compare raw
73/// [`to_bits`](f32::to_bits) representations, not [`PartialEq`]. This means
74/// distinct bit patterns that compare equal, such as `0.0` and `-0.0`, do not
75/// match for CAS, and NaN payloads must match exactly. Prefer
76/// [`compare_set`](Self::compare_set) or [`compare_set_weak`](Self::compare_set_weak)
77/// when the caller needs an explicit success indicator for `f32` or `f64`.
78///
79/// # Example
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///
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 /// `Ok(previous)` when the value was replaced, or `Err(actual)` when the
375 /// comparison failed, including possible spurious failure.
376 ///
377 /// For `Atomic<f32>` and `Atomic<f64>`, the same caveat applies to raw-bit
378 /// equality: `0.0` and `-0.0` compare equal by [`PartialEq`] but are
379 /// different CAS values. Use [`compare_set_weak`](Self::compare_set_weak)
380 /// or compare [`to_bits`](f32::to_bits) values when distinguishing success
381 /// from failure matters.
382 ///
383 /// # Example
384 ///
385 /// Weak CAS may fail spuriously; retry on `Err(actual)`.
386 ///
387 /// ```rust
388 /// use qubit_atomic::Atomic;
389 ///
390 /// let atomic = Atomic::new(5);
391 /// let mut current = 5;
392 /// loop {
393 /// match atomic.compare_and_exchange_weak(current, 10) {
394 /// Ok(previous) => {
395 /// assert_eq!(previous, current);
396 /// break;
397 /// }
398 /// Err(actual) => current = actual,
399 /// }
400 /// }
401 /// assert_eq!(atomic.load(), 10);
402 /// ```
403 #[inline]
404 pub fn compare_and_exchange_weak(&self, current: T, new: T) -> Result<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: FnMut(T) -> T,
434 {
435 AtomicOps::fetch_update(&self.primitive, f)
436 }
437
438 /// Updates the value with a function and returns the new value.
439 ///
440 /// The update uses a CAS loop until it succeeds. The closure may be called
441 /// more than once under contention.
442 ///
443 /// # Parameters
444 ///
445 /// * `f` - A function that maps the current value to the next value.
446 ///
447 /// # Returns
448 ///
449 /// The value committed by the successful update.
450 ///
451 /// # Example
452 ///
453 /// ```rust
454 /// use qubit_atomic::Atomic;
455 ///
456 /// let atomic = Atomic::new(3);
457 /// assert_eq!(atomic.update_and_get(|x| x * 2), 6);
458 /// assert_eq!(atomic.load(), 6);
459 /// ```
460 #[inline]
461 pub fn update_and_get<F>(&self, f: F) -> T
462 where
463 F: FnMut(T) -> T,
464 {
465 AtomicOps::update_and_get(&self.primitive, f)
466 }
467
468 /// Conditionally updates the value with a function.
469 ///
470 /// The update uses a CAS loop until it succeeds or the closure rejects the
471 /// observed current value by returning `None`. The closure may be called
472 /// more than once under contention.
473 ///
474 /// # Parameters
475 ///
476 /// * `f` - A function that maps the current value to `Some(next)` to update
477 /// the atomic, or `None` to leave it unchanged.
478 ///
479 /// # Returns
480 ///
481 /// `Some(old_value)` with the value before the successful update, or `None`
482 /// when `f` rejects the observed current value.
483 ///
484 /// # Example
485 ///
486 /// ```rust
487 /// use qubit_atomic::Atomic;
488 ///
489 /// let atomic = Atomic::new(3);
490 /// assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), Some(3));
491 /// assert_eq!(atomic.load(), 4);
492 /// assert_eq!(atomic.try_update(|x| (x % 2 == 1).then_some(x + 1)), None);
493 /// assert_eq!(atomic.load(), 4);
494 /// ```
495 #[inline]
496 pub fn try_update<F>(&self, f: F) -> Option<T>
497 where
498 F: FnMut(T) -> Option<T>,
499 {
500 AtomicOps::try_update(&self.primitive, f)
501 }
502
503 /// Conditionally updates the value with a function and returns the new value.
504 ///
505 /// The update uses a CAS loop until it succeeds or the closure rejects the
506 /// observed current value by returning `None`. The closure may be called
507 /// more than once under contention.
508 ///
509 /// # Parameters
510 ///
511 /// * `f` - A function that maps the current value to `Some(next)` to update
512 /// the atomic, or `None` to leave it unchanged.
513 ///
514 /// # Returns
515 ///
516 /// `Some(new_value)` with the value committed by the successful update, or
517 /// `None` when `f` rejects the observed current value.
518 ///
519 /// # Example
520 ///
521 /// ```rust
522 /// use qubit_atomic::Atomic;
523 ///
524 /// let atomic = Atomic::new(3);
525 /// assert_eq!(
526 /// atomic.try_update_and_get(|x| (x % 2 == 1).then_some(x + 1)),
527 /// Some(4),
528 /// );
529 /// assert_eq!(atomic.load(), 4);
530 /// assert_eq!(
531 /// atomic.try_update_and_get(|x| (x % 2 == 1).then_some(x + 1)),
532 /// None,
533 /// );
534 /// assert_eq!(atomic.load(), 4);
535 /// ```
536 #[inline]
537 pub fn try_update_and_get<F>(&self, f: F) -> Option<T>
538 where
539 F: FnMut(T) -> Option<T>,
540 {
541 AtomicOps::try_update_and_get(&self.primitive, f)
542 }
543
544 /// Returns the raw backend atomic value.
545 ///
546 /// Use this method only when the default orderings are not appropriate
547 /// and the caller needs direct access to the backend atomic storage.
548 ///
549 /// # Returns
550 ///
551 /// A shared reference to the raw backend atomic value.
552 ///
553 /// # Example
554 ///
555 /// ```rust
556 /// use qubit_atomic::Atomic;
557 /// use std::sync::atomic::Ordering;
558 ///
559 /// let atomic = Atomic::<i32>::new(0);
560 /// assert_eq!(atomic.inner().load(Ordering::Relaxed), 0);
561 /// ```
562 #[inline]
563 pub fn inner(&self) -> &T::Inner {
564 T::inner(&self.primitive)
565 }
566}
567
568impl<T> Atomic<T>
569where
570 T: AtomicValue,
571 T::Primitive: AtomicNumberOps<Value = T>,
572{
573 /// Adds `delta` to the value and returns the previous value.
574 ///
575 /// Integer atomics use relaxed ordering for this operation. Floating-point
576 /// atomics use a CAS loop. Integer addition wraps on overflow and
577 /// underflow.
578 ///
579 /// # Parameters
580 ///
581 /// * `delta` - The value to add.
582 ///
583 /// # Returns
584 ///
585 /// The value before the addition.
586 ///
587 /// # Example
588 ///
589 /// ```rust
590 /// use qubit_atomic::Atomic;
591 ///
592 /// let atomic = Atomic::new(10);
593 /// assert_eq!(atomic.fetch_add(3), 10);
594 /// assert_eq!(atomic.load(), 13);
595 /// ```
596 #[inline]
597 pub fn fetch_add(&self, delta: T) -> T {
598 AtomicNumberOps::fetch_add(&self.primitive, delta)
599 }
600
601 /// Subtracts `delta` from the value and returns the previous value.
602 ///
603 /// Integer atomics use relaxed ordering for this operation. Floating-point
604 /// atomics use a CAS loop. Integer subtraction wraps on overflow and
605 /// underflow.
606 ///
607 /// # Parameters
608 ///
609 /// * `delta` - The value to subtract.
610 ///
611 /// # Returns
612 ///
613 /// The value before the subtraction.
614 ///
615 /// # Example
616 ///
617 /// ```rust
618 /// use qubit_atomic::Atomic;
619 ///
620 /// let atomic = Atomic::new(10);
621 /// assert_eq!(atomic.fetch_sub(3), 10);
622 /// assert_eq!(atomic.load(), 7);
623 /// ```
624 #[inline]
625 pub fn fetch_sub(&self, delta: T) -> T {
626 AtomicNumberOps::fetch_sub(&self.primitive, delta)
627 }
628
629 /// Multiplies the value by `factor` and returns the previous value.
630 ///
631 /// This operation uses a CAS loop. Integer multiplication wraps on
632 /// overflow and underflow.
633 ///
634 /// # Parameters
635 ///
636 /// * `factor` - The value to multiply by.
637 ///
638 /// # Returns
639 ///
640 /// The value before the multiplication.
641 ///
642 /// # Example
643 ///
644 /// ```rust
645 /// use qubit_atomic::Atomic;
646 ///
647 /// let atomic = Atomic::new(3);
648 /// assert_eq!(atomic.fetch_mul(4), 3);
649 /// assert_eq!(atomic.load(), 12);
650 /// ```
651 #[inline]
652 pub fn fetch_mul(&self, factor: T) -> T {
653 AtomicNumberOps::fetch_mul(&self.primitive, factor)
654 }
655
656 /// Divides the value by `divisor` and returns the previous value.
657 ///
658 /// This operation uses a CAS loop. Integer division uses wrapping
659 /// semantics; for signed integers, `MIN / -1` wraps to `MIN`.
660 ///
661 /// # Parameters
662 ///
663 /// * `divisor` - The value to divide by.
664 ///
665 /// # Returns
666 ///
667 /// The value before the division.
668 ///
669 /// # Panics
670 ///
671 /// For integer specializations, panics if `divisor` is zero. Floating-point
672 /// specializations follow IEEE-754 division semantics and do not panic
673 /// solely because `divisor` is zero.
674 ///
675 /// # Example
676 ///
677 /// ```rust
678 /// use qubit_atomic::Atomic;
679 ///
680 /// let atomic = Atomic::new(20);
681 /// assert_eq!(atomic.fetch_div(4), 20);
682 /// assert_eq!(atomic.load(), 5);
683 /// ```
684 #[inline]
685 pub fn fetch_div(&self, divisor: T) -> T {
686 AtomicNumberOps::fetch_div(&self.primitive, divisor)
687 }
688}
689
690impl<T> Atomic<T>
691where
692 T: AtomicIntegerValue,
693{
694 /// Increments the value by one and returns the previous value.
695 ///
696 /// # Returns
697 ///
698 /// The value before the increment.
699 ///
700 /// # Example
701 ///
702 /// ```rust
703 /// use qubit_atomic::Atomic;
704 ///
705 /// let atomic = Atomic::new(0);
706 /// assert_eq!(atomic.fetch_inc(), 0);
707 /// assert_eq!(atomic.load(), 1);
708 /// ```
709 #[inline]
710 pub fn fetch_inc(&self) -> T {
711 T::fetch_inc(&self.primitive)
712 }
713
714 /// Increments the value by one with an explicit memory ordering and returns
715 /// the previous value.
716 ///
717 /// Arithmetic wraps on overflow, matching Rust atomic integer operations.
718 ///
719 /// # Parameters
720 ///
721 /// * `ordering` - The memory ordering used by the atomic read-modify-write
722 /// operation.
723 ///
724 /// # Returns
725 ///
726 /// The value before the increment.
727 ///
728 /// # Example
729 ///
730 /// ```rust
731 /// use qubit_atomic::Atomic;
732 /// use std::sync::atomic::Ordering;
733 ///
734 /// let atomic = Atomic::new(0);
735 /// assert_eq!(atomic.fetch_inc_with_ordering(Ordering::AcqRel), 0);
736 /// assert_eq!(atomic.load(), 1);
737 /// ```
738 #[inline]
739 pub fn fetch_inc_with_ordering(&self, ordering: Ordering) -> T {
740 T::fetch_inc_with_ordering(&self.primitive, ordering)
741 }
742
743 /// Decrements the value by one and returns the previous value.
744 ///
745 /// # Returns
746 ///
747 /// The value before the decrement.
748 ///
749 /// # Example
750 ///
751 /// ```rust
752 /// use qubit_atomic::Atomic;
753 ///
754 /// let atomic = Atomic::new(1);
755 /// assert_eq!(atomic.fetch_dec(), 1);
756 /// assert_eq!(atomic.load(), 0);
757 /// ```
758 #[inline]
759 pub fn fetch_dec(&self) -> T {
760 T::fetch_dec(&self.primitive)
761 }
762
763 /// Decrements the value by one with an explicit memory ordering and returns
764 /// the previous value.
765 ///
766 /// Arithmetic wraps on underflow, matching Rust atomic integer operations.
767 ///
768 /// # Parameters
769 ///
770 /// * `ordering` - The memory ordering used by the atomic read-modify-write
771 /// operation.
772 ///
773 /// # Returns
774 ///
775 /// The value before the decrement.
776 ///
777 /// # Example
778 ///
779 /// ```rust
780 /// use qubit_atomic::Atomic;
781 /// use std::sync::atomic::Ordering;
782 ///
783 /// let atomic = Atomic::new(1);
784 /// assert_eq!(atomic.fetch_dec_with_ordering(Ordering::AcqRel), 1);
785 /// assert_eq!(atomic.load(), 0);
786 /// ```
787 #[inline]
788 pub fn fetch_dec_with_ordering(&self, ordering: Ordering) -> T {
789 T::fetch_dec_with_ordering(&self.primitive, ordering)
790 }
791
792 /// Adds `delta` with an explicit memory ordering and returns the previous
793 /// value.
794 ///
795 /// Arithmetic wraps on overflow and underflow, matching Rust atomic integer
796 /// operations.
797 ///
798 /// # Parameters
799 ///
800 /// * `delta` - The value to add.
801 /// * `ordering` - The memory ordering used by the atomic read-modify-write
802 /// operation.
803 ///
804 /// # Returns
805 ///
806 /// The value before the addition.
807 ///
808 /// # Example
809 ///
810 /// ```rust
811 /// use qubit_atomic::Atomic;
812 /// use std::sync::atomic::Ordering;
813 ///
814 /// let atomic = Atomic::new(10);
815 /// assert_eq!(atomic.fetch_add_with_ordering(5, Ordering::AcqRel), 10);
816 /// assert_eq!(atomic.load(), 15);
817 /// ```
818 #[inline]
819 pub fn fetch_add_with_ordering(&self, delta: T, ordering: Ordering) -> T {
820 T::fetch_add_with_ordering(&self.primitive, delta, ordering)
821 }
822
823 /// Subtracts `delta` with an explicit memory ordering and returns the
824 /// previous value.
825 ///
826 /// Arithmetic wraps on overflow and underflow, matching Rust atomic integer
827 /// operations.
828 ///
829 /// # Parameters
830 ///
831 /// * `delta` - The value to subtract.
832 /// * `ordering` - The memory ordering used by the atomic read-modify-write
833 /// operation.
834 ///
835 /// # Returns
836 ///
837 /// The value before the subtraction.
838 ///
839 /// # Example
840 ///
841 /// ```rust
842 /// use qubit_atomic::Atomic;
843 /// use std::sync::atomic::Ordering;
844 ///
845 /// let atomic = Atomic::new(10);
846 /// assert_eq!(atomic.fetch_sub_with_ordering(3, Ordering::AcqRel), 10);
847 /// assert_eq!(atomic.load(), 7);
848 /// ```
849 #[inline]
850 pub fn fetch_sub_with_ordering(&self, delta: T, ordering: Ordering) -> T {
851 T::fetch_sub_with_ordering(&self.primitive, delta, ordering)
852 }
853
854 /// Applies bitwise AND and returns the previous value.
855 ///
856 /// # Parameters
857 ///
858 /// * `value` - The mask to apply.
859 ///
860 /// # Returns
861 ///
862 /// The value before the operation.
863 ///
864 /// # Example
865 ///
866 /// ```rust
867 /// use qubit_atomic::Atomic;
868 ///
869 /// let atomic = Atomic::<u8>::new(0b1111);
870 /// assert_eq!(atomic.fetch_and(0b1010), 0b1111);
871 /// assert_eq!(atomic.load(), 0b1010);
872 /// ```
873 #[inline]
874 pub fn fetch_and(&self, value: T) -> T {
875 T::fetch_and(&self.primitive, value)
876 }
877
878 /// Applies bitwise OR and returns the previous value.
879 ///
880 /// # Parameters
881 ///
882 /// * `value` - The mask to apply.
883 ///
884 /// # Returns
885 ///
886 /// The value before the operation.
887 ///
888 /// # Example
889 ///
890 /// ```rust
891 /// use qubit_atomic::Atomic;
892 ///
893 /// let atomic = Atomic::<u8>::new(0b1000);
894 /// assert_eq!(atomic.fetch_or(0b0011), 0b1000);
895 /// assert_eq!(atomic.load(), 0b1011);
896 /// ```
897 #[inline]
898 pub fn fetch_or(&self, value: T) -> T {
899 T::fetch_or(&self.primitive, value)
900 }
901
902 /// Applies bitwise XOR and returns the previous value.
903 ///
904 /// # Parameters
905 ///
906 /// * `value` - The mask to apply.
907 ///
908 /// # Returns
909 ///
910 /// The value before the operation.
911 ///
912 /// # Example
913 ///
914 /// ```rust
915 /// use qubit_atomic::Atomic;
916 ///
917 /// let atomic = Atomic::<u8>::new(0b1111);
918 /// assert_eq!(atomic.fetch_xor(0b1010), 0b1111);
919 /// assert_eq!(atomic.load(), 0b0101);
920 /// ```
921 #[inline]
922 pub fn fetch_xor(&self, value: T) -> T {
923 T::fetch_xor(&self.primitive, value)
924 }
925
926 /// Flips all bits and returns the previous value.
927 ///
928 /// # Returns
929 ///
930 /// The value before the operation.
931 ///
932 /// # Example
933 ///
934 /// ```rust
935 /// use qubit_atomic::Atomic;
936 ///
937 /// let atomic = Atomic::<i32>::new(0);
938 /// assert_eq!(atomic.fetch_not(), 0);
939 /// assert_eq!(atomic.load(), !0);
940 /// ```
941 #[inline]
942 pub fn fetch_not(&self) -> T {
943 T::fetch_not(&self.primitive)
944 }
945
946 /// Updates the value by accumulating it with `value`.
947 ///
948 /// # Parameters
949 ///
950 /// * `value` - The right-hand input to the accumulator.
951 /// * `f` - A function that combines the current value and `value`.
952 ///
953 /// # Returns
954 ///
955 /// The value before the successful update.
956 ///
957 /// The closure may be called more than once when concurrent updates cause
958 /// CAS retries.
959 ///
960 /// # Example
961 ///
962 /// ```rust
963 /// use qubit_atomic::Atomic;
964 ///
965 /// let atomic = Atomic::new(10);
966 /// assert_eq!(atomic.fetch_accumulate(5, |a, b| a + b), 10);
967 /// assert_eq!(atomic.load(), 15);
968 /// ```
969 #[inline]
970 pub fn fetch_accumulate<F>(&self, value: T, f: F) -> T
971 where
972 F: FnMut(T, T) -> T,
973 {
974 T::fetch_accumulate(&self.primitive, value, f)
975 }
976
977 /// Updates the value by accumulating it with `value` and returns the new value.
978 ///
979 /// # Parameters
980 ///
981 /// * `value` - The right-hand input to the accumulator.
982 /// * `f` - A function that combines the current value and `value`.
983 ///
984 /// # Returns
985 ///
986 /// The value committed by the successful update.
987 ///
988 /// The closure may be called more than once when concurrent updates cause
989 /// CAS retries.
990 ///
991 /// # Example
992 ///
993 /// ```rust
994 /// use qubit_atomic::Atomic;
995 ///
996 /// let atomic = Atomic::new(10);
997 /// assert_eq!(atomic.accumulate_and_get(5, |a, b| a + b), 15);
998 /// assert_eq!(atomic.load(), 15);
999 /// ```
1000 #[inline]
1001 pub fn accumulate_and_get<F>(&self, value: T, f: F) -> T
1002 where
1003 F: FnMut(T, T) -> T,
1004 {
1005 T::accumulate_and_get(&self.primitive, value, f)
1006 }
1007
1008 /// Replaces the value with the maximum of the current value and `value`.
1009 ///
1010 /// # Parameters
1011 ///
1012 /// * `value` - The value to compare with the current value.
1013 ///
1014 /// # Returns
1015 ///
1016 /// The value before the operation.
1017 ///
1018 /// # Example
1019 ///
1020 /// ```rust
1021 /// use qubit_atomic::Atomic;
1022 ///
1023 /// let atomic = Atomic::new(3);
1024 /// assert_eq!(atomic.fetch_max(10), 3);
1025 /// assert_eq!(atomic.load(), 10);
1026 /// ```
1027 #[inline]
1028 pub fn fetch_max(&self, value: T) -> T {
1029 T::fetch_max(&self.primitive, value)
1030 }
1031
1032 /// Replaces the value with the minimum of the current value and `value`.
1033 ///
1034 /// # Parameters
1035 ///
1036 /// * `value` - The value to compare with the current value.
1037 ///
1038 /// # Returns
1039 ///
1040 /// The value before the operation.
1041 ///
1042 /// # Example
1043 ///
1044 /// ```rust
1045 /// use qubit_atomic::Atomic;
1046 ///
1047 /// let atomic = Atomic::new(10);
1048 /// assert_eq!(atomic.fetch_min(3), 10);
1049 /// assert_eq!(atomic.load(), 3);
1050 /// ```
1051 #[inline]
1052 pub fn fetch_min(&self, value: T) -> T {
1053 T::fetch_min(&self.primitive, value)
1054 }
1055}
1056
1057impl Atomic<bool> {
1058 /// Stores `true` and returns the previous value.
1059 ///
1060 /// # Returns
1061 ///
1062 /// The previous value.
1063 ///
1064 /// # Example
1065 ///
1066 /// ```rust
1067 /// use qubit_atomic::Atomic;
1068 ///
1069 /// let flag = Atomic::new(false);
1070 /// assert_eq!(flag.fetch_set(), false);
1071 /// assert!(flag.load());
1072 /// ```
1073 #[inline]
1074 pub fn fetch_set(&self) -> bool {
1075 self.primitive.fetch_set()
1076 }
1077
1078 /// Stores `false` and returns the previous value.
1079 ///
1080 /// # Returns
1081 ///
1082 /// The previous value.
1083 ///
1084 /// # Example
1085 ///
1086 /// ```rust
1087 /// use qubit_atomic::Atomic;
1088 ///
1089 /// let flag = Atomic::new(true);
1090 /// assert_eq!(flag.fetch_clear(), true);
1091 /// assert!(!flag.load());
1092 /// ```
1093 #[inline]
1094 pub fn fetch_clear(&self) -> bool {
1095 self.primitive.fetch_clear()
1096 }
1097
1098 /// Negates the value and returns the previous value.
1099 ///
1100 /// # Returns
1101 ///
1102 /// The previous value.
1103 ///
1104 /// # Example
1105 ///
1106 /// ```rust
1107 /// use qubit_atomic::Atomic;
1108 ///
1109 /// let flag = Atomic::new(false);
1110 /// assert_eq!(flag.fetch_not(), false);
1111 /// assert!(flag.load());
1112 /// ```
1113 #[inline]
1114 pub fn fetch_not(&self) -> bool {
1115 self.primitive.fetch_not()
1116 }
1117
1118 /// Applies logical AND and returns the previous value.
1119 ///
1120 /// # Parameters
1121 ///
1122 /// * `value` - The value to combine with the current value.
1123 ///
1124 /// # Returns
1125 ///
1126 /// The previous value.
1127 ///
1128 /// # Example
1129 ///
1130 /// ```rust
1131 /// use qubit_atomic::Atomic;
1132 ///
1133 /// let flag = Atomic::new(true);
1134 /// assert_eq!(flag.fetch_and(false), true);
1135 /// assert!(!flag.load());
1136 /// ```
1137 #[inline]
1138 pub fn fetch_and(&self, value: bool) -> bool {
1139 self.primitive.fetch_and(value)
1140 }
1141
1142 /// Applies logical OR and returns the previous value.
1143 ///
1144 /// # Parameters
1145 ///
1146 /// * `value` - The value to combine with the current value.
1147 ///
1148 /// # Returns
1149 ///
1150 /// The previous value.
1151 ///
1152 /// # Example
1153 ///
1154 /// ```rust
1155 /// use qubit_atomic::Atomic;
1156 ///
1157 /// let flag = Atomic::new(false);
1158 /// assert_eq!(flag.fetch_or(true), false);
1159 /// assert!(flag.load());
1160 /// ```
1161 #[inline]
1162 pub fn fetch_or(&self, value: bool) -> bool {
1163 self.primitive.fetch_or(value)
1164 }
1165
1166 /// Applies logical XOR and returns the previous value.
1167 ///
1168 /// # Parameters
1169 ///
1170 /// * `value` - The value to combine with the current value.
1171 ///
1172 /// # Returns
1173 ///
1174 /// The previous value.
1175 ///
1176 /// # Example
1177 ///
1178 /// ```rust
1179 /// use qubit_atomic::Atomic;
1180 ///
1181 /// let flag = Atomic::new(true);
1182 /// assert_eq!(flag.fetch_xor(true), true);
1183 /// assert!(!flag.load());
1184 /// ```
1185 #[inline]
1186 pub fn fetch_xor(&self, value: bool) -> bool {
1187 self.primitive.fetch_xor(value)
1188 }
1189
1190 /// Stores `new` only when the current value is `false`.
1191 ///
1192 /// # Parameters
1193 ///
1194 /// * `new` - The replacement value.
1195 ///
1196 /// # Returns
1197 ///
1198 /// `Ok(())` if the value was replaced.
1199 ///
1200 /// # Errors
1201 ///
1202 /// Returns `Err(true)` if the observed current value was already `true`.
1203 /// In that case, `new` is not stored.
1204 ///
1205 /// # Example
1206 ///
1207 /// ```rust
1208 /// use qubit_atomic::Atomic;
1209 ///
1210 /// let flag = Atomic::new(false);
1211 /// assert!(flag.set_if_false(true).is_ok());
1212 /// assert!(flag.load());
1213 /// assert!(flag.set_if_false(false).is_err());
1214 /// ```
1215 #[inline]
1216 pub fn set_if_false(&self, new: bool) -> Result<(), bool> {
1217 self.primitive.set_if_false(new)
1218 }
1219
1220 /// Stores `new` only when the current value is `true`.
1221 ///
1222 /// # Parameters
1223 ///
1224 /// * `new` - The replacement value.
1225 ///
1226 /// # Returns
1227 ///
1228 /// `Ok(())` if the value was replaced.
1229 ///
1230 /// # Errors
1231 ///
1232 /// Returns `Err(false)` if the observed current value was already `false`.
1233 /// In that case, `new` is not stored.
1234 ///
1235 /// # Example
1236 ///
1237 /// ```rust
1238 /// use qubit_atomic::Atomic;
1239 ///
1240 /// let flag = Atomic::new(true);
1241 /// assert!(flag.set_if_true(false).is_ok());
1242 /// assert!(!flag.load());
1243 /// assert!(flag.set_if_true(true).is_err());
1244 /// ```
1245 #[inline]
1246 pub fn set_if_true(&self, new: bool) -> Result<(), bool> {
1247 self.primitive.set_if_true(new)
1248 }
1249}
1250
1251impl<T> Default for Atomic<T>
1252where
1253 T: AtomicValue + Default,
1254{
1255 /// Creates an atomic with [`Default::default`] as the initial value.
1256 ///
1257 /// # Example
1258 ///
1259 /// ```rust
1260 /// use qubit_atomic::Atomic;
1261 ///
1262 /// let atomic = Atomic::<i32>::default();
1263 /// assert_eq!(atomic.load(), 0);
1264 /// ```
1265 #[inline]
1266 fn default() -> Self {
1267 Self::new(T::default())
1268 }
1269}
1270
1271impl<T> From<T> for Atomic<T>
1272where
1273 T: AtomicValue,
1274{
1275 /// Converts `value` into an [`Atomic`] via [`Atomic::new`].
1276 ///
1277 /// # Example
1278 ///
1279 /// ```rust
1280 /// use qubit_atomic::Atomic;
1281 ///
1282 /// let atomic = Atomic::from(42i32);
1283 /// assert_eq!(atomic.load(), 42);
1284 /// ```
1285 #[inline]
1286 fn from(value: T) -> Self {
1287 Self::new(value)
1288 }
1289}
1290
1291impl<T> fmt::Debug for Atomic<T>
1292where
1293 T: AtomicValue + fmt::Debug,
1294{
1295 /// Formats the loaded value as `Atomic { value: ... }`.
1296 ///
1297 /// # Example
1298 ///
1299 /// ```rust
1300 /// use qubit_atomic::Atomic;
1301 ///
1302 /// let atomic = Atomic::new(7);
1303 /// assert!(format!("{:?}", atomic).contains("7"));
1304 /// ```
1305 #[inline]
1306 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1307 f.debug_struct("Atomic")
1308 .field("value", &self.load())
1309 .finish()
1310 }
1311}
1312
1313impl<T> fmt::Display for Atomic<T>
1314where
1315 T: AtomicValue + fmt::Display,
1316{
1317 /// Formats the loaded value using its [`Display`](fmt::Display) implementation.
1318 ///
1319 /// # Example
1320 ///
1321 /// ```rust
1322 /// use qubit_atomic::Atomic;
1323 ///
1324 /// let atomic = Atomic::new(42);
1325 /// assert_eq!(format!("{}", atomic), "42");
1326 /// ```
1327 #[inline]
1328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1329 write!(f, "{}", self.load())
1330 }
1331}