1use crate::{
2 with::{ArchiveWith, Atomic, DeserializeWith, SerializeWith, With},
3 Archived, Fallible,
4};
5use core::sync::atomic::{
6 AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicU16, AtomicU32, AtomicU8, Ordering,
7};
8#[cfg(has_atomics_64)]
9use core::sync::atomic::{AtomicI64, AtomicU64};
10
11macro_rules! impl_atomic {
12 (@serialize_deserialize $type:ty) => {
13 impl<S: Fallible + ?Sized> SerializeWith<$type, S> for Atomic {
14 #[inline]
15 fn serialize_with(_: &$type, _: &mut S) -> Result<Self::Resolver, S::Error> {
16 Ok(())
17 }
18 }
19 };
20 ($type:ty) => {
21 impl ArchiveWith<$type> for Atomic {
22 type Archived = $type;
23 type Resolver = ();
24
25 #[inline]
26 unsafe fn resolve_with(field: &$type, _: usize, _: Self::Resolver, out: *mut Self::Archived) {
27 (&*out).store(field.load(Ordering::Relaxed), Ordering::Relaxed);
28 }
29 }
30
31 impl_atomic!(@serialize_deserialize $type);
32
33 impl<D: Fallible + ?Sized> DeserializeWith<$type, $type, D> for Atomic {
34 #[inline]
35 fn deserialize_with(field: &$type, _: &mut D) -> Result<$type, D::Error> {
36 Ok(field.load(Ordering::Relaxed).into())
37 }
38 }
39 };
40 (@multibyte $type:ty) => {
41 impl ArchiveWith<$type> for Atomic {
42 #[cfg(not(any(feature = "archive_le", feature = "archive_be")))]
43 type Archived = $type;
44 #[cfg(feature = "archive_le")]
45 type Archived = crate::rend::LittleEndian<$type>;
46 #[cfg(feature = "archive_be")]
47 type Archived = crate::rend::BigEndian<$type>;
48
49 type Resolver = ();
50
51 #[inline]
52 unsafe fn resolve_with(field: &$type, _: usize, _: Self::Resolver, out: *mut Self::Archived) {
53 (&*out).store(field.load(Ordering::Relaxed), Ordering::Relaxed);
54 }
55 }
56
57 impl_atomic!(@serialize_deserialize $type);
58
59 impl<D: Fallible + ?Sized> DeserializeWith<Archived<With<$type, Self>>, $type, D> for Atomic {
60 #[inline]
61 fn deserialize_with(field: &Archived<With<$type, Self>>, _: &mut D) -> Result<$type, D::Error> {
62 Ok(field.load(Ordering::Relaxed).into())
63 }
64 }
65 };
66}
67
68impl_atomic!(AtomicBool);
69impl_atomic!(AtomicI8);
70impl_atomic!(AtomicU8);
71
72impl_atomic!(@multibyte AtomicI16);
73impl_atomic!(@multibyte AtomicI32);
74#[cfg(has_atomics_64)]
75impl_atomic!(@multibyte AtomicI64);
76impl_atomic!(@multibyte AtomicU16);
77impl_atomic!(@multibyte AtomicU32);
78#[cfg(has_atomics_64)]
79impl_atomic!(@multibyte AtomicU64);
80
81#[cfg(any(has_atomics_64, not(feature = "size_64")))]
86const _: () = {
87 use crate::FixedUsize;
88 use core::sync::atomic::AtomicUsize;
89
90 #[cfg(not(has_atomics_64))]
91 type FixedAtomicUsize = pick_size_type!(AtomicU16, AtomicU32, ());
92 #[cfg(has_atomics_64)]
93 type FixedAtomicUsize = pick_size_type!(AtomicU16, AtomicU32, AtomicU64);
94
95 impl ArchiveWith<AtomicUsize> for Atomic {
96 type Archived = Archived<With<FixedAtomicUsize, Self>>;
97 type Resolver = ();
98
99 #[inline]
100 unsafe fn resolve_with(
101 field: &AtomicUsize,
102 _: usize,
103 _: Self::Resolver,
104 out: *mut Self::Archived,
105 ) {
106 (&*out).store(
107 field.load(Ordering::Relaxed) as FixedUsize,
108 Ordering::Relaxed,
109 );
110 }
111 }
112
113 impl<S: Fallible + ?Sized> SerializeWith<AtomicUsize, S> for Atomic {
114 #[inline]
115 fn serialize_with(_: &AtomicUsize, _: &mut S) -> Result<Self::Resolver, S::Error> {
116 Ok(())
117 }
118 }
119
120 impl<D: Fallible + ?Sized>
121 DeserializeWith<<Self as ArchiveWith<FixedAtomicUsize>>::Archived, AtomicUsize, D>
122 for Atomic
123 {
124 #[inline]
125 fn deserialize_with(
126 field: &<Self as ArchiveWith<FixedAtomicUsize>>::Archived,
127 _: &mut D,
128 ) -> Result<AtomicUsize, D::Error> {
129 Ok((field.load(Ordering::Relaxed) as usize).into())
130 }
131 }
132};
133
134#[cfg(any(has_atomics_64, not(feature = "size_64")))]
139const _: () = {
140 use crate::FixedIsize;
141 use core::sync::atomic::AtomicIsize;
142
143 #[cfg(not(has_atomics_64))]
144 type FixedAtomicIsize = pick_size_type!(AtomicI16, AtomicI32, ());
145 #[cfg(has_atomics_64)]
146 type FixedAtomicIsize = pick_size_type!(AtomicI16, AtomicI32, AtomicI64);
147
148 impl ArchiveWith<AtomicIsize> for Atomic {
149 type Archived = Archived<With<FixedAtomicIsize, Self>>;
150 type Resolver = ();
151
152 #[inline]
153 unsafe fn resolve_with(
154 field: &AtomicIsize,
155 _: usize,
156 _: Self::Resolver,
157 out: *mut Self::Archived,
158 ) {
159 (&*out).store(
160 field.load(Ordering::Relaxed) as FixedIsize,
161 Ordering::Relaxed,
162 );
163 }
164 }
165
166 impl<S: Fallible + ?Sized> SerializeWith<AtomicIsize, S> for Atomic {
167 #[inline]
168 fn serialize_with(_: &AtomicIsize, _: &mut S) -> Result<Self::Resolver, S::Error> {
169 Ok(())
170 }
171 }
172
173 impl<D: Fallible + ?Sized> DeserializeWith<Archived<With<AtomicIsize, Self>>, AtomicIsize, D>
174 for Atomic
175 {
176 #[inline]
177 fn deserialize_with(
178 field: &Archived<With<AtomicIsize, Self>>,
179 _: &mut D,
180 ) -> Result<AtomicIsize, D::Error> {
181 Ok((field.load(Ordering::Relaxed) as isize).into())
182 }
183 }
184};