Skip to main content

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}