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