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 into_inner(storage: Self::Storage) -> Self;
23}
24
25macro_rules! impl_atomic_bits {
26    ($bits:ty, $atomic:ty) => {
27        impl AtomicBits for $bits {
28            type Storage = $atomic;
29
30            fn new(bits: Self) -> Self::Storage {
31                <$atomic>::new(bits)
32            }
33
34            fn store(storage: &Self::Storage, bits: Self, ordering: Ordering) {
35                <$atomic>::store(storage, bits, ordering);
36            }
37
38            fn load(storage: &Self::Storage, ordering: Ordering) -> Self {
39                <$atomic>::load(storage, ordering)
40            }
41
42            fn fetch_and(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
43                <$atomic>::fetch_and(storage, bits, ordering)
44            }
45
46            fn fetch_or(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
47                <$atomic>::fetch_or(storage, bits, ordering)
48            }
49
50            fn fetch_xor(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
51                <$atomic>::fetch_xor(storage, bits, ordering)
52            }
53
54            fn fetch_nand(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
55                <$atomic>::fetch_nand(storage, bits, ordering)
56            }
57
58            fn swap(storage: &Self::Storage, bits: Self, ordering: Ordering) -> Self {
59                <$atomic>::swap(storage, bits, ordering)
60            }
61
62            fn into_inner(storage: Self::Storage) -> Self {
63                storage.into_inner()
64            }
65        }
66    };
67}
68
69// bitflags implements Flags for almost all integer types:
70// u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize.
71// There is no 128-bit atomic integer in Rust.
72impl_atomic_bits!(u8, AtomicU8);
73impl_atomic_bits!(u16, AtomicU16);
74impl_atomic_bits!(u32, AtomicU32);
75impl_atomic_bits!(u64, AtomicU64);
76impl_atomic_bits!(usize, AtomicUsize);
77impl_atomic_bits!(i8, AtomicI8);
78impl_atomic_bits!(i16, AtomicI16);
79impl_atomic_bits!(i32, AtomicI32);
80impl_atomic_bits!(i64, AtomicI64);
81impl_atomic_bits!(isize, AtomicIsize);