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