1use core::sync::atomic::Ordering;
2
3use crate::Sealed;
4
5#[expect(private_bounds)]
32pub trait PrimitiveAtomic: Sealed + Sized + Send + Sync {
33 type Value: Copy + Send + Sync + crate::AtomicPrimitive<Atomic = Self>;
39
40 fn new(value: Self::Value) -> Self;
42
43 fn get_mut(&mut self) -> &mut Self::Value;
45
46 fn into_inner(self) -> Self::Value;
48
49 fn load(&self, order: Ordering) -> Self::Value;
51
52 fn store(&self, value: Self::Value, order: Ordering);
54
55 fn swap(&self, value: Self::Value, order: Ordering) -> Self::Value;
57
58 fn compare_exchange(
61 &self,
62 current: Self::Value,
63 new: Self::Value,
64 success: Ordering,
65 failure: Ordering,
66 ) -> Result<Self::Value, Self::Value>;
67
68 fn compare_exchange_weak(
72 &self,
73 current: Self::Value,
74 new: Self::Value,
75 success: Ordering,
76 failure: Ordering,
77 ) -> Result<Self::Value, Self::Value>;
78
79 fn fetch_update<F>(
83 &self,
84 set_order: Ordering,
85 fetch_order: Ordering,
86 f: F,
87 ) -> Result<Self::Value, Self::Value>
88 where
89 F: FnMut(Self::Value) -> Option<Self::Value>;
90
91 fn fetch_and(&self, val: Self::Value, order: Ordering) -> Self::Value;
93
94 fn fetch_nand(&self, val: Self::Value, order: Ordering) -> Self::Value;
96
97 fn fetch_or(&self, val: Self::Value, order: Ordering) -> Self::Value;
99
100 fn fetch_xor(&self, val: Self::Value, order: Ordering) -> Self::Value;
102
103 fn as_ptr(&self) -> *mut Self::Value;
105}
106
107macro_rules! impl_primitive_atomic {
108 ($Atomic:ty, $Value:ty) => {
109 impl Sealed for $Atomic {}
110
111 impl PrimitiveAtomic for $Atomic {
112 type Value = $Value;
113
114 forward! {
115 fn new(value: $Value) -> Self;
116 fn get_mut(&mut self) -> &mut $Value;
117 fn into_inner(self) -> $Value;
118 fn load(&self, order: Ordering) -> $Value;
119 }
120
121 #[inline]
123 fn store(&self, value: $Value, order: Ordering) {
124 <$Atomic>::store(self, value, order)
125 }
126
127 forward! {
128 fn swap(&self, value: $Value, order: Ordering) -> $Value;
129 fn compare_exchange(&self, current: $Value, new: $Value, success: Ordering, failure: Ordering) -> Result<$Value, $Value>;
130 fn compare_exchange_weak(&self, current: $Value, new: $Value, success: Ordering, failure: Ordering) -> Result<$Value, $Value>;
131 }
132
133 #[inline]
135 fn fetch_update<F>(
136 &self,
137 set_order: Ordering,
138 fetch_order: Ordering,
139 f: F,
140 ) -> Result<$Value, $Value>
141 where
142 F: FnMut($Value) -> Option<$Value>,
143 {
144 <$Atomic>::fetch_update(self, set_order, fetch_order, f)
145 }
146
147 forward! {
148 fn fetch_and(&self, val: $Value, order: Ordering) -> $Value;
149 fn fetch_nand(&self, val: $Value, order: Ordering) -> $Value;
150 fn fetch_or(&self, val: $Value, order: Ordering) -> $Value;
151 fn fetch_xor(&self, val: $Value, order: Ordering) -> $Value;
152 fn as_ptr(&self) -> *mut $Value;
153 }
154 }
155 };
156}
157
158use core::sync::atomic::{
159 AtomicBool, AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicU8, AtomicU16, AtomicU32,
160 AtomicUsize,
161};
162#[cfg(target_has_atomic = "64")]
163use core::sync::atomic::{AtomicI64, AtomicU64};
164
165impl_primitive_atomic!(AtomicBool, bool);
166impl_primitive_atomic!(AtomicU8, u8);
167impl_primitive_atomic!(AtomicU16, u16);
168impl_primitive_atomic!(AtomicU32, u32);
169impl_primitive_atomic!(AtomicUsize, usize);
170impl_primitive_atomic!(AtomicI8, i8);
171impl_primitive_atomic!(AtomicI16, i16);
172impl_primitive_atomic!(AtomicI32, i32);
173impl_primitive_atomic!(AtomicIsize, isize);
174#[cfg(target_has_atomic = "64")]
175impl_primitive_atomic!(AtomicU64, u64);
176#[cfg(target_has_atomic = "64")]
177impl_primitive_atomic!(AtomicI64, i64);