1use std::sync::atomic::{
2 AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicU8, AtomicU16, AtomicU32,
3 AtomicU64, AtomicUsize, Ordering,
4};
5
6pub trait AtomicBits: Copy {
11 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
103impl_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);