proc_bitfield/traits/
arr_impls.rs1use super::{Bit, Bits, SetBit, SetBits, WithBit, WithBits};
2
3macro_rules! impl_bits_for_int_type {
4 ($storage: ident ($storage_u: ident), $value: ident ($value_u: ident)) => {
5 mod $value {
6 use super::*;
7 const S_SHIFT: u32 = <$storage>::BITS.trailing_zeros();
8 const S_MASK: usize = <$storage>::BITS as usize - 1;
9 const V_BITS: usize = <$value>::BITS as usize;
10 const V_SHIFT: u32 = <$value>::BITS.trailing_zeros();
11
12 impl<const N: usize> Bits<$value> for [$storage; N] {
13 #[inline]
14 fn bits<const START: usize, const END: usize>(&self) -> $value {
15 let bits = if START >> S_SHIFT == (END - 1) >> S_SHIFT {
16 (self[START >> S_SHIFT] >> (START & S_MASK)) as $value
17 } else {
18 let mut bits: $value = 0;
19 for i in START >> S_SHIFT..=(END - 1) >> S_SHIFT {
20 let start = START.max(i << S_SHIFT);
21 bits |= ((self[i] as $storage_u >> (start & S_MASK)) as $value)
22 << (start - START);
23 }
24 bits
25 };
26 let read_bits = END - START;
27 bits << (V_BITS - read_bits) >> (V_BITS - read_bits)
28 }
29 }
30
31 impl<const N: usize> WithBits<$value> for [$storage; N] {
32 #[inline]
33 fn with_bits<const START: usize, const END: usize>(
34 mut self,
35 value: $value,
36 ) -> Self {
37 self.set_bits::<START, END>(value);
38 self
39 }
40 }
41
42 impl<const N: usize> SetBits<$value> for [$storage; N] {
43 #[inline]
44 fn set_bits<const START: usize, const END: usize>(&mut self, value: $value) {
45 if START >> S_SHIFT == (END - 1) >> S_SHIFT {
46 let i = START >> S_SHIFT;
47 let written_bits = END - START;
48 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
49 << (START & S_MASK);
50 self[i] =
51 (self[i] & !mask) | ((value as $storage) << (START & S_MASK) & mask);
52 } else {
53 for i in START >> S_SHIFT..=(END - 1) >> S_SHIFT {
54 let start = START.max(i << S_SHIFT);
55 let end = END.min((i + 1) << S_SHIFT);
56 let written_bits = end - start;
57 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
58 << (start & S_MASK);
59 self[i] = (self[i] & !mask)
60 | (((value >> (start - START)) as $storage) << (start & S_MASK)
61 & mask);
62 }
63 }
64 }
65 }
66
67 impl Bits<$value> for [$storage] {
68 #[inline]
69 fn bits<const START: usize, const END: usize>(&self) -> $value {
70 let bits = if START >> S_SHIFT == (END - 1) >> S_SHIFT {
71 (self[START >> S_SHIFT] >> (START & S_MASK)) as $value
72 } else {
73 let mut bits: $value = 0;
74 for i in START >> S_SHIFT..=(END - 1) >> S_SHIFT {
75 let start = START.max(i << S_SHIFT);
76 bits |= ((self[i] as $storage_u >> (start & S_MASK)) as $value)
77 << (start - START);
78 }
79 bits
80 };
81 let read_bits = END - START;
82 bits << (V_BITS - read_bits) >> (V_BITS - read_bits)
83 }
84 }
85
86 impl SetBits<$value> for [$storage] {
87 #[inline]
88 fn set_bits<const START: usize, const END: usize>(&mut self, value: $value) {
89 if START >> S_SHIFT == (END - 1) >> S_SHIFT {
90 let i = START >> S_SHIFT;
91 let written_bits = END - START;
92 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
93 << (START & S_MASK);
94 self[i] =
95 (self[i] & !mask) | ((value as $storage) << (START & S_MASK) & mask);
96 } else {
97 for i in START >> S_SHIFT..=(END - 1) >> S_SHIFT {
98 let start = START.max(i << S_SHIFT);
99 let end = END.min((i + 1) << S_SHIFT);
100 let written_bits = end - start;
101 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
102 << (start & S_MASK);
103 self[i] = (self[i] & !mask)
104 | (((value >> (start - START)) as $storage) << (start & S_MASK)
105 & mask);
106 }
107 }
108 }
109 }
110
111 impl<const M: usize> Bits<[$value; M]> for $storage {
112 #[inline]
113 fn bits<const START: usize, const END: usize>(&self) -> [$value; M] {
114 let mut result = [0; M];
115 for i in 0..=(END - START - 1) >> V_SHIFT {
116 let start = START + (i << V_SHIFT);
117 let end = (start + V_BITS).min(END);
118 let read_bits = end - start;
119 result[i] = ((*self >> start) as $value) << (V_BITS - read_bits)
120 >> (V_BITS - read_bits);
121 }
122 result
123 }
124 }
125
126 impl<const M: usize> WithBits<[$value; M]> for $storage {
127 #[inline]
128 fn with_bits<const START: usize, const END: usize>(
129 mut self,
130 value: [$value; M],
131 ) -> Self {
132 for i in 0..=(END - START - 1) >> V_SHIFT {
133 let start = START + (i << V_SHIFT);
134 let end = (start + V_BITS).min(END);
135 let written_bits = end - start;
136 let mask =
137 ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1) << start;
138 self = (self & !mask) | ((value[i] as $storage) << start & mask);
139 }
140 self
141 }
142 }
143
144 impl<const M: usize> SetBits<[$value; M]> for $storage {
145 #[inline]
146 fn set_bits<const START: usize, const END: usize>(&mut self, value: [$value; M]) {
147 *self = self.with_bits::<START, END>(value);
148 }
149 }
150
151 impl<const M: usize, const N: usize> Bits<[$value; M]> for [$storage; N] {
152 #[inline]
153 fn bits<const START: usize, const END: usize>(&self) -> [$value; M] {
154 let mut result = [0; M];
155 for i in 0..=(END - START - 1) >> V_SHIFT {
156 let start = START + (i << V_SHIFT);
157 let end = (start + V_BITS).min(END);
158 let bits = if start >> S_SHIFT == (end - 1) >> S_SHIFT {
159 (self[start >> S_SHIFT] >> (start & S_MASK)) as $value
160 } else {
161 let mut bits: $value = 0;
162 for j in start >> S_SHIFT..=(end - 1) >> S_SHIFT {
163 let start_ = start.max(j << S_SHIFT);
164 bits |= ((self[j] as $storage_u >> (start_ & S_MASK)) as $value)
165 << (start_ - start);
166 }
167 bits
168 };
169 let read_bits = end - start;
170 result[i] = bits << (V_BITS - read_bits) >> (V_BITS - read_bits);
171 }
172 result
173 }
174 }
175
176 impl<const M: usize, const N: usize> WithBits<[$value; M]> for [$storage; N] {
177 #[inline]
178 fn with_bits<const START: usize, const END: usize>(
179 mut self,
180 value: [$value; M],
181 ) -> Self {
182 self.set_bits::<START, END>(value);
183 self
184 }
185 }
186
187 impl<const M: usize, const N: usize> SetBits<[$value; M]> for [$storage; N] {
188 #[inline]
189 fn set_bits<const START: usize, const END: usize>(&mut self, value: [$value; M]) {
190 for i in 0..=(END - START - 1) >> V_SHIFT {
191 let start = START + (i << V_SHIFT);
192 let end = (start + V_BITS).min(END);
193 if start >> S_SHIFT == (end - 1) >> S_SHIFT {
194 let j = start >> S_SHIFT;
195 let written_bits = end - start;
196 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
197 << (start & S_MASK);
198 self[j] = (self[j] & !mask)
199 | ((value[i] as $storage) << (start & S_MASK) & mask);
200 } else {
201 for j in start >> S_SHIFT..=(end - 1) >> S_SHIFT {
202 let start_ = start.max(j << S_SHIFT);
203 let end_ = end.min((j + 1) << S_SHIFT);
204 let written_bits = end_ - start_;
205 let mask = ((1 as $storage) << (written_bits - 1) << 1)
206 .wrapping_sub(1)
207 << (start_ & S_MASK);
208 self[j] = (self[j] & !mask)
209 | (((value[i] >> (start_ - start)) as $storage)
210 << (start_ & S_MASK)
211 & mask);
212 }
213 }
214 }
215 }
216 }
217
218 impl<const M: usize> Bits<[$value; M]> for [$storage] {
219 #[inline]
220 fn bits<const START: usize, const END: usize>(&self) -> [$value; M] {
221 let mut result = [0; M];
222 for i in 0..=(END - START - 1) >> V_SHIFT {
223 let start = START + (i << V_SHIFT);
224 let end = (start + V_BITS).min(END);
225 let bits = if start >> S_SHIFT == (end - 1) >> S_SHIFT {
226 (self[start >> S_SHIFT] >> (start & S_MASK)) as $value
227 } else {
228 let mut bits: $value = 0;
229 for j in start >> S_SHIFT..=(end - 1) >> S_SHIFT {
230 let start_ = start.max(j << S_SHIFT);
231 bits |= ((self[j] as $storage_u >> (start_ & S_MASK)) as $value)
232 << (start_ - start);
233 }
234 bits
235 };
236 let read_bits = end - start;
237 result[i] = bits << (V_BITS - read_bits) >> (V_BITS - read_bits);
238 }
239 result
240 }
241 }
242
243 impl<const M: usize> SetBits<[$value; M]> for [$storage] {
244 #[inline]
245 fn set_bits<const START: usize, const END: usize>(&mut self, value: [$value; M]) {
246 for i in 0..=(END - START - 1) >> V_SHIFT {
247 let start = START + (i << V_SHIFT);
248 let end = (start + V_BITS).min(END);
249 if start >> S_SHIFT == (end - 1) >> S_SHIFT {
250 let j = start >> S_SHIFT;
251 let written_bits = end - start;
252 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
253 << (start & S_MASK);
254 self[j] = (self[j] & !mask)
255 | ((value[i] as $storage) << (start & S_MASK) & mask);
256 } else {
257 for j in start >> S_SHIFT..=(end - 1) >> S_SHIFT {
258 let start_ = start.max(j << S_SHIFT);
259 let end_ = end.min((j + 1) << S_SHIFT);
260 let written_bits = end_ - start_;
261 let mask = ((1 as $storage) << (written_bits - 1) << 1)
262 .wrapping_sub(1)
263 << (start_ & S_MASK);
264 self[j] = (self[j] & !mask)
265 | (((value[i] >> (start_ - start)) as $storage)
266 << (start_ & S_MASK)
267 & mask);
268 }
269 }
270 }
271 }
272 }
273 }
274 };
275}
276
277macro_rules! impl_bits_for_int_types {
278 (=> $($dst_ty: ident ($dst_u_ty: ident)),*) => {};
279 (
280 $src_ty: ident ($src_u_ty: ident)
281 $(, $other_src_ty: ident ($other_src_u_ty: ident))*
282 => $($dst_ty: ident ($dst_u_ty: ident)),*
283 ) => {
284 mod $src_ty {
285 use super::*;
286 $(
287 impl_bits_for_int_type!($src_ty ($src_u_ty), $dst_ty ($dst_u_ty));
288 )*
289 }
290 impl_bits_for_int_types!(
291 $($other_src_ty ($other_src_u_ty)),* => $($dst_ty ($dst_u_ty)),*
292 );
293 };
294}
295
296mod bits {
297 use super::*;
298 impl_bits_for_int_types!(
299 u8 (u8), u16 (u16), u32 (u32), u64 (u64), u128 (u128), usize (usize),
300 i8 (u8), i16 (u16), i32 (u32), i64 (u64), i128 (u128), isize (usize)
301 => u8 (u8), u16 (u16), u32 (u32), u64 (u64), u128 (u128), usize (usize),
302 i8 (u8), i16 (u16), i32 (u32), i64 (u64), i128 (u128), isize (usize)
303 );
304}
305
306macro_rules! impl_bit_for_arr_int_type {
307 ($t: ident) => {
308 mod $t {
309 use super::*;
310 const SHIFT: u32 = <$t>::BITS.trailing_zeros();
311 const MASK: usize = <$t>::BITS as usize - 1;
312
313 impl<const N: usize> Bit for [$t; N] {
314 #[inline]
315 fn bit<const BIT: usize>(&self) -> bool {
316 self[BIT >> SHIFT] & 1 << (BIT & MASK) != 0
317 }
318 }
319
320 impl<const N: usize> WithBit for [$t; N] {
321 #[inline]
322 fn with_bit<const BIT: usize>(mut self, value: bool) -> Self {
323 self.set_bit::<BIT>(value);
324 self
325 }
326 }
327
328 impl<const N: usize> SetBit for [$t; N] {
329 #[inline]
330 fn set_bit<const BIT: usize>(&mut self, value: bool) {
331 self[BIT >> SHIFT] =
332 (self[BIT >> SHIFT] & !(1 << (BIT & MASK))) | (value as $t) << BIT;
333 }
334 }
335
336 impl Bit for [$t] {
337 #[inline]
338 fn bit<const BIT: usize>(&self) -> bool {
339 self[BIT >> SHIFT] & 1 << (BIT & MASK) != 0
340 }
341 }
342
343 impl SetBit for [$t] {
344 #[inline]
345 fn set_bit<const BIT: usize>(&mut self, value: bool) {
346 self[BIT >> SHIFT] =
347 (self[BIT >> SHIFT] & !(1 << (BIT & MASK))) | (value as $t) << BIT;
348 }
349 }
350 }
351 };
352}
353
354macro_rules! impl_bit_for_arr_int_types {
355 ($($t: ident),*) => {
356 $(impl_bit_for_arr_int_type!($t);)*
357 };
358}
359
360mod bit {
361 use super::*;
362 impl_bit_for_arr_int_types!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
363}