rend/
traits.rs

1macro_rules! impl_unop {
2    ($trait:ident:: $fn:ident for $name:ident : $prim:ty) => {
3        impl ::core::ops::$trait for $name {
4            type Output = <$prim as ::core::ops::$trait>::Output;
5
6            #[inline]
7            fn $fn(self) -> Self::Output {
8                self.to_native().$fn()
9            }
10        }
11    };
12}
13
14macro_rules! impl_binop_nonzero {
15    ($trait:ident::$fn:ident for $name:ident: $prim:ty) => {
16        impl_binop_both!($trait::$fn ($name, $prim) -> $prim);
17        impl_binop_both!($trait::$fn (&'_ $name, $prim) -> $prim);
18
19        impl_binop_one!($trait::$fn ($name, $name) -> $prim);
20        impl_binop_one!($trait::$fn (&'_ $name, $name) -> $prim);
21        impl_binop_one!($trait::$fn ($name, &'_ $name) -> $prim);
22        impl_binop_one!($trait::$fn (&'_ $name, &'_ $name) -> $prim);
23    };
24}
25
26macro_rules! impl_binop_one {
27    ($trait:ident:: $fn:ident($self:ty, $other:ty) -> $output:ty) => {
28        impl ::core::ops::$trait<$other> for $self {
29            type Output = $output;
30
31            #[inline]
32            fn $fn(self, other: $other) -> Self::Output {
33                self.to_native().$fn(other.to_native())
34            }
35        }
36    };
37}
38
39macro_rules! impl_binop_both {
40    ($trait:ident:: $fn:ident($self:ty, $other:ty) -> $output:ty) => {
41        impl ::core::ops::$trait<$other> for $self {
42            type Output = $output;
43
44            #[inline]
45            fn $fn(self, other: $other) -> Self::Output {
46                self.to_native().$fn(other)
47            }
48        }
49
50        impl ::core::ops::$trait<$self> for $other {
51            type Output = $output;
52
53            #[inline]
54            fn $fn(self, other: $self) -> Self::Output {
55                self.$fn(other.to_native())
56            }
57        }
58    };
59}
60
61macro_rules! impl_binop {
62    ($trait:ident::$fn:ident for $name:ident: $prim:ty) => {
63        impl_binop_both!($trait::$fn ($name, $prim) -> $prim);
64        impl_binop_both!($trait::$fn (&'_ $name, $prim) -> $prim);
65        impl_binop_both!($trait::$fn ($name, &'_ $prim) -> $prim);
66        impl_binop_both!($trait::$fn (&'_ $name, &'_ $prim) -> $prim);
67
68        impl_binop_one!($trait::$fn ($name, $name) -> $prim);
69        impl_binop_one!($trait::$fn (&'_ $name, $name) -> $prim);
70        impl_binop_one!($trait::$fn ($name, &'_ $name) -> $prim);
71        impl_binop_one!($trait::$fn (&'_ $name, &'_ $name) -> $prim);
72    };
73}
74
75macro_rules! impl_binassign_nonzero {
76    ($trait:ident:: $fn:ident for $name:ident : $prim:ty) => {
77        impl ::core::ops::$trait<$prim> for $name {
78            #[inline]
79            fn $fn(&mut self, other: $prim) {
80                let mut value = self.to_native();
81                value.$fn(other);
82                *self = Self::from_native(value);
83            }
84        }
85
86        impl ::core::ops::$trait<$name> for $name {
87            #[inline]
88            fn $fn(&mut self, other: $name) {
89                let mut value = self.to_native();
90                value.$fn(other.to_native());
91                *self = Self::from_native(value);
92            }
93        }
94    };
95}
96
97macro_rules! impl_binassign {
98    ($trait:ident:: $fn:ident for $name:ident : $prim:ty) => {
99        impl ::core::ops::$trait<$prim> for $name {
100            #[inline]
101            fn $fn(&mut self, other: $prim) {
102                let mut value = self.to_native();
103                value.$fn(other);
104                *self = Self::from_native(value);
105            }
106        }
107
108        impl ::core::ops::$trait<$name> for $name {
109            #[inline]
110            fn $fn(&mut self, other: $name) {
111                let mut value = self.to_native();
112                value.$fn(other.to_native());
113                *self = Self::from_native(value);
114            }
115        }
116
117        impl ::core::ops::$trait<&'_ $prim> for $name {
118            #[inline]
119            fn $fn(&mut self, other: &'_ $prim) {
120                let mut value = self.to_native();
121                value.$fn(other);
122                *self = Self::from_native(value);
123            }
124        }
125
126        impl ::core::ops::$trait<&'_ $name> for $name {
127            #[inline]
128            fn $fn(&mut self, other: &'_ $name) {
129                let mut value = self.to_native();
130                value.$fn(other.to_native());
131                *self = Self::from_native(value);
132            }
133        }
134    };
135}
136
137macro_rules! impl_clone_and_copy {
138    (for $name:ident) => {
139        impl Clone for $name {
140            #[inline]
141            fn clone(&self) -> Self {
142                *self
143            }
144        }
145
146        impl Copy for $name {}
147    };
148}
149
150macro_rules! impl_fmt {
151    ($trait:ident for $name:ident) => {
152        impl ::core::fmt::$trait for $name {
153            #[inline]
154            fn fmt(
155                &self,
156                f: &mut ::core::fmt::Formatter<'_>,
157            ) -> ::core::fmt::Result {
158                ::core::fmt::$trait::fmt(&self.to_native(), f)
159            }
160        }
161    };
162}
163
164macro_rules! impl_default {
165    (for $name:ident : $prim:ty) => {
166        impl Default for $name {
167            #[inline]
168            fn default() -> Self {
169                Self::from_native(<$prim>::default())
170            }
171        }
172    };
173}
174
175macro_rules! impl_from {
176    (for $name:ident : $prim:ty) => {
177        impl From<$prim> for $name {
178            fn from(value: $prim) -> Self {
179                Self::from_native(value)
180            }
181        }
182
183        impl<'a> From<&'a $prim> for $name {
184            fn from(value: &'a $prim) -> Self {
185                Self::from_native(*value)
186            }
187        }
188
189        impl From<$name> for $prim {
190            fn from(value: $name) -> Self {
191                value.to_native()
192            }
193        }
194
195        impl<'a> From<&'a $name> for $prim {
196            fn from(value: &'a $name) -> Self {
197                value.to_native()
198            }
199        }
200    };
201}
202
203macro_rules! impl_try_from_ptr_size {
204    ($size:ident for $name:ident: $prim:ident) => {
205        impl TryFrom<$size> for $name {
206            type Error = <$prim as TryFrom<$size>>::Error;
207
208            #[inline]
209            fn try_from(value: $size) -> Result<Self, Self::Error> {
210                Ok(Self::from_native(<$prim>::try_from(value)?))
211            }
212        }
213
214        impl_try_into_ptr_size!($size for $name: $prim);
215    };
216}
217
218macro_rules! impl_try_into_ptr_size {
219    (isize for $name:ident: i16) => {
220        impl_into_ptr_size!(isize for $name);
221    };
222
223    (usize for $name:ident: u16) => {
224        impl_into_ptr_size!(usize for $name);
225    };
226
227    ($size:ident for $name:ident: $prim:ident) => {
228        impl TryFrom<$name> for $size {
229            type Error = <$size as TryFrom<$prim>>::Error;
230
231            #[inline]
232            fn try_from(value: $name) -> Result<Self, Self::Error> {
233                <$size>::try_from(value.to_native())
234            }
235        }
236    };
237}
238
239macro_rules! impl_into_ptr_size {
240    ($size:ident for $name:ident) => {
241        impl From<$name> for $size {
242            #[inline]
243            fn from(value: $name) -> Self {
244                <$size>::from(value.to_native())
245            }
246        }
247    };
248}
249
250macro_rules! impl_hash {
251    (for $name:ident) => {
252        impl core::hash::Hash for $name {
253            fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
254                self.to_native().hash(state);
255            }
256        }
257    };
258}
259
260macro_rules! impl_partial_ord_and_ord {
261    (for $name:ident : $prim:ty) => {
262        impl PartialOrd for $name {
263            #[inline]
264            fn partial_cmp(
265                &self,
266                other: &Self,
267            ) -> Option<::core::cmp::Ordering> {
268                Some(self.cmp(other))
269            }
270        }
271
272        impl PartialOrd<$prim> for $name {
273            #[inline]
274            fn partial_cmp(
275                &self,
276                other: &$prim,
277            ) -> Option<::core::cmp::Ordering> {
278                self.to_native().partial_cmp(other)
279            }
280        }
281
282        impl Ord for $name {
283            #[inline]
284            fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
285                self.to_native().cmp(&other.to_native())
286            }
287        }
288    };
289}
290
291macro_rules! impl_partial_eq_and_eq {
292    (for $name:ident : $prim:ty) => {
293        impl PartialEq for $name {
294            #[inline]
295            fn eq(&self, other: &Self) -> bool {
296                let lhs = self.0;
297                let rhs = other.0;
298                lhs.eq(&rhs)
299            }
300        }
301
302        impl PartialEq<$prim> for $name {
303            #[inline]
304            fn eq(&self, other: &$prim) -> bool {
305                self.to_native().eq(other)
306            }
307        }
308
309        impl PartialEq<$name> for $prim {
310            #[inline]
311            fn eq(&self, other: &$name) -> bool {
312                self.eq(&other.to_native())
313            }
314        }
315
316        impl Eq for $name {}
317    };
318}
319
320macro_rules! impl_partial_ord {
321    (for $name:ident : $prim:ty) => {
322        impl PartialOrd for $name {
323            #[inline]
324            fn partial_cmp(
325                &self,
326                other: &Self,
327            ) -> Option<::core::cmp::Ordering> {
328                self.to_native().partial_cmp(&other.to_native())
329            }
330        }
331
332        impl PartialOrd<$prim> for $name {
333            #[inline]
334            fn partial_cmp(
335                &self,
336                other: &$prim,
337            ) -> Option<::core::cmp::Ordering> {
338                self.to_native().partial_cmp(other)
339            }
340        }
341    };
342}
343
344macro_rules! impl_product_and_sum {
345    (for $name:ident) => {
346        impl ::core::iter::Product for $name {
347            #[inline]
348            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
349                Self::from_native(iter.map(|x| x.to_native()).product())
350            }
351        }
352
353        impl ::core::iter::Sum for $name {
354            #[inline]
355            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
356                Self::from_native(iter.map(|x| x.to_native()).sum())
357            }
358        }
359    };
360}
361
362/// # Safety
363///
364/// An impl of `CheckBytes` with a `check_bytes` function that is a no-op must
365/// be sound for `$name`.
366macro_rules! unsafe_impl_check_bytes_noop {
367    (for $name:ident) => {
368        #[cfg(feature = "bytecheck")]
369        // SAFETY: All callers of this macro have guaranteed that all pointers
370        // to `$name`s which are properly aligned and point to enough bytes to
371        // represent the type also point to a valid instance of the type.
372        unsafe impl<C> bytecheck::CheckBytes<C> for $name
373        where
374            C: bytecheck::rancor::Fallible + ?Sized,
375        {
376            #[inline]
377            unsafe fn check_bytes(
378                _: *const Self,
379                _: &mut C,
380            ) -> Result<(), C::Error> {
381                // SAFETY: The invoker of this macro has guaranteed that an impl
382                // of `CheckBytes` with a `check_bytes` function that is a no-op
383                // is sound.
384                Ok(())
385            }
386        }
387    };
388}
389
390/// # Safety
391///
392/// An all-zero bit pattern for `$name` must be a valid value.
393/// As a rule, any derivative type (e.g. `u64_le` or `i32_be`) of a native type
394/// (e.g. `u64`, `i32`) that is `Zeroable` will also be zeroable.
395macro_rules! unsafe_impl_zeroable {
396    (for $name:ident) => {
397        #[cfg(feature = "bytemuck-1")]
398        unsafe impl bytemuck_1::Zeroable for $name {}
399    };
400}
401
402/// # Safety
403///
404/// Read the safety requirements of [`bytemuck::Pod`].
405/// In general, any type that is natively `Pod` (e.g. `u64`, `AtomicU32`) will
406/// be `Pod` even if wrapped (`u64_le`).
407///
408/// It is required that `$name` has an impl for `Zeroable` for this macro to
409/// work. See [`unsafe_impl_zeroable!()`].
410macro_rules! unsafe_impl_pod {
411    (for $name:ident) => {
412        #[cfg(feature = "bytemuck-1")]
413        unsafe impl bytemuck_1::Pod for $name {}
414    };
415}
416
417/// # Safety
418///
419/// Read the safety requirements of [`bytemuck::NoUninit`].
420/// All primitive types are `NoUninit` and as a result, all of this crates's
421/// wrapped primitive types are also `NoUninit`.
422macro_rules! unsafe_impl_no_uninit {
423    (for $name:ident) => {
424        #[cfg(feature = "bytemuck-1")]
425        unsafe impl bytemuck_1::NoUninit for $name {}
426    };
427}