qubit_atomic/atomic/atomic_bool.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//! # Atomic Boolean
10//!
11//! Provides an easy-to-use atomic boolean type with sensible default memory
12//! orderings.
13
14use std::sync::atomic::AtomicBool as StdAtomicBool;
15use std::sync::atomic::Ordering;
16
17use crate::atomic::atomic_ops::AtomicOps;
18
19/// Atomic boolean type.
20///
21/// Provides easy-to-use atomic operations with automatic memory ordering
22/// selection. All methods are thread-safe and can be shared across threads.
23///
24/// # Memory Ordering Strategy
25///
26/// This type uses carefully selected default memory orderings:
27///
28/// - **Read operations** (`load`): Use `Acquire` ordering to ensure that all
29/// writes from other threads that happened before a `Release` store are
30/// visible after this load.
31///
32/// - **Write operations** (`store`): Use `Release` ordering to ensure that all
33/// prior writes in this thread are visible to other threads that perform an
34/// `Acquire` load.
35///
36/// - **Read-Modify-Write operations** (`swap`, `compare_set`, `fetch_*`): Use
37/// `AcqRel` ordering to combine both `Acquire` and `Release` semantics,
38/// ensuring proper synchronization in both directions.
39///
40/// - **CAS failure**: Use `Acquire` ordering on failure to observe the actual
41/// value written by another thread.
42///
43/// These orderings provide a balance between performance and correctness
44/// for typical concurrent programming patterns.
45///
46/// # Features
47///
48/// - Automatic memory ordering selection
49/// - Rich set of boolean-specific operations
50/// - Thin `#[repr(transparent)]` wrapper with inline forwarding methods
51/// - Access to underlying type via `inner()` for advanced use cases
52///
53/// # Example
54///
55/// ```rust
56/// use qubit_atomic::Atomic;
57/// use std::sync::Arc;
58/// use std::thread;
59///
60/// let flag = Arc::new(Atomic::<bool>::new(false));
61/// let flag_clone = flag.clone();
62///
63/// let handle = thread::spawn(move || {
64/// flag_clone.store(true);
65/// });
66///
67/// handle.join().unwrap();
68/// assert_eq!(flag.load(), true);
69/// ```
70#[repr(transparent)]
71pub struct AtomicBool {
72 /// Standard-library atomic boolean used as the storage backend.
73 inner: StdAtomicBool,
74}
75
76impl AtomicBool {
77 /// Creates a new atomic boolean.
78 ///
79 /// # Parameters
80 ///
81 /// * `value` - The initial value.
82 ///
83 /// # Returns
84 ///
85 /// An atomic boolean initialized to `value`.
86 ///
87 /// # Example
88 ///
89 /// ```rust
90 /// use qubit_atomic::Atomic;
91 ///
92 /// let flag = Atomic::<bool>::new(false);
93 /// assert_eq!(flag.load(), false);
94 /// ```
95 #[inline]
96 pub const fn new(value: bool) -> Self {
97 Self {
98 inner: StdAtomicBool::new(value),
99 }
100 }
101
102 /// Gets the current value.
103 ///
104 /// # Memory Ordering
105 ///
106 /// Uses `Acquire` ordering. This ensures that:
107 /// - All writes from other threads that happened before a `Release` store
108 /// are visible after this load.
109 /// - Forms a synchronizes-with relationship with `Release` stores.
110 /// - Prevents reordering of subsequent reads/writes before this load.
111 ///
112 /// This is appropriate for reading shared state that may have been
113 /// modified by other threads.
114 ///
115 /// # Returns
116 ///
117 /// The current value.
118 ///
119 /// # Example
120 ///
121 /// ```rust
122 /// use qubit_atomic::Atomic;
123 ///
124 /// let flag = Atomic::<bool>::new(true);
125 /// assert_eq!(flag.load(), true);
126 /// ```
127 #[inline]
128 pub fn load(&self) -> bool {
129 self.inner.load(Ordering::Acquire)
130 }
131
132 /// Sets a new value.
133 ///
134 /// # Memory Ordering
135 ///
136 /// Uses `Release` ordering. This ensures that:
137 /// - All prior writes in this thread are visible to other threads that
138 /// perform an `Acquire` load.
139 /// - Forms a synchronizes-with relationship with `Acquire` loads.
140 /// - Prevents reordering of prior reads/writes after this store.
141 ///
142 /// This is appropriate for publishing shared state to other threads.
143 ///
144 /// # Parameters
145 ///
146 /// * `value` - The new value to set.
147 ///
148 /// # Example
149 ///
150 /// ```rust
151 /// use qubit_atomic::Atomic;
152 ///
153 /// let flag = Atomic::<bool>::new(false);
154 /// flag.store(true);
155 /// assert_eq!(flag.load(), true);
156 /// ```
157 #[inline]
158 pub fn store(&self, value: bool) {
159 self.inner.store(value, Ordering::Release);
160 }
161
162 /// Swaps the current value with a new value, returning the old value.
163 ///
164 /// # Memory Ordering
165 ///
166 /// Uses `AcqRel` ordering. This ensures that:
167 /// - **Acquire**: All writes from other threads that happened before their
168 /// `Release` operations are visible after this operation.
169 /// - **Release**: All prior writes in this thread are visible to other
170 /// threads that perform subsequent `Acquire` operations.
171 ///
172 /// This provides full synchronization for read-modify-write operations.
173 ///
174 /// # Parameters
175 ///
176 /// * `value` - The new value to swap in.
177 ///
178 /// # Returns
179 ///
180 /// The old value.
181 ///
182 /// # Example
183 ///
184 /// ```rust
185 /// use qubit_atomic::Atomic;
186 ///
187 /// let flag = Atomic::<bool>::new(false);
188 /// let old = flag.swap(true);
189 /// assert_eq!(old, false);
190 /// assert_eq!(flag.load(), true);
191 /// ```
192 #[inline]
193 pub fn swap(&self, value: bool) -> bool {
194 self.inner.swap(value, Ordering::AcqRel)
195 }
196
197 /// Compares and sets the value atomically.
198 ///
199 /// If the current value equals `current`, sets it to `new` and returns
200 /// `Ok(())`. Otherwise, returns `Err(actual)` where `actual` is the
201 /// current value.
202 ///
203 /// # Memory Ordering
204 ///
205 /// - **Success**: Uses `AcqRel` ordering to ensure full synchronization
206 /// when the exchange succeeds.
207 /// - **Failure**: Uses `Acquire` ordering to observe the actual value
208 /// written by another thread.
209 ///
210 /// This pattern is essential for implementing lock-free algorithms where
211 /// you need to retry based on the observed value.
212 ///
213 /// # Parameters
214 ///
215 /// * `current` - The expected current value.
216 /// * `new` - The new value to set if current matches.
217 ///
218 /// # Returns
219 ///
220 /// `Ok(())` when the value was replaced.
221 ///
222 /// # Errors
223 ///
224 /// Returns `Err(actual)` with the observed value when the comparison
225 /// fails. In that case, `new` is not stored.
226 ///
227 /// # Example
228 ///
229 /// ```rust
230 /// use qubit_atomic::Atomic;
231 ///
232 /// let flag = Atomic::<bool>::new(false);
233 /// assert!(flag.compare_set(false, true).is_ok());
234 /// assert_eq!(flag.load(), true);
235 ///
236 /// // Fails because current value is true, not false
237 /// assert!(flag.compare_set(false, false).is_err());
238 /// ```
239 #[inline]
240 pub fn compare_set(&self, current: bool, new: bool) -> Result<(), bool> {
241 self.inner
242 .compare_exchange(current, new, Ordering::AcqRel, Ordering::Acquire)
243 .map(|_| ())
244 }
245
246 /// Weak version of compare-and-set.
247 ///
248 /// May spuriously fail even when the comparison succeeds. Should be used
249 /// in a loop.
250 ///
251 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
252 ///
253 /// # Parameters
254 ///
255 /// * `current` - The expected current value.
256 /// * `new` - The new value to set if current matches.
257 ///
258 /// # Returns
259 ///
260 /// `Ok(())` when the value was replaced.
261 ///
262 /// # Errors
263 ///
264 /// Returns `Err(actual)` with the observed value when the comparison
265 /// fails, including possible spurious failures. In that case, `new` is not
266 /// stored.
267 ///
268 /// # Example
269 ///
270 /// ```rust
271 /// use qubit_atomic::Atomic;
272 ///
273 /// let flag = Atomic::<bool>::new(false);
274 /// let mut current = flag.load();
275 /// loop {
276 /// match flag.compare_set_weak(current, true) {
277 /// Ok(_) => break,
278 /// Err(actual) => current = actual,
279 /// }
280 /// }
281 /// assert_eq!(flag.load(), true);
282 /// ```
283 #[inline]
284 pub fn compare_set_weak(
285 &self,
286 current: bool,
287 new: bool,
288 ) -> Result<(), bool> {
289 self.inner
290 .compare_exchange_weak(
291 current,
292 new,
293 Ordering::AcqRel,
294 Ordering::Acquire,
295 )
296 .map(|_| ())
297 }
298
299 /// Compares and exchanges the value atomically, returning the previous
300 /// value.
301 ///
302 /// If the current value equals `current`, sets it to `new` and returns
303 /// the old value. Otherwise, returns the actual current value.
304 ///
305 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
306 ///
307 /// # Parameters
308 ///
309 /// * `current` - The expected current value.
310 /// * `new` - The new value to set if current matches.
311 ///
312 /// # Returns
313 ///
314 /// The value observed before the operation completed. If the returned
315 /// value equals `current`, the exchange succeeded; otherwise it is the
316 /// actual value that prevented the exchange.
317 ///
318 /// # Example
319 ///
320 /// ```rust
321 /// use qubit_atomic::Atomic;
322 ///
323 /// let flag = Atomic::<bool>::new(false);
324 /// let prev = flag.compare_and_exchange(false, true);
325 /// assert_eq!(prev, false);
326 /// assert_eq!(flag.load(), true);
327 /// ```
328 #[inline]
329 pub fn compare_and_exchange(&self, current: bool, new: bool) -> bool {
330 match self.inner.compare_exchange(
331 current,
332 new,
333 Ordering::AcqRel,
334 Ordering::Acquire,
335 ) {
336 Ok(prev) => prev,
337 Err(actual) => actual,
338 }
339 }
340
341 /// Weak version of compare-and-exchange.
342 ///
343 /// May spuriously fail even when the comparison succeeds. Should be used
344 /// in a loop.
345 ///
346 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
347 ///
348 /// # Parameters
349 ///
350 /// * `current` - The expected current value.
351 /// * `new` - The new value to set if current matches.
352 ///
353 /// # Returns
354 ///
355 /// `Ok(previous)` when the value was replaced, or `Err(actual)` when the
356 /// comparison failed, including possible spurious failure.
357 ///
358 /// # Example
359 ///
360 /// ```rust
361 /// use qubit_atomic::Atomic;
362 ///
363 /// let flag = Atomic::<bool>::new(false);
364 /// let mut current = flag.load();
365 /// loop {
366 /// match flag.compare_and_exchange_weak(current, true) {
367 /// Ok(previous) => {
368 /// assert_eq!(previous, current);
369 /// break;
370 /// }
371 /// Err(actual) => current = actual,
372 /// }
373 /// }
374 /// assert_eq!(flag.load(), true);
375 /// ```
376 #[inline]
377 pub fn compare_and_exchange_weak(
378 &self,
379 current: bool,
380 new: bool,
381 ) -> Result<bool, bool> {
382 self.inner.compare_exchange_weak(
383 current,
384 new,
385 Ordering::AcqRel,
386 Ordering::Acquire,
387 )
388 }
389
390 /// Atomically sets the value to `true`, returning the old value.
391 ///
392 /// # Memory Ordering
393 ///
394 /// Uses `AcqRel` ordering (via `swap`). This ensures full
395 /// synchronization with other threads for this read-modify-write
396 /// operation.
397 ///
398 /// # Returns
399 ///
400 /// The old value before setting to `true`.
401 ///
402 /// # Example
403 ///
404 /// ```rust
405 /// use qubit_atomic::Atomic;
406 ///
407 /// let flag = Atomic::<bool>::new(false);
408 /// let old = flag.fetch_set();
409 /// assert_eq!(old, false);
410 /// assert_eq!(flag.load(), true);
411 /// ```
412 #[inline]
413 pub fn fetch_set(&self) -> bool {
414 self.swap(true)
415 }
416
417 /// Atomically sets the value to `false`, returning the old value.
418 ///
419 /// # Memory Ordering
420 ///
421 /// Uses `AcqRel` ordering (via `swap`). This ensures full
422 /// synchronization with other threads for this read-modify-write
423 /// operation.
424 ///
425 /// # Returns
426 ///
427 /// The old value before setting to `false`.
428 ///
429 /// # Example
430 ///
431 /// ```rust
432 /// use qubit_atomic::Atomic;
433 ///
434 /// let flag = Atomic::<bool>::new(true);
435 /// let old = flag.fetch_clear();
436 /// assert_eq!(old, true);
437 /// assert_eq!(flag.load(), false);
438 /// ```
439 #[inline]
440 pub fn fetch_clear(&self) -> bool {
441 self.swap(false)
442 }
443
444 /// Atomically negates the value, returning the old value.
445 ///
446 /// # Memory Ordering
447 ///
448 /// Uses `AcqRel` ordering. This ensures full synchronization with other
449 /// threads for this read-modify-write operation.
450 ///
451 /// # Returns
452 ///
453 /// The old value before negation.
454 ///
455 /// # Example
456 ///
457 /// ```rust
458 /// use qubit_atomic::Atomic;
459 ///
460 /// let flag = Atomic::<bool>::new(false);
461 /// assert_eq!(flag.fetch_not(), false);
462 /// assert_eq!(flag.load(), true);
463 /// assert_eq!(flag.fetch_not(), true);
464 /// assert_eq!(flag.load(), false);
465 /// ```
466 #[inline]
467 pub fn fetch_not(&self) -> bool {
468 self.inner.fetch_xor(true, Ordering::AcqRel)
469 }
470
471 /// Atomically performs logical AND, returning the old value.
472 ///
473 /// # Memory Ordering
474 ///
475 /// Uses `AcqRel` ordering. This ensures full synchronization with other
476 /// threads for this read-modify-write operation, which is necessary
477 /// because the operation depends on the current value.
478 ///
479 /// # Parameters
480 ///
481 /// * `value` - The value to AND with.
482 ///
483 /// # Returns
484 ///
485 /// The old value before the operation.
486 ///
487 /// # Example
488 ///
489 /// ```rust
490 /// use qubit_atomic::Atomic;
491 ///
492 /// let flag = Atomic::<bool>::new(true);
493 /// assert_eq!(flag.fetch_and(false), true);
494 /// assert_eq!(flag.load(), false);
495 /// ```
496 #[inline]
497 pub fn fetch_and(&self, value: bool) -> bool {
498 self.inner.fetch_and(value, Ordering::AcqRel)
499 }
500
501 /// Atomically performs logical OR, returning the old value.
502 ///
503 /// # Memory Ordering
504 ///
505 /// Uses `AcqRel` ordering. This ensures full synchronization with other
506 /// threads for this read-modify-write operation, which is necessary
507 /// because the operation depends on the current value.
508 ///
509 /// # Parameters
510 ///
511 /// * `value` - The value to OR with.
512 ///
513 /// # Returns
514 ///
515 /// The old value before the operation.
516 ///
517 /// # Example
518 ///
519 /// ```rust
520 /// use qubit_atomic::Atomic;
521 ///
522 /// let flag = Atomic::<bool>::new(false);
523 /// assert_eq!(flag.fetch_or(true), false);
524 /// assert_eq!(flag.load(), true);
525 /// ```
526 #[inline]
527 pub fn fetch_or(&self, value: bool) -> bool {
528 self.inner.fetch_or(value, Ordering::AcqRel)
529 }
530
531 /// Atomically performs logical XOR, returning the old value.
532 ///
533 /// # Memory Ordering
534 ///
535 /// Uses `AcqRel` ordering. This ensures full synchronization with other
536 /// threads for this read-modify-write operation, which is necessary
537 /// because the operation depends on the current value.
538 ///
539 /// # Parameters
540 ///
541 /// * `value` - The value to XOR with.
542 ///
543 /// # Returns
544 ///
545 /// The old value before the operation.
546 ///
547 /// # Example
548 ///
549 /// ```rust
550 /// use qubit_atomic::Atomic;
551 ///
552 /// let flag = Atomic::<bool>::new(false);
553 /// assert_eq!(flag.fetch_xor(true), false);
554 /// assert_eq!(flag.load(), true);
555 /// ```
556 #[inline]
557 pub fn fetch_xor(&self, value: bool) -> bool {
558 self.inner.fetch_xor(value, Ordering::AcqRel)
559 }
560
561 /// Conditionally sets the value if it is currently `false`.
562 ///
563 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
564 ///
565 /// # Parameters
566 ///
567 /// * `new` - The new value to set if current is `false`.
568 ///
569 /// # Returns
570 ///
571 /// `Ok(())` if the value was `false` and has been set to `new`.
572 ///
573 /// # Errors
574 ///
575 /// Returns `Err(true)` if the value was already `true`. In that case,
576 /// `new` is not stored.
577 ///
578 /// # Example
579 ///
580 /// ```rust
581 /// use qubit_atomic::Atomic;
582 ///
583 /// let flag = Atomic::<bool>::new(false);
584 /// assert!(flag.set_if_false(true).is_ok());
585 /// assert_eq!(flag.load(), true);
586 ///
587 /// // Second attempt fails
588 /// assert!(flag.set_if_false(true).is_err());
589 /// ```
590 #[inline]
591 pub fn set_if_false(&self, new: bool) -> Result<(), bool> {
592 self.compare_set(false, new)
593 }
594
595 /// Conditionally sets the value if it is currently `true`.
596 ///
597 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
598 ///
599 /// # Parameters
600 ///
601 /// * `new` - The new value to set if current is `true`.
602 ///
603 /// # Returns
604 ///
605 /// `Ok(())` if the value was `true` and has been set to `new`.
606 ///
607 /// # Errors
608 ///
609 /// Returns `Err(false)` if the value was already `false`. In that case,
610 /// `new` is not stored.
611 ///
612 /// # Example
613 ///
614 /// ```rust
615 /// use qubit_atomic::Atomic;
616 ///
617 /// let flag = Atomic::<bool>::new(true);
618 /// assert!(flag.set_if_true(false).is_ok());
619 /// assert_eq!(flag.load(), false);
620 ///
621 /// // Second attempt fails
622 /// assert!(flag.set_if_true(false).is_err());
623 /// ```
624 #[inline]
625 pub fn set_if_true(&self, new: bool) -> Result<(), bool> {
626 self.compare_set(true, new)
627 }
628
629 /// Updates the value using a function, returning the old value.
630 ///
631 /// Internally uses a CAS loop until the update succeeds.
632 ///
633 /// # Parameters
634 ///
635 /// * `f` - A function that takes the current value and returns the new
636 /// value.
637 ///
638 /// # Returns
639 ///
640 /// The old value before the update.
641 ///
642 /// The closure may be called more than once when concurrent updates cause
643 /// CAS retries.
644 ///
645 /// # Example
646 ///
647 /// ```rust
648 /// use qubit_atomic::Atomic;
649 ///
650 /// let flag = Atomic::<bool>::new(false);
651 /// assert_eq!(flag.fetch_update(|current| !current), false);
652 /// assert_eq!(flag.load(), true);
653 /// ```
654 #[inline]
655 pub fn fetch_update<F>(&self, mut f: F) -> bool
656 where
657 F: FnMut(bool) -> bool,
658 {
659 let mut current = self.load();
660 loop {
661 let new = f(current);
662 match self.compare_set_weak(current, new) {
663 Ok(_) => return current,
664 Err(actual) => current = actual,
665 }
666 }
667 }
668
669 /// Updates the value using a function, returning the new value.
670 ///
671 /// Internally uses a CAS loop until the update succeeds.
672 ///
673 /// # Parameters
674 ///
675 /// * `f` - A function that takes the current value and returns the new
676 /// value.
677 ///
678 /// # Returns
679 ///
680 /// The value committed by the successful update.
681 ///
682 /// The closure may be called more than once when concurrent updates cause
683 /// CAS retries.
684 ///
685 /// # Example
686 ///
687 /// ```rust
688 /// use qubit_atomic::Atomic;
689 ///
690 /// let flag = Atomic::<bool>::new(false);
691 /// assert_eq!(flag.update_and_get(|current| !current), true);
692 /// assert_eq!(flag.load(), true);
693 /// ```
694 #[inline]
695 pub fn update_and_get<F>(&self, mut f: F) -> bool
696 where
697 F: FnMut(bool) -> bool,
698 {
699 let mut current = self.load();
700 loop {
701 let new = f(current);
702 match self.compare_set_weak(current, new) {
703 Ok(_) => return new,
704 Err(actual) => current = actual,
705 }
706 }
707 }
708
709 /// Conditionally updates the value using a function.
710 ///
711 /// Internally uses a CAS loop until the update succeeds or the closure
712 /// rejects the current value by returning `None`.
713 ///
714 /// # Parameters
715 ///
716 /// * `f` - A function that takes the current value and returns the new
717 /// value, or `None` to leave the value unchanged.
718 ///
719 /// # Returns
720 ///
721 /// `Some(old_value)` when the update succeeds, or `None` when `f` rejects
722 /// the observed current value.
723 ///
724 /// The closure may be called more than once when concurrent updates cause
725 /// CAS retries.
726 ///
727 /// # Example
728 ///
729 /// ```rust
730 /// use qubit_atomic::Atomic;
731 ///
732 /// let flag = Atomic::<bool>::new(false);
733 /// assert_eq!(flag.try_update(|current| (!current).then_some(true)), Some(false));
734 /// assert_eq!(flag.load(), true);
735 /// assert_eq!(flag.try_update(|current| (!current).then_some(true)), None);
736 /// assert_eq!(flag.load(), true);
737 /// ```
738 #[inline]
739 pub fn try_update<F>(&self, mut f: F) -> Option<bool>
740 where
741 F: FnMut(bool) -> Option<bool>,
742 {
743 let mut current = self.load();
744 loop {
745 let new = f(current)?;
746 match self.compare_set_weak(current, new) {
747 Ok(_) => return Some(current),
748 Err(actual) => current = actual,
749 }
750 }
751 }
752
753 /// Conditionally updates the value using a function, returning the new
754 /// value.
755 ///
756 /// Internally uses a CAS loop until the update succeeds or the closure
757 /// rejects the current value by returning `None`.
758 ///
759 /// # Parameters
760 ///
761 /// * `f` - A function that takes the current value and returns the new
762 /// value, or `None` to leave the value unchanged.
763 ///
764 /// # Returns
765 ///
766 /// `Some(new_value)` when the update succeeds, or `None` when `f` rejects
767 /// the observed current value.
768 ///
769 /// The closure may be called more than once when concurrent updates cause
770 /// CAS retries.
771 ///
772 /// # Example
773 ///
774 /// ```rust
775 /// use qubit_atomic::Atomic;
776 ///
777 /// let flag = Atomic::<bool>::new(false);
778 /// assert_eq!(
779 /// flag.try_update_and_get(|current| (!current).then_some(true)),
780 /// Some(true),
781 /// );
782 /// assert_eq!(flag.load(), true);
783 /// assert_eq!(
784 /// flag.try_update_and_get(|current| (!current).then_some(true)),
785 /// None,
786 /// );
787 /// assert_eq!(flag.load(), true);
788 /// ```
789 #[inline]
790 pub fn try_update_and_get<F>(&self, mut f: F) -> Option<bool>
791 where
792 F: FnMut(bool) -> Option<bool>,
793 {
794 let mut current = self.load();
795 loop {
796 let new = f(current)?;
797 match self.compare_set_weak(current, new) {
798 Ok(_) => return Some(new),
799 Err(actual) => current = actual,
800 }
801 }
802 }
803
804 /// Gets a reference to the underlying standard library atomic type.
805 ///
806 /// This allows direct access to the standard library's atomic operations
807 /// for advanced use cases that require fine-grained control over memory
808 /// ordering.
809 ///
810 /// # Memory Ordering
811 ///
812 /// When using the returned reference, you have full control over memory
813 /// ordering. Choose the appropriate ordering based on your specific
814 /// synchronization requirements.
815 ///
816 /// # Returns
817 ///
818 /// A reference to the underlying `std::sync::atomic::AtomicBool`.
819 ///
820 /// # Example
821 ///
822 /// ```rust
823 /// use qubit_atomic::Atomic;
824 /// use std::sync::atomic::Ordering;
825 ///
826 /// let flag = Atomic::<bool>::new(false);
827 /// flag.inner().store(true, Ordering::Relaxed);
828 /// assert_eq!(flag.inner().load(Ordering::Relaxed), true);
829 /// ```
830 #[inline]
831 pub fn inner(&self) -> &StdAtomicBool {
832 &self.inner
833 }
834}
835
836impl AtomicOps for AtomicBool {
837 type Value = bool;
838
839 #[inline]
840 fn load(&self) -> bool {
841 self.load()
842 }
843
844 #[inline]
845 fn store(&self, value: bool) {
846 self.store(value);
847 }
848
849 #[inline]
850 fn swap(&self, value: bool) -> bool {
851 self.swap(value)
852 }
853
854 #[inline]
855 fn compare_set(&self, current: bool, new: bool) -> Result<(), bool> {
856 self.compare_set(current, new)
857 }
858
859 #[inline]
860 fn compare_set_weak(&self, current: bool, new: bool) -> Result<(), bool> {
861 self.compare_set_weak(current, new)
862 }
863
864 #[inline]
865 fn compare_exchange(&self, current: bool, new: bool) -> bool {
866 self.compare_and_exchange(current, new)
867 }
868
869 #[inline]
870 fn compare_exchange_weak(
871 &self,
872 current: bool,
873 new: bool,
874 ) -> Result<bool, bool> {
875 self.compare_and_exchange_weak(current, new)
876 }
877
878 #[inline]
879 fn fetch_update<F>(&self, f: F) -> bool
880 where
881 F: FnMut(bool) -> bool,
882 {
883 self.fetch_update(f)
884 }
885
886 #[inline]
887 fn update_and_get<F>(&self, f: F) -> bool
888 where
889 F: FnMut(bool) -> bool,
890 {
891 self.update_and_get(f)
892 }
893
894 #[inline]
895 fn try_update<F>(&self, f: F) -> Option<bool>
896 where
897 F: FnMut(bool) -> Option<bool>,
898 {
899 self.try_update(f)
900 }
901
902 #[inline]
903 fn try_update_and_get<F>(&self, f: F) -> Option<bool>
904 where
905 F: FnMut(bool) -> Option<bool>,
906 {
907 self.try_update_and_get(f)
908 }
909}