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/// # Examples
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 /// # Examples
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 /// # Examples
120 ///
121 /// ```rust
122 /// use qubit_atomic::Atomic;
123 ///
124 /// let flag = Atomic::<bool>::new(true);
125 /// assert_eq!(flag.load(), true);
126 /// ```
127 #[must_use]
128 #[inline(always)]
129 pub fn load(&self) -> bool {
130 self.inner.load(Ordering::Acquire)
131 }
132
133 /// Sets a new value.
134 ///
135 /// # Memory Ordering
136 ///
137 /// Uses `Release` ordering. This ensures that:
138 /// - All prior writes in this thread are visible to other threads that
139 /// perform an `Acquire` load.
140 /// - Forms a synchronizes-with relationship with `Acquire` loads.
141 /// - Prevents reordering of prior reads/writes after this store.
142 ///
143 /// This is appropriate for publishing shared state to other threads.
144 ///
145 /// # Parameters
146 ///
147 /// * `value` - The new value to set.
148 ///
149 /// # Examples
150 ///
151 /// ```rust
152 /// use qubit_atomic::Atomic;
153 ///
154 /// let flag = Atomic::<bool>::new(false);
155 /// flag.store(true);
156 /// assert_eq!(flag.load(), true);
157 /// ```
158 #[inline(always)]
159 pub fn store(&self, value: bool) {
160 self.inner.store(value, Ordering::Release);
161 }
162
163 /// Swaps the current value with a new value, returning the old value.
164 ///
165 /// # Memory Ordering
166 ///
167 /// Uses `AcqRel` ordering. This ensures that:
168 /// - **Acquire**: All writes from other threads that happened before their
169 /// `Release` operations are visible after this operation.
170 /// - **Release**: All prior writes in this thread are visible to other
171 /// threads that perform subsequent `Acquire` operations.
172 ///
173 /// This provides full synchronization for read-modify-write operations.
174 ///
175 /// # Parameters
176 ///
177 /// * `value` - The new value to swap in.
178 ///
179 /// # Returns
180 ///
181 /// The old value.
182 ///
183 /// # Examples
184 ///
185 /// ```rust
186 /// use qubit_atomic::Atomic;
187 ///
188 /// let flag = Atomic::<bool>::new(false);
189 /// let old = flag.swap(true);
190 /// assert_eq!(old, false);
191 /// assert_eq!(flag.load(), true);
192 /// ```
193 #[must_use]
194 #[inline(always)]
195 pub fn swap(&self, value: bool) -> bool {
196 self.inner.swap(value, Ordering::AcqRel)
197 }
198
199 /// Compares and sets the value atomically.
200 ///
201 /// If the current value equals `current`, sets it to `new` and returns
202 /// `Ok(())`. Otherwise, returns `Err(actual)` where `actual` is the
203 /// current value.
204 ///
205 /// # Memory Ordering
206 ///
207 /// - **Success**: Uses `AcqRel` ordering to ensure full synchronization
208 /// when the exchange succeeds.
209 /// - **Failure**: Uses `Acquire` ordering to observe the actual value
210 /// written by another thread.
211 ///
212 /// This pattern is essential for implementing lock-free algorithms where
213 /// you need to retry based on the observed value.
214 ///
215 /// # Parameters
216 ///
217 /// * `current` - The expected current value.
218 /// * `new` - The new value to set if current matches.
219 ///
220 /// # Returns
221 ///
222 /// `Ok(())` when the value was replaced.
223 ///
224 /// # Errors
225 ///
226 /// Returns `Err(actual)` with the observed value when the comparison
227 /// fails. In that case, `new` is not stored.
228 ///
229 /// # Examples
230 ///
231 /// ```rust
232 /// use qubit_atomic::Atomic;
233 ///
234 /// let flag = Atomic::<bool>::new(false);
235 /// assert!(flag.compare_set(false, true).is_ok());
236 /// assert_eq!(flag.load(), true);
237 ///
238 /// // Fails because current value is true, not false
239 /// assert!(flag.compare_set(false, false).is_err());
240 /// ```
241 #[inline(always)]
242 pub fn compare_set(&self, current: bool, new: bool) -> Result<(), bool> {
243 self.inner
244 .compare_exchange(current, new, Ordering::AcqRel, Ordering::Acquire)
245 .map(|_| ())
246 }
247
248 /// Weak version of compare-and-set.
249 ///
250 /// May spuriously fail even when the comparison succeeds. Should be used
251 /// in a loop.
252 ///
253 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
254 ///
255 /// # Parameters
256 ///
257 /// * `current` - The expected current value.
258 /// * `new` - The new value to set if current matches.
259 ///
260 /// # Returns
261 ///
262 /// `Ok(())` when the value was replaced.
263 ///
264 /// # Errors
265 ///
266 /// Returns `Err(actual)` with the observed value when the comparison
267 /// fails, including possible spurious failures. In that case, `new` is not
268 /// stored.
269 ///
270 /// # Examples
271 ///
272 /// ```rust
273 /// use qubit_atomic::Atomic;
274 ///
275 /// let flag = Atomic::<bool>::new(false);
276 /// let mut current = flag.load();
277 /// loop {
278 /// match flag.compare_set_weak(current, true) {
279 /// Ok(_) => break,
280 /// Err(actual) => current = actual,
281 /// }
282 /// }
283 /// assert_eq!(flag.load(), true);
284 /// ```
285 #[inline(always)]
286 pub fn compare_set_weak(
287 &self,
288 current: bool,
289 new: bool,
290 ) -> Result<(), bool> {
291 self.inner
292 .compare_exchange_weak(
293 current,
294 new,
295 Ordering::AcqRel,
296 Ordering::Acquire,
297 )
298 .map(|_| ())
299 }
300
301 /// Compares and exchanges the value atomically, returning the previous
302 /// value.
303 ///
304 /// If the current value equals `current`, sets it to `new` and returns
305 /// the old value. Otherwise, returns the actual current value.
306 ///
307 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
308 ///
309 /// # Parameters
310 ///
311 /// * `current` - The expected current value.
312 /// * `new` - The new value to set if current matches.
313 ///
314 /// # Returns
315 ///
316 /// The value observed before the operation completed. If the returned
317 /// value equals `current`, the exchange succeeded; otherwise it is the
318 /// actual value that prevented the exchange.
319 ///
320 /// # Examples
321 ///
322 /// ```rust
323 /// use qubit_atomic::Atomic;
324 ///
325 /// let flag = Atomic::<bool>::new(false);
326 /// let prev = flag.compare_and_exchange(false, true);
327 /// assert_eq!(prev, false);
328 /// assert_eq!(flag.load(), true);
329 /// ```
330 #[must_use]
331 #[inline]
332 pub fn compare_and_exchange(&self, current: bool, new: bool) -> bool {
333 match self.inner.compare_exchange(
334 current,
335 new,
336 Ordering::AcqRel,
337 Ordering::Acquire,
338 ) {
339 Ok(prev) => prev,
340 Err(actual) => actual,
341 }
342 }
343
344 /// Weak version of compare-and-exchange.
345 ///
346 /// May spuriously fail even when the comparison succeeds. Should be used
347 /// in a loop.
348 ///
349 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
350 ///
351 /// # Parameters
352 ///
353 /// * `current` - The expected current value.
354 /// * `new` - The new value to set if current matches.
355 ///
356 /// # Returns
357 ///
358 /// `Ok(previous)` when the value was replaced, or `Err(actual)` when the
359 /// comparison failed, including possible spurious failure.
360 ///
361 /// # Examples
362 ///
363 /// ```rust
364 /// use qubit_atomic::Atomic;
365 ///
366 /// let flag = Atomic::<bool>::new(false);
367 /// let mut current = flag.load();
368 /// loop {
369 /// match flag.compare_and_exchange_weak(current, true) {
370 /// Ok(previous) => {
371 /// assert_eq!(previous, current);
372 /// break;
373 /// }
374 /// Err(actual) => current = actual,
375 /// }
376 /// }
377 /// assert_eq!(flag.load(), true);
378 /// ```
379 #[inline(always)]
380 pub fn compare_and_exchange_weak(
381 &self,
382 current: bool,
383 new: bool,
384 ) -> Result<bool, bool> {
385 self.inner.compare_exchange_weak(
386 current,
387 new,
388 Ordering::AcqRel,
389 Ordering::Acquire,
390 )
391 }
392
393 /// Atomically sets the value to `true`, returning the old value.
394 ///
395 /// # Memory Ordering
396 ///
397 /// Uses `AcqRel` ordering (via `swap`). This ensures full
398 /// synchronization with other threads for this read-modify-write
399 /// operation.
400 ///
401 /// # Returns
402 ///
403 /// The old value before setting to `true`.
404 ///
405 /// # Examples
406 ///
407 /// ```rust
408 /// use qubit_atomic::Atomic;
409 ///
410 /// let flag = Atomic::<bool>::new(false);
411 /// let old = flag.fetch_set();
412 /// assert_eq!(old, false);
413 /// assert_eq!(flag.load(), true);
414 /// ```
415 #[inline(always)]
416 pub fn fetch_set(&self) -> bool {
417 self.swap(true)
418 }
419
420 /// Atomically sets the value to `false`, returning the old value.
421 ///
422 /// # Memory Ordering
423 ///
424 /// Uses `AcqRel` ordering (via `swap`). This ensures full
425 /// synchronization with other threads for this read-modify-write
426 /// operation.
427 ///
428 /// # Returns
429 ///
430 /// The old value before setting to `false`.
431 ///
432 /// # Examples
433 ///
434 /// ```rust
435 /// use qubit_atomic::Atomic;
436 ///
437 /// let flag = Atomic::<bool>::new(true);
438 /// let old = flag.fetch_clear();
439 /// assert_eq!(old, true);
440 /// assert_eq!(flag.load(), false);
441 /// ```
442 #[inline(always)]
443 pub fn fetch_clear(&self) -> bool {
444 self.swap(false)
445 }
446
447 /// Atomically negates the value, returning the old value.
448 ///
449 /// # Memory Ordering
450 ///
451 /// Uses `AcqRel` ordering. This ensures full synchronization with other
452 /// threads for this read-modify-write operation.
453 ///
454 /// # Returns
455 ///
456 /// The old value before negation.
457 ///
458 /// # Examples
459 ///
460 /// ```rust
461 /// use qubit_atomic::Atomic;
462 ///
463 /// let flag = Atomic::<bool>::new(false);
464 /// assert_eq!(flag.fetch_not(), false);
465 /// assert_eq!(flag.load(), true);
466 /// assert_eq!(flag.fetch_not(), true);
467 /// assert_eq!(flag.load(), false);
468 /// ```
469 #[inline(always)]
470 pub fn fetch_not(&self) -> bool {
471 self.inner.fetch_xor(true, Ordering::AcqRel)
472 }
473
474 /// Atomically performs logical AND, returning the old value.
475 ///
476 /// # Memory Ordering
477 ///
478 /// Uses `AcqRel` ordering. This ensures full synchronization with other
479 /// threads for this read-modify-write operation, which is necessary
480 /// because the operation depends on the current value.
481 ///
482 /// # Parameters
483 ///
484 /// * `value` - The value to AND with.
485 ///
486 /// # Returns
487 ///
488 /// The old value before the operation.
489 ///
490 /// # Examples
491 ///
492 /// ```rust
493 /// use qubit_atomic::Atomic;
494 ///
495 /// let flag = Atomic::<bool>::new(true);
496 /// assert_eq!(flag.fetch_and(false), true);
497 /// assert_eq!(flag.load(), false);
498 /// ```
499 #[inline(always)]
500 pub fn fetch_and(&self, value: bool) -> bool {
501 self.inner.fetch_and(value, Ordering::AcqRel)
502 }
503
504 /// Atomically performs logical OR, returning the old value.
505 ///
506 /// # Memory Ordering
507 ///
508 /// Uses `AcqRel` ordering. This ensures full synchronization with other
509 /// threads for this read-modify-write operation, which is necessary
510 /// because the operation depends on the current value.
511 ///
512 /// # Parameters
513 ///
514 /// * `value` - The value to OR with.
515 ///
516 /// # Returns
517 ///
518 /// The old value before the operation.
519 ///
520 /// # Examples
521 ///
522 /// ```rust
523 /// use qubit_atomic::Atomic;
524 ///
525 /// let flag = Atomic::<bool>::new(false);
526 /// assert_eq!(flag.fetch_or(true), false);
527 /// assert_eq!(flag.load(), true);
528 /// ```
529 #[inline(always)]
530 pub fn fetch_or(&self, value: bool) -> bool {
531 self.inner.fetch_or(value, Ordering::AcqRel)
532 }
533
534 /// Atomically performs logical XOR, returning the old value.
535 ///
536 /// # Memory Ordering
537 ///
538 /// Uses `AcqRel` ordering. This ensures full synchronization with other
539 /// threads for this read-modify-write operation, which is necessary
540 /// because the operation depends on the current value.
541 ///
542 /// # Parameters
543 ///
544 /// * `value` - The value to XOR with.
545 ///
546 /// # Returns
547 ///
548 /// The old value before the operation.
549 ///
550 /// # Examples
551 ///
552 /// ```rust
553 /// use qubit_atomic::Atomic;
554 ///
555 /// let flag = Atomic::<bool>::new(false);
556 /// assert_eq!(flag.fetch_xor(true), false);
557 /// assert_eq!(flag.load(), true);
558 /// ```
559 #[inline(always)]
560 pub fn fetch_xor(&self, value: bool) -> bool {
561 self.inner.fetch_xor(value, Ordering::AcqRel)
562 }
563
564 /// Conditionally sets the value if it is currently `false`.
565 ///
566 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
567 ///
568 /// # Parameters
569 ///
570 /// * `new` - The new value to set if current is `false`.
571 ///
572 /// # Returns
573 ///
574 /// `Ok(())` if the value was `false` and has been set to `new`.
575 ///
576 /// # Errors
577 ///
578 /// Returns `Err(true)` if the value was already `true`. In that case,
579 /// `new` is not stored.
580 ///
581 /// # Examples
582 ///
583 /// ```rust
584 /// use qubit_atomic::Atomic;
585 ///
586 /// let flag = Atomic::<bool>::new(false);
587 /// assert!(flag.set_if_false(true).is_ok());
588 /// assert_eq!(flag.load(), true);
589 ///
590 /// // Second attempt fails
591 /// assert!(flag.set_if_false(true).is_err());
592 /// ```
593 #[inline(always)]
594 pub fn set_if_false(&self, new: bool) -> Result<(), bool> {
595 self.compare_set(false, new)
596 }
597
598 /// Conditionally sets the value if it is currently `true`.
599 ///
600 /// Uses `AcqRel` ordering on success and `Acquire` ordering on failure.
601 ///
602 /// # Parameters
603 ///
604 /// * `new` - The new value to set if current is `true`.
605 ///
606 /// # Returns
607 ///
608 /// `Ok(())` if the value was `true` and has been set to `new`.
609 ///
610 /// # Errors
611 ///
612 /// Returns `Err(false)` if the value was already `false`. In that case,
613 /// `new` is not stored.
614 ///
615 /// # Examples
616 ///
617 /// ```rust
618 /// use qubit_atomic::Atomic;
619 ///
620 /// let flag = Atomic::<bool>::new(true);
621 /// assert!(flag.set_if_true(false).is_ok());
622 /// assert_eq!(flag.load(), false);
623 ///
624 /// // Second attempt fails
625 /// assert!(flag.set_if_true(false).is_err());
626 /// ```
627 #[inline(always)]
628 pub fn set_if_true(&self, new: bool) -> Result<(), bool> {
629 self.compare_set(true, new)
630 }
631
632 /// Updates the value using a function, returning the old value.
633 ///
634 /// Internally uses a CAS loop until the update succeeds.
635 ///
636 /// # Parameters
637 ///
638 /// * `f` - A function that takes the current value and returns the new
639 /// value.
640 ///
641 /// # Returns
642 ///
643 /// The old value before the update.
644 ///
645 /// The closure may be called more than once when concurrent updates cause
646 /// CAS retries.
647 ///
648 /// # Examples
649 ///
650 /// ```rust
651 /// use qubit_atomic::Atomic;
652 ///
653 /// let flag = Atomic::<bool>::new(false);
654 /// assert_eq!(flag.fetch_update(|current| !current), false);
655 /// assert_eq!(flag.load(), true);
656 /// ```
657 pub fn fetch_update<F>(&self, mut f: F) -> bool
658 where
659 F: FnMut(bool) -> bool,
660 {
661 let mut current = self.load();
662 loop {
663 let new = f(current);
664 match self.compare_set_weak(current, new) {
665 Ok(_) => return current,
666 Err(actual) => current = actual,
667 }
668 }
669 }
670
671 /// Updates the value using a function, returning the new value.
672 ///
673 /// Internally uses a CAS loop until the update succeeds.
674 ///
675 /// # Parameters
676 ///
677 /// * `f` - A function that takes the current value and returns the new
678 /// value.
679 ///
680 /// # Returns
681 ///
682 /// The value committed by the successful update.
683 ///
684 /// The closure may be called more than once when concurrent updates cause
685 /// CAS retries.
686 ///
687 /// # Examples
688 ///
689 /// ```rust
690 /// use qubit_atomic::Atomic;
691 ///
692 /// let flag = Atomic::<bool>::new(false);
693 /// assert_eq!(flag.update_and_get(|current| !current), true);
694 /// assert_eq!(flag.load(), true);
695 /// ```
696 pub fn update_and_get<F>(&self, mut f: F) -> bool
697 where
698 F: FnMut(bool) -> bool,
699 {
700 let mut current = self.load();
701 loop {
702 let new = f(current);
703 match self.compare_set_weak(current, new) {
704 Ok(_) => return new,
705 Err(actual) => current = actual,
706 }
707 }
708 }
709
710 /// Conditionally updates the value using a function.
711 ///
712 /// Internally uses a CAS loop until the update succeeds or the closure
713 /// rejects the current value by returning `None`.
714 ///
715 /// # Parameters
716 ///
717 /// * `f` - A function that takes the current value and returns the new
718 /// value, or `None` to leave the value unchanged.
719 ///
720 /// # Returns
721 ///
722 /// `Some(old_value)` when the update succeeds, or `None` when `f` rejects
723 /// the observed current value.
724 ///
725 /// The closure may be called more than once when concurrent updates cause
726 /// CAS retries.
727 ///
728 /// # Examples
729 ///
730 /// ```rust
731 /// use qubit_atomic::Atomic;
732 ///
733 /// let flag = Atomic::<bool>::new(false);
734 /// assert_eq!(flag.try_update(|current| (!current).then_some(true)), Some(false));
735 /// assert_eq!(flag.load(), true);
736 /// assert_eq!(flag.try_update(|current| (!current).then_some(true)), None);
737 /// assert_eq!(flag.load(), true);
738 /// ```
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 /// # Examples
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 pub fn try_update_and_get<F>(&self, mut f: F) -> Option<bool>
790 where
791 F: FnMut(bool) -> Option<bool>,
792 {
793 let mut current = self.load();
794 loop {
795 let new = f(current)?;
796 match self.compare_set_weak(current, new) {
797 Ok(_) => return Some(new),
798 Err(actual) => current = actual,
799 }
800 }
801 }
802
803 /// Gets a reference to the underlying standard library atomic type.
804 ///
805 /// This allows direct access to the standard library's atomic operations
806 /// for advanced use cases that require fine-grained control over memory
807 /// ordering.
808 ///
809 /// # Memory Ordering
810 ///
811 /// When using the returned reference, you have full control over memory
812 /// ordering. Choose the appropriate ordering based on your specific
813 /// synchronization requirements.
814 ///
815 /// # Returns
816 ///
817 /// A reference to the underlying `std::sync::atomic::AtomicBool`.
818 ///
819 /// # Examples
820 ///
821 /// ```rust
822 /// use qubit_atomic::Atomic;
823 /// use std::sync::atomic::Ordering;
824 ///
825 /// let flag = Atomic::<bool>::new(false);
826 /// flag.inner().store(true, Ordering::Relaxed);
827 /// assert_eq!(flag.inner().load(Ordering::Relaxed), true);
828 /// ```
829 #[must_use]
830 #[inline(always)]
831 pub fn inner(&self) -> &StdAtomicBool {
832 &self.inner
833 }
834}
835
836impl AtomicOps for AtomicBool {
837 type Value = bool;
838
839 #[inline(always)]
840 fn load(&self) -> bool {
841 self.load()
842 }
843
844 #[inline(always)]
845 fn store(&self, value: bool) {
846 self.store(value);
847 }
848
849 #[inline(always)]
850 fn swap(&self, value: bool) -> bool {
851 self.swap(value)
852 }
853
854 #[inline(always)]
855 fn compare_set(&self, current: bool, new: bool) -> Result<(), bool> {
856 self.compare_set(current, new)
857 }
858
859 #[inline(always)]
860 fn compare_set_weak(&self, current: bool, new: bool) -> Result<(), bool> {
861 self.compare_set_weak(current, new)
862 }
863
864 #[inline(always)]
865 fn compare_exchange(&self, current: bool, new: bool) -> bool {
866 self.compare_and_exchange(current, new)
867 }
868
869 #[inline(always)]
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(always)]
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(always)]
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(always)]
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(always)]
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}