Skip to main content

atomic_bitflags/
atomic_bits.rs

1use std::sync::atomic::{
2    AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicU8, AtomicU16, AtomicU32,
3    AtomicU64, AtomicUsize, Ordering,
4};
5
6/// Integer type that can back an [`AtomicFlags`](crate::AtomicFlags).
7///
8/// Implemented for every integer type `bitflags` supports except `u128` and
9/// `i128`, which have no atomic counterpart.
10pub trait AtomicBits: Copy {
11    /// The atomic type that holds the bits.
12    type Storage;
13
14    fn new(bits: Self) -> Self::Storage;
15    fn store(storage: &Self::Storage, bits: Self, ordering: Ordering);
16    fn load(storage: &Self::Storage, ordering: Ordering) -> Self;
17    fn fetch_and(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self;
18    fn fetch_or(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self;
19    fn fetch_xor(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self;
20    fn fetch_nand(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self;
21    fn swap(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self;
22    fn compare_exchange(
23        storage: &Self::Storage,
24        current: Self,
25        new: Self,
26        success: Ordering,
27        failure: Ordering,
28    ) -> Result<Self, Self>;
29    fn compare_exchange_weak(
30        storage: &Self::Storage,
31        current: Self,
32        new: Self,
33        success: Ordering,
34        failure: Ordering,
35    ) -> Result<Self, Self>;
36    fn into_inner(storage: Self::Storage) -> Self;
37}
38
39macro_rules! impl_atomic_bits {
40    ($bits:ty, $atomic:ty) => {
41        impl AtomicBits for $bits {
42            type Storage = $atomic;
43
44            fn new(bits: Self) -> Self::Storage {
45                <$atomic>::new(bits)
46            }
47
48            fn store(storage: &Self::Storage, bits: Self, ordering: Ordering) {
49                <$atomic>::store(storage, bits, ordering);
50            }
51
52            fn load(storage: &Self::Storage, ordering: Ordering) -> Self {
53                <$atomic>::load(storage, ordering)
54            }
55
56            fn fetch_and(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
57                <$atomic>::fetch_and(storage, bits, ordering)
58            }
59
60            fn fetch_or(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
61                <$atomic>::fetch_or(storage, bits, ordering)
62            }
63
64            fn fetch_xor(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
65                <$atomic>::fetch_xor(storage, bits, ordering)
66            }
67
68            fn fetch_nand(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
69                <$atomic>::fetch_nand(storage, bits, ordering)
70            }
71
72            fn swap(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
73                <$atomic>::swap(storage, bits, ordering)
74            }
75
76            fn compare_exchange(
77                storage: &Self::Storage,
78                current: Self,
79                new: Self,
80                success: Ordering,
81                failure: Ordering,
82            ) -> Result<Self, Self> {
83                <$atomic>::compare_exchange(storage, current, new, success, failure)
84            }
85
86            fn compare_exchange_weak(
87                storage: &Self::Storage,
88                current: Self,
89                new: Self,
90                success: Ordering,
91                failure: Ordering,
92            ) -> Result<Self, Self> {
93                <$atomic>::compare_exchange_weak(storage, current, new, success, failure)
94            }
95
96            fn into_inner(storage: Self::Storage) -> Self {
97                storage.into_inner()
98            }
99        }
100    };
101}
102
103// bitflags implements Flags for almost all integer types:
104// u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize.
105// There is no 128-bit atomic integer in Rust.
106impl_atomic_bits!(u8, AtomicU8);
107impl_atomic_bits!(u16, AtomicU16);
108impl_atomic_bits!(u32, AtomicU32);
109impl_atomic_bits!(u64, AtomicU64);
110impl_atomic_bits!(usize, AtomicUsize);
111impl_atomic_bits!(i8, AtomicI8);
112impl_atomic_bits!(i16, AtomicI16);
113impl_atomic_bits!(i32, AtomicI32);
114impl_atomic_bits!(i64, AtomicI64);
115impl_atomic_bits!(isize, AtomicIsize);