]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | //! Macros implementing `FromBits` |
2 | ||
3 | macro_rules! impl_from_bits_ { | |
4 | ($id:ident[$test_tt:tt]: $from_ty:ident) => { | |
5 | impl crate::api::into_bits::FromBits<$from_ty> for $id { | |
6 | #[inline] | |
7 | fn from_bits(x: $from_ty) -> Self { | |
8 | unsafe { crate::mem::transmute(x) } | |
9 | } | |
10 | } | |
11 | ||
12 | test_if! { | |
13 | $test_tt: | |
14 | paste::item! { | |
15 | pub mod [<$id _from_bits_ $from_ty>] { | |
16 | use super::*; | |
17 | #[cfg_attr(not(target_arch = "wasm32"), test)] | |
18 | #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | |
19 | fn test() { | |
20 | use crate::{ | |
21 | ptr::{read_unaligned}, | |
22 | mem::{size_of, zeroed} | |
23 | }; | |
24 | use crate::IntoBits; | |
25 | assert_eq!(size_of::<$id>(), | |
26 | size_of::<$from_ty>()); | |
27 | // This is safe becasue we never create a reference to | |
28 | // uninitialized memory: | |
29 | let a: $from_ty = unsafe { zeroed() }; | |
30 | ||
31 | let b_0: $id = crate::FromBits::from_bits(a); | |
32 | let b_1: $id = a.into_bits(); | |
33 | ||
34 | // Check that these are byte-wise equal, that is, | |
35 | // that the bit patterns are identical: | |
36 | for i in 0..size_of::<$id>() { | |
37 | // This is safe because we only read initialized | |
38 | // memory in bounds. Also, taking a reference to | |
39 | // `b_i` is ok because the fields are initialized. | |
40 | unsafe { | |
41 | let b_0_v: u8 = read_unaligned( | |
42 | (&b_0 as *const $id as *const u8) | |
43 | .wrapping_add(i) | |
44 | ); | |
45 | let b_1_v: u8 = read_unaligned( | |
46 | (&b_1 as *const $id as *const u8) | |
47 | .wrapping_add(i) | |
48 | ); | |
49 | assert_eq!(b_0_v, b_1_v); | |
50 | } | |
51 | } | |
52 | } | |
53 | } | |
54 | } | |
55 | } | |
56 | }; | |
57 | } | |
58 | ||
59 | macro_rules! impl_from_bits { | |
60 | ($id:ident[$test_tt:tt]: $($from_ty:ident),*) => { | |
61 | $( | |
62 | impl_from_bits_!($id[$test_tt]: $from_ty); | |
63 | )* | |
64 | } | |
65 | } | |
66 | ||
67 | #[allow(unused)] | |
68 | macro_rules! impl_into_bits { | |
69 | ($id:ident[$test_tt:tt]: $($from_ty:ident),*) => { | |
70 | $( | |
71 | impl_from_bits_!($from_ty[$test_tt]: $id); | |
72 | )* | |
73 | } | |
74 | } |