bitcode/derive/
atomic.rs

1#[cfg(any(
2    target_has_atomic = "8",
3    target_has_atomic = "16",
4    target_has_atomic = "32",
5    target_has_atomic = "64",
6    target_has_atomic = "ptr"
7))]
8use core::sync::atomic::Ordering::Relaxed;
9#[cfg(target_has_atomic = "8")]
10use core::sync::atomic::{AtomicBool, AtomicI8, AtomicU8};
11#[cfg(target_has_atomic = "16")]
12use core::sync::atomic::{AtomicI16, AtomicU16};
13#[cfg(target_has_atomic = "32")]
14use core::sync::atomic::{AtomicI32, AtomicU32};
15#[cfg(target_has_atomic = "64")]
16use core::sync::atomic::{AtomicI64, AtomicU64};
17#[cfg(target_has_atomic = "ptr")]
18use core::sync::atomic::{AtomicIsize, AtomicUsize};
19
20macro_rules! atomic_impl {
21    ($(($atomic: path, $repr: ident, $size:expr),)*) => {
22        $(
23        #[cfg(target_has_atomic = $size)]
24        impl super::convert::ConvertFrom<&$atomic> for $repr {
25            #[inline(always)]
26            fn convert_from(atomic: &$atomic) -> Self {
27                // `Relaxed` matches `Debug` and `serde::Serialize`. It is your responsiblity to avoid
28                // race conditions, such as by excluding or fencing operations from other threads.
29                atomic.load(Relaxed)
30            }
31        }
32        #[cfg(target_has_atomic = $size)]
33        impl super::convert::ConvertFrom<$repr> for $atomic {
34            #[inline(always)]
35            fn convert_from(bits: $repr) -> Self {
36                Self::from(bits)
37            }
38        }
39        #[cfg(target_has_atomic = $size)]
40        impl crate::derive::Encode for $atomic {
41            type Encoder = crate::derive::convert::ConvertIntoEncoder<$repr>;
42        }
43        #[cfg(target_has_atomic = $size)]
44        impl<'a> crate::derive::Decode<'a> for $atomic {
45            type Decoder = crate::derive::convert::ConvertFromDecoder<'a, $repr>;
46        }
47        )*
48    };
49}
50
51atomic_impl!(
52    (AtomicBool, bool, "8"),
53    (AtomicI8, i8, "8"),
54    (AtomicI16, i16, "16"),
55    (AtomicI32, i32, "32"),
56    (AtomicI64, i64, "64"),
57    (AtomicIsize, isize, "ptr"),
58    (AtomicU8, u8, "8"),
59    (AtomicU16, u16, "16"),
60    (AtomicU32, u32, "32"),
61    (AtomicUsize, usize, "ptr"),
62    (AtomicU64, u64, "64"),
63);
64
65#[cfg(test)]
66mod tests {
67    use crate::{decode, encode};
68    use core::sync::atomic::*;
69
70    #[test]
71    fn test_atomic() {
72        macro_rules! atomic_test {
73            ($atomic: ident, $inner: expr) => {
74                assert!(decode::<$atomic>(&encode(&$atomic::new($inner)))
75                    .is_ok_and(|x| x.load(Ordering::Relaxed) == $inner));
76            };
77        }
78        atomic_test!(AtomicBool, true);
79        atomic_test!(AtomicI8, -128i8);
80        atomic_test!(AtomicI16, -5897i16);
81        atomic_test!(AtomicI32, -487952i32);
82        atomic_test!(AtomicI64, -783414i64);
83        atomic_test!(AtomicIsize, isize::MIN);
84        atomic_test!(AtomicU8, 255u8);
85        atomic_test!(AtomicU16, 8932u16);
86        atomic_test!(AtomicU32, 58902u32);
87        atomic_test!(AtomicU64, 90887783u64);
88        atomic_test!(AtomicUsize, usize::MAX);
89    }
90}