Skip to main content

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}