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