Skip to main content

atomic_primitive/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3
4#[macro_use]
5mod macros;
6
7mod atomic;
8mod integer;
9mod signed;
10mod unsigned;
11
12#[cfg(test)]
13mod tests;
14
15pub use self::atomic::PrimitiveAtomic;
16pub use self::integer::PrimitiveAtomicInteger;
17pub use self::signed::PrimitiveAtomicSigned;
18pub use self::unsigned::PrimitiveAtomicUnsigned;
19
20trait Sealed {}
21
22/// Maps a non-atomic primitive type to its corresponding atomic type.
23///
24/// This mirrors the unstable [`core::sync::atomic::AtomicPrimitive`] trait.
25/// Once that trait is stabilized, this can be deprecated in favor of the std
26/// version.
27///
28/// # Examples
29///
30/// ```
31/// use atomic_primitive::{AtomicPrimitive, PrimitiveAtomic};
32///
33/// fn make_atomic<T: AtomicPrimitive>(val: T) -> T::Atomic {
34///     T::Atomic::new(val)
35/// }
36/// ```
37///
38/// [`core::sync::atomic::AtomicPrimitive`]: https://doc.rust-lang.org/core/sync/atomic/trait.AtomicPrimitive.html
39pub trait AtomicPrimitive: Sized + Copy + Send + Sync {
40    /// The atomic type corresponding to this primitive type.
41    ///
42    /// Note that the bound on `Value` is not imposed in the unstable
43    /// `core::sync::atomic::AtomicPrimitive` trait, but it is useful
44    /// to round-trip between the primitive and atomic types.
45    type Atomic: PrimitiveAtomic<Value = Self>;
46
47    /// Converts this value to its atomic counterpart.
48    #[inline]
49    fn to_atomic(self) -> Self::Atomic {
50        Self::Atomic::new(self)
51    }
52}
53
54/// Type alias for the atomic version of a primitive type.
55///
56/// This mirrors the unstable [`core::sync::atomic::Atomic`] type alias.
57///
58/// [`core::sync::atomic::Atomic`]: https://doc.rust-lang.org/core/sync/atomic/type.Atomic.html
59pub type Atomic<T> = <T as AtomicPrimitive>::Atomic;
60
61macro_rules! impl_atomic_primitive {
62    ($($Primitive:ty => $AtomicType:ty),+ $(,)?) => {$(
63        impl AtomicPrimitive for $Primitive {
64            type Atomic = $AtomicType;
65        }
66    )+};
67}
68
69use core::sync::atomic::{
70    AtomicBool, AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicU8, AtomicU16, AtomicU32,
71    AtomicUsize,
72};
73#[cfg(target_has_atomic = "64")]
74use core::sync::atomic::{AtomicI64, AtomicU64};
75
76impl_atomic_primitive! {
77    bool => AtomicBool,
78    u8 => AtomicU8,
79    u16 => AtomicU16,
80    u32 => AtomicU32,
81    usize => AtomicUsize,
82    i8 => AtomicI8,
83    i16 => AtomicI16,
84    i32 => AtomicI32,
85    isize => AtomicIsize,
86}
87
88#[cfg(target_has_atomic = "64")]
89impl_atomic_primitive! {
90    u64 => AtomicU64,
91    i64 => AtomicI64,
92}