rkyv_test/with/
atomic.rs

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// AtomicUsize
82
83// We can't implement Archive for AtomicUsize if the platform does not have 64-bit atomics but the
84// size type is 64-bit
85#[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// AtomicIsize
135
136// We can't implement Archive for AtomicIsize if the platform does not have 64-bit atomics but the
137// size type is 64-bit
138#[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};