1use 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) $(, $const:tt)?) => {
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> $($const)* Bits<$value> for [$storage; N] {
13 #[inline]
14 fn bits<const START: usize, const END: usize>(&self) -> $value {
15 if START >= END {
16 return 0;
17 }
18 let bits = if START >> S_SHIFT == (END - 1) >> S_SHIFT {
19 (self[START >> S_SHIFT] >> (START & S_MASK)) as $value
20 } else {
21 let mut bits: $value = 0;
22 let mut i = START >> S_SHIFT;
23 while i <= (END - 1) >> S_SHIFT {
24 let start = $crate::__private::max(START, i << S_SHIFT);
25 bits |= ((self[i] as $storage_u >> (start & S_MASK)) as $value)
26 << (start - START);
27 i += 1;
28 }
29 bits
30 };
31 let read_bits = END - START;
32 bits << (V_BITS - read_bits) >> (V_BITS - read_bits)
33 }
34 }
35
36 impl<const N: usize> $($const)* WithBits<$value> for [$storage; N] {
37 #[inline]
38 fn with_bits<const START: usize, const END: usize>(
39 mut self,
40 value: $value,
41 ) -> Self {
42 self.set_bits::<START, END>(value);
43 self
44 }
45 }
46
47 impl<const N: usize> $($const)* SetBits<$value> for [$storage; N] {
48 #[inline]
49 fn set_bits<const START: usize, const END: usize>(&mut self, value: $value) {
50 if START >= END {
51 return;
52 }
53 if START >> S_SHIFT == (END - 1) >> S_SHIFT {
54 let i = START >> S_SHIFT;
55 let written_bits = END - START;
56 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
57 << (START & S_MASK);
58 self[i] =
59 (self[i] & !mask) | ((value as $storage) << (START & S_MASK) & mask);
60 } else {
61 let mut i = START >> S_SHIFT;
62 while i <= (END - 1) >> S_SHIFT {
63 let start = $crate::__private::max(START, i << S_SHIFT);
64 let end = $crate::__private::min(END, (i + 1) << S_SHIFT);
65 let written_bits = end - start;
66 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
67 << (start & S_MASK);
68 self[i] = (self[i] & !mask)
69 | (((value >> (start - START)) as $storage) << (start & S_MASK)
70 & mask);
71 i += 1;
72 }
73 }
74 }
75 }
76
77 impl $($const)* Bits<$value> for [$storage] {
78 #[inline]
79 fn bits<const START: usize, const END: usize>(&self) -> $value {
80 if START >= END {
81 return 0;
82 }
83 let bits = if START >> S_SHIFT == (END - 1) >> S_SHIFT {
84 (self[START >> S_SHIFT] >> (START & S_MASK)) as $value
85 } else {
86 let mut bits: $value = 0;
87 let mut i = START >> S_SHIFT;
88 while i <= (END - 1) >> S_SHIFT {
89 let start = $crate::__private::max(START, i << S_SHIFT);
90 bits |= ((self[i] as $storage_u >> (start & S_MASK)) as $value)
91 << (start - START);
92 i += 1;
93 }
94 bits
95 };
96 let read_bits = END - START;
97 bits << (V_BITS - read_bits) >> (V_BITS - read_bits)
98 }
99 }
100
101 impl $($const)* SetBits<$value> for [$storage] {
102 #[inline]
103 fn set_bits<const START: usize, const END: usize>(&mut self, value: $value) {
104 if START >= END {
105 return;
106 }
107 if START >> S_SHIFT == (END - 1) >> S_SHIFT {
108 let i = START >> S_SHIFT;
109 let written_bits = END - START;
110 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
111 << (START & S_MASK);
112 self[i] =
113 (self[i] & !mask) | ((value as $storage) << (START & S_MASK) & mask);
114 } else {
115 let mut i = START >> S_SHIFT;
116 while i <= (END - 1) >> S_SHIFT {
117 let start = $crate::__private::max(START, i << S_SHIFT);
118 let end = $crate::__private::min(END, (i + 1) << S_SHIFT);
119 let written_bits = end - start;
120 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
121 << (start & S_MASK);
122 self[i] = (self[i] & !mask)
123 | (((value >> (start - START)) as $storage) << (start & S_MASK)
124 & mask);
125 i += 1;
126 }
127 }
128 }
129 }
130
131 impl<const M: usize> $($const)* Bits<[$value; M]> for $storage {
132 #[inline]
133 fn bits<const START: usize, const END: usize>(&self) -> [$value; M] {
134 if START >= END {
135 return [0; M];
136 }
137 let mut result = [0; M];
138 let mut i = 0;
139 while i <= (END - START - 1) >> V_SHIFT {
140 let start = START + (i << V_SHIFT);
141 let end = $crate::__private::min(END, start + V_BITS);
142 let read_bits = end - start;
143 result[i] = ((*self >> start) as $value) << (V_BITS - read_bits)
144 >> (V_BITS - read_bits);
145 i += 1;
146 }
147 result
148 }
149 }
150
151 impl<const M: usize> $($const)* WithBits<[$value; M]> for $storage {
152 #[inline]
153 fn with_bits<const START: usize, const END: usize>(
154 mut self,
155 value: [$value; M],
156 ) -> Self {
157 if START >= END {
158 return self;
159 }
160 let mut i = 0;
161 while i <= (END - START - 1) >> V_SHIFT {
162 let start = START + (i << V_SHIFT);
163 let end = $crate::__private::min(END, start + V_BITS);
164 let written_bits = end - start;
165 let mask =
166 ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1) << start;
167 self = (self & !mask) | ((value[i] as $storage) << start & mask);
168 i += 1;
169 }
170 self
171 }
172 }
173
174 impl<const M: usize> $($const)* SetBits<[$value; M]> for $storage {
175 #[inline]
176 fn set_bits<const START: usize, const END: usize>(&mut self, value: [$value; M]) {
177 *self = self.with_bits::<START, END>(value);
178 }
179 }
180
181 impl<const M: usize, const N: usize> $($const)* Bits<[$value; M]> for [$storage; N] {
182 #[inline]
183 fn bits<const START: usize, const END: usize>(&self) -> [$value; M] {
184 if START >= END {
185 return [0; M];
186 }
187 let mut result = [0; M];
188 let mut i = 0;
189 while i <= (END - START - 1) >> V_SHIFT {
190 let start = START + (i << V_SHIFT);
191 let end = $crate::__private::min(END, start + V_BITS);
192 let bits = if start >> S_SHIFT == (end - 1) >> S_SHIFT {
193 (self[start >> S_SHIFT] >> (start & S_MASK)) as $value
194 } else {
195 let mut bits: $value = 0;
196 let mut j = start >> S_SHIFT;
197 while j <= (end - 1) >> S_SHIFT {
198 let start_ = $crate::__private::max(start, j << S_SHIFT);
199 bits |= ((self[j] as $storage_u >> (start_ & S_MASK)) as $value)
200 << (start_ - start);
201 j += 1;
202 }
203 bits
204 };
205 let read_bits = end - start;
206 result[i] = bits << (V_BITS - read_bits) >> (V_BITS - read_bits);
207 i += 1;
208 }
209 result
210 }
211 }
212
213 impl<const M: usize, const N: usize> $($const)* WithBits<[$value; M]> for
214 [$storage; N]
215 {
216 #[inline]
217 fn with_bits<const START: usize, const END: usize>(
218 mut self,
219 value: [$value; M],
220 ) -> Self {
221 self.set_bits::<START, END>(value);
222 self
223 }
224 }
225
226 impl<const M: usize, const N: usize> $($const)* SetBits<[$value; M]> for [$storage; N] {
227 #[inline]
228 fn set_bits<const START: usize, const END: usize>(&mut self, value: [$value; M]) {
229 if START >= END {
230 return;
231 }
232 let mut i = 0;
233 while i <= (END - START - 1) >> V_SHIFT {
234 let start = START + (i << V_SHIFT);
235 let end = $crate::__private::min(END, start + V_BITS);
236 if start >> S_SHIFT == (end - 1) >> S_SHIFT {
237 let j = start >> S_SHIFT;
238 let written_bits = end - start;
239 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
240 << (start & S_MASK);
241 self[j] = (self[j] & !mask)
242 | ((value[i] as $storage) << (start & S_MASK) & mask);
243 } else {
244 let mut j = start >> S_SHIFT;
245 while j <= (end - 1) >> S_SHIFT {
246 let start_ = $crate::__private::max(start, j << S_SHIFT);
247 let end_ = $crate::__private::min(end, (j + 1) << S_SHIFT);
248 let written_bits = end_ - start_;
249 let mask = ((1 as $storage) << (written_bits - 1) << 1)
250 .wrapping_sub(1)
251 << (start_ & S_MASK);
252 self[j] = (self[j] & !mask)
253 | (((value[i] >> (start_ - start)) as $storage)
254 << (start_ & S_MASK)
255 & mask);
256 j += 1;
257 }
258 }
259 i += 1;
260 }
261 }
262 }
263
264 impl<const M: usize> $($const)* Bits<[$value; M]> for [$storage] {
265 #[inline]
266 fn bits<const START: usize, const END: usize>(&self) -> [$value; M] {
267 if START >= END {
268 return [0; M];
269 }
270 let mut result = [0; M];
271 let mut i = 0;
272 while i <= (END - START - 1) >> V_SHIFT {
273 let start = START + (i << V_SHIFT);
274 let end = $crate::__private::min(END, start + V_BITS);
275 let bits = if start >> S_SHIFT == (end - 1) >> S_SHIFT {
276 (self[start >> S_SHIFT] >> (start & S_MASK)) as $value
277 } else {
278 let mut bits: $value = 0;
279 let mut j = start >> S_SHIFT;
280 while j <= (end - 1) >> S_SHIFT {
281 let start_ = $crate::__private::max(start, j << S_SHIFT);
282 bits |= ((self[j] as $storage_u >> (start_ & S_MASK)) as $value)
283 << (start_ - start);
284 j += 1;
285 }
286 bits
287 };
288 let read_bits = end - start;
289 result[i] = bits << (V_BITS - read_bits) >> (V_BITS - read_bits);
290 i += 1;
291 }
292 result
293 }
294 }
295
296 impl<const M: usize> $($const)* SetBits<[$value; M]> for [$storage] {
297 #[inline]
298 fn set_bits<const START: usize, const END: usize>(&mut self, value: [$value; M]) {
299 if START >= END {
300 return;
301 }
302 let mut i = 0;
303 while i <= (END - START - 1) >> V_SHIFT {
304 let start = START + (i << V_SHIFT);
305 let end = $crate::__private::min(END, start + V_BITS);
306 if start >> S_SHIFT == (end - 1) >> S_SHIFT {
307 let j = start >> S_SHIFT;
308 let written_bits = end - start;
309 let mask = ((1 as $storage) << (written_bits - 1) << 1).wrapping_sub(1)
310 << (start & S_MASK);
311 self[j] = (self[j] & !mask)
312 | ((value[i] as $storage) << (start & S_MASK) & mask);
313 } else {
314 let mut j = start >> S_SHIFT;
315 while j <= (end - 1) >> S_SHIFT {
316 let start_ = $crate::__private::max(start, j << S_SHIFT);
317 let end_ = $crate::__private::min(end, (j + 1) << S_SHIFT);
318 let written_bits = end_ - start_;
319 let mask = ((1 as $storage) << (written_bits - 1) << 1)
320 .wrapping_sub(1)
321 << (start_ & S_MASK);
322 self[j] = (self[j] & !mask)
323 | (((value[i] >> (start_ - start)) as $storage)
324 << (start_ & S_MASK)
325 & mask);
326 j += 1;
327 }
328 }
329 i += 1;
330 }
331 }
332 }
333 }
334 };
335}
336
337macro_rules! impl_bits_for_int_types {
338 (const => $($dst_ty: ident ($dst_u_ty: ident)),*) => {};
339 (=> $($dst_ty: ident ($dst_u_ty: ident)),*) => {};
340 (
341 const $src_ty: ident ($src_u_ty: ident)
342 $(, $other_src_ty: ident ($other_src_u_ty: ident))*
343 => $($dst_ty: ident ($dst_u_ty: ident)),*
344 ) => {
345 mod $src_ty {
346 use super::*;
347 $(
348 impl_bits_for_int_type!($src_ty ($src_u_ty), $dst_ty ($dst_u_ty), const);
349 )*
350 }
351 impl_bits_for_int_types!(
352 const $($other_src_ty ($other_src_u_ty)),* => $($dst_ty ($dst_u_ty)),*
353 );
354 };
355 (
356 $src_ty: ident ($src_u_ty: ident)
357 $(, $other_src_ty: ident ($other_src_u_ty: ident))*
358 => $($dst_ty: ident ($dst_u_ty: ident)),*
359 ) => {
360 mod $src_ty {
361 use super::*;
362 $(
363 impl_bits_for_int_type!($src_ty ($src_u_ty), $dst_ty ($dst_u_ty));
364 )*
365 }
366 impl_bits_for_int_types!(
367 $($other_src_ty ($other_src_u_ty)),* => $($dst_ty ($dst_u_ty)),*
368 );
369 };
370}
371
372mod bits {
373 use super::*;
374 #[cfg(not(feature = "nightly"))]
375 impl_bits_for_int_types!(
376 u8 (u8), u16 (u16), u32 (u32), u64 (u64), u128 (u128), usize (usize),
377 i8 (u8), i16 (u16), i32 (u32), i64 (u64), i128 (u128), isize (usize)
378 => u8 (u8), u16 (u16), u32 (u32), u64 (u64), u128 (u128), usize (usize),
379 i8 (u8), i16 (u16), i32 (u32), i64 (u64), i128 (u128), isize (usize)
380 );
381 #[cfg(feature = "nightly")]
382 impl_bits_for_int_types!(
383 const
384 u8 (u8), u16 (u16), u32 (u32), u64 (u64), u128 (u128), usize (usize),
385 i8 (u8), i16 (u16), i32 (u32), i64 (u64), i128 (u128), isize (usize)
386 => u8 (u8), u16 (u16), u32 (u32), u64 (u64), u128 (u128), usize (usize),
387 i8 (u8), i16 (u16), i32 (u32), i64 (u64), i128 (u128), isize (usize)
388 );
389}
390
391macro_rules! impl_bit_for_arr_int_type {
392 ($t: ident $(, $const:tt)?) => {
393 mod $t {
394 use super::*;
395 const SHIFT: u32 = <$t>::BITS.trailing_zeros();
396 const MASK: usize = <$t>::BITS as usize - 1;
397
398 impl<const N: usize> $($const)* Bit for [$t; N] {
399 #[inline]
400 fn bit<const BIT: usize>(&self) -> bool {
401 self[BIT >> SHIFT] & 1 << (BIT & MASK) != 0
402 }
403 }
404
405 impl<const N: usize> $($const)* WithBit for [$t; N] {
406 #[inline]
407 fn with_bit<const BIT: usize>(mut self, value: bool) -> Self {
408 self.set_bit::<BIT>(value);
409 self
410 }
411 }
412
413 impl<const N: usize> $($const)* SetBit for [$t; N] {
414 #[inline]
415 fn set_bit<const BIT: usize>(&mut self, value: bool) {
416 self[BIT >> SHIFT] =
417 (self[BIT >> SHIFT] & !(1 << (BIT & MASK))) | (value as $t) << BIT;
418 }
419 }
420
421 impl $($const)* Bit for [$t] {
422 #[inline]
423 fn bit<const BIT: usize>(&self) -> bool {
424 self[BIT >> SHIFT] & 1 << (BIT & MASK) != 0
425 }
426 }
427
428 impl $($const)* SetBit for [$t] {
429 #[inline]
430 fn set_bit<const BIT: usize>(&mut self, value: bool) {
431 self[BIT >> SHIFT] =
432 (self[BIT >> SHIFT] & !(1 << (BIT & MASK))) | (value as $t) << BIT;
433 }
434 }
435 }
436 };
437}
438
439macro_rules! impl_bit_for_arr_int_types {
440 (const $($t: ident),*) => {
441 $(impl_bit_for_arr_int_type!($t, const);)*
442 };
443 ($($t: ident),*) => {
444 $(impl_bit_for_arr_int_type!($t);)*
445 };
446}
447
448mod bit {
449 use super::*;
450 #[cfg(not(feature = "nightly"))]
451 impl_bit_for_arr_int_types!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
452 #[cfg(feature = "nightly")]
453 impl_bit_for_arr_int_types!(
454 const
455 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
456 );
457}