1macro_rules! get_ptr_method {
4 ($self:expr, $base:expr, $S:ty, $F:ty) => {{
5 #[cfg(feature = "testing")]
6 let _: *const $S = $base;
7
8 ($base as *const $S as *const u8).offset($self.offset as isize) as *const $F
9 }};
10}
11
12macro_rules! get_mut_ptr_method {
15 ($self:expr, $base:expr, $S:ty, $F:ty) => {{
16 #[cfg(feature = "testing")]
17 let _: *mut $S = $base;
18
19 ($base as *mut $S as *mut u8).offset($self.offset as isize) as *mut $F
20 }};
21}
22
23macro_rules! replace_unaligned {
24 ($self:expr, $base:expr, $value:expr, $S:ty, $F:ty) => {{
25 let ptr = get_mut_ptr_method!($self, $base, $S, $F);
26 let ret = ptr.read_unaligned();
27 ptr.write_unaligned($value);
28 ret
29 }};
30}
31
32macro_rules! unaligned_swap {
33 ($self:expr, $left:expr, $right:expr, $left_to_right:expr, $S:ty, $F:ty) => {{
34 let mut tmp = core::mem::MaybeUninit::<$F>::uninit();
36 let tmp = tmp.as_mut_ptr() as *mut u8;
37
38 let left = get_mut_ptr_method!($self, $left, $S, $F) as *mut u8;
39 let right = get_mut_ptr_method!($self, $right, $S, $F) as *mut u8;
40 core::ptr::copy_nonoverlapping(left, tmp, crate::utils::Mem::<$F>::SIZE);
41 $left_to_right(right, left, crate::utils::Mem::<$F>::SIZE);
42 core::ptr::copy_nonoverlapping(tmp, right, crate::utils::Mem::<$F>::SIZE);
43 }};
44}
45
46macro_rules! impl_fo {
47 (fn get<$S:ty, $F:ty, Aligned>($self:expr, $base:expr)) => {
48 &*get_ptr_method!($self, $base, $S, $F)
49 };
50 (fn get_mut<$S:ty, $F:ty, Aligned>($self:expr, $base:expr)) => {
51 &mut *get_mut_ptr_method!($self, $base, $S, $F)
52 };
53 (fn get_ptr<$S:ty, $F:ty, $A:ident>($self:expr, $base:expr)) => {
54 get_ptr_method!($self, $base, $S, $F)
55 };
56 (fn get_mut_ptr<$S:ty, $F:ty, $A:ident>($self:expr, $base:expr)) => {
57 get_mut_ptr_method!($self, $base, $S, $F)
58 };
59 (fn raw_get<$S:ty, $F:ty, $A:ident>($self:expr, $base:expr)) => {
60 get_ptr_method!($self, $base, $S, $F)
61 };
62 (fn raw_get_mut<$S:ty, $F:ty, $A:ident>($self:expr, $base:expr)) => {
63 get_mut_ptr_method!($self, $base, $S, $F)
64 };
65 (fn get_copy<$S:ty, $F:ty, $A:ident>($self:expr, $base:expr)) => {
66 if_aligned! {
67 $A {
68 *get_ptr_method!($self, $base, $S, $F)
69 } else {
70 get_ptr_method!($self, $base, $S, $F).read_unaligned()
71 }
72 }
73 };
74 (fn read_copy<$S:ty, $F:ty, $A:ident>($self:expr, $base:expr)) => {
75 if_aligned! {
76 $A {
77 *get_ptr_method!($self, $base, $S, $F)
78 } else {
79 get_ptr_method!($self, $base, $S, $F).read_unaligned()
80 }
81 }
82 };
83 (fn read<$S:ty, $F:ty, $A:ident>($self:expr, $source:ident)) => {
84 if_aligned! {
85 $A {
86 get_ptr_method!($self, $source, $S, $F).read()
87 } else {
88 get_ptr_method!($self, $source, $S, $F).read_unaligned()
89 }
90 }
91 };
92 (fn write<$S:ty, $F:ty, $A:ident>($self:expr, $dst:ident, $value:ident)) => {
93 if_aligned! {
94 $A {
95 get_mut_ptr_method!($self, $dst, $S, $F).write($value)
96 } else {
97 get_mut_ptr_method!($self, $dst, $S, $F).write_unaligned($value)
98 }
99 }
100 };
101 (fn copy<$S:ty, $F:ty, $A:ident>($self:expr, $source:ident, $dst:ident)) => {
102 if_aligned! {
103 $A {
104 core::ptr::copy(
105 get_ptr_method!($self, $source, $S, $F),
106 get_mut_ptr_method!($self, $dst, $S, $F),
107 1,
108 )
109 } else {
110 core::ptr::copy(
111 get_ptr_method!($self, $source, $S, $F) as *const u8,
112 get_mut_ptr_method!($self, $dst, $S, $F) as *mut u8,
113 crate::utils::Mem::<F>::SIZE,
114 )
115 }
116 }
117 };
118 (fn copy_nonoverlapping<$S:ty, $F:ty, $A:ident>($self:expr, $source:ident, $dst:ident)) => {
119 if_aligned! {
120 $A {
121 core::ptr::copy_nonoverlapping(
122 get_ptr_method!($self, $source, $S, $F),
123 get_mut_ptr_method!($self, $dst, $S, $F),
124 1,
125 )
126 } else {
127 core::ptr::copy_nonoverlapping(
128 get_ptr_method!($self, $source, $S, $F) as *const u8,
129 get_mut_ptr_method!($self, $dst, $S, $F) as *mut u8,
130 crate::utils::Mem::<F>::SIZE,
131 )
132 }
133 }
134 };
135 (fn replace<$S:ty, $F:ty, $A:ident>($self:expr, $dst:ident, $value:ident)) => {
136 if_aligned! {
137 $A {
138 core::ptr::replace(get_mut_ptr_method!($self, $dst, $S, $F), $value)
139 } else {
140 replace_unaligned!($self, $dst, $value, $S, $F)
141 }
142 }
143 };
144 (fn replace_mut<$S:ty, $F:ty, $A:ident>($self:expr, $dst:ident, $value:ident)) => {
145 if_aligned! {
146 $A {
147 core::mem::replace(&mut *get_mut_ptr_method!($self, $dst, $S, $F), $value)
148 } else {
149 replace_unaligned!($self, $dst, $value, $S, $F)
150 }
151 }
152 };
153 (fn swap<$S:ty, $F:ty, $A:ident>($self:expr, $l:ident, $r:ident)) => {
154 if_aligned! {
155 $A {
156 core::ptr::swap::<F>(
157 get_mut_ptr_method!($self, $l, $S, $F),
158 get_mut_ptr_method!($self, $r, $S, $F),
159 )
160 } else {
161 unaligned_swap!($self, $l, $r, core::ptr::copy, $S, $F)
162 }
163 }
164 };
165 (fn swap_nonoverlapping<$S:ty, $F:ty, $A:ident>($self:expr, $l:ident, $r:ident)) => {
166 if_aligned! {
167 $A {
168 core::ptr::swap_nonoverlapping::<F>(
169 get_mut_ptr_method!($self, $l, $S, $F),
170 get_mut_ptr_method!($self, $r, $S, $F),
171 1,
172 )
173 } else {
174 unaligned_swap!($self, $l, $r, core::ptr::copy_nonoverlapping, $S, $F)
175 }
176 }
177 };
178 (fn swap_mut<$S:ty, $F:ty, $A:ident>($self:expr, $l:ident, $r:ident)) => {
179 if_aligned! {
180 $A {
181 core::mem::swap(
182 &mut *get_mut_ptr_method!($self, $l, $S, $F),
183 &mut *get_mut_ptr_method!($self, $r, $S, $F),
184 )
185 } else {{
186 let l = get_mut_ptr_method!($self, $l, $S, $F);
188 let r = get_mut_ptr_method!($self, $r, $S, $F);
189 let tmp = l.read_unaligned();
190 l.write_unaligned(r.read_unaligned());
191 r.write_unaligned(tmp);
192 }}
193 }
194 };
195}
196
197macro_rules! if_aligned {
198 (Aligned {$($then:tt)*} else {$($else:tt)*}) => {
199 $($then)*
200 };
201 (Unaligned {$($then:tt)*} else {$($else:tt)*}) => {
202 $($else)*
203 };
204}