/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bit_field-0.10.3/src/lib.rs
Line | Count | Source |
1 | | //! Provides the abstraction of a bit field, which allows for bit-level update and retrieval |
2 | | //! operations. |
3 | | |
4 | | #![no_std] |
5 | | |
6 | | #[cfg(test)] |
7 | | mod tests; |
8 | | |
9 | | use core::ops::{Bound, Range, RangeBounds}; |
10 | | |
11 | | /// A generic trait which provides methods for extracting and setting specific bits or ranges of |
12 | | /// bits. |
13 | | pub trait BitField { |
14 | | /// The number of bits in this bit field. |
15 | | /// |
16 | | /// ```rust |
17 | | /// use bit_field::BitField; |
18 | | /// |
19 | | /// assert_eq!(u32::BIT_LENGTH, 32); |
20 | | /// assert_eq!(u64::BIT_LENGTH, 64); |
21 | | /// ``` |
22 | | const BIT_LENGTH: usize; |
23 | | |
24 | | /// Obtains the bit at the index `bit`; note that index 0 is the least significant bit, while |
25 | | /// index `length() - 1` is the most significant bit. |
26 | | /// |
27 | | /// ```rust |
28 | | /// use bit_field::BitField; |
29 | | /// |
30 | | /// let value: u32 = 0b110101; |
31 | | /// |
32 | | /// assert_eq!(value.get_bit(1), false); |
33 | | /// assert_eq!(value.get_bit(2), true); |
34 | | /// ``` |
35 | | /// |
36 | | /// ## Panics |
37 | | /// |
38 | | /// This method will panic if the bit index is out of bounds of the bit field. |
39 | | fn get_bit(&self, bit: usize) -> bool; |
40 | | |
41 | | /// Obtains the range of bits specified by `range`; note that index 0 is the least significant |
42 | | /// bit, while index `length() - 1` is the most significant bit. |
43 | | /// |
44 | | /// ```rust |
45 | | /// use bit_field::BitField; |
46 | | /// |
47 | | /// let value: u32 = 0b110101; |
48 | | /// |
49 | | /// assert_eq!(value.get_bits(0..3), 0b101); |
50 | | /// assert_eq!(value.get_bits(2..6), 0b1101); |
51 | | /// assert_eq!(value.get_bits(..), 0b110101); |
52 | | /// assert_eq!(value.get_bits(3..=3), value.get_bit(3) as u32); |
53 | | /// ``` |
54 | | /// |
55 | | /// ## Panics |
56 | | /// |
57 | | /// This method will panic if the start or end indexes of the range are out of bounds of the |
58 | | /// bit field. |
59 | | fn get_bits<T: RangeBounds<usize>>(&self, range: T) -> Self; |
60 | | |
61 | | /// Sets the bit at the index `bit` to the value `value` (where true means a value of '1' and |
62 | | /// false means a value of '0'); note that index 0 is the least significant bit, while index |
63 | | /// `length() - 1` is the most significant bit. |
64 | | /// |
65 | | /// ```rust |
66 | | /// use bit_field::BitField; |
67 | | /// |
68 | | /// let mut value = 0u32; |
69 | | /// |
70 | | /// value.set_bit(1, true); |
71 | | /// assert_eq!(value, 2u32); |
72 | | /// |
73 | | /// value.set_bit(3, true); |
74 | | /// assert_eq!(value, 10u32); |
75 | | /// |
76 | | /// value.set_bit(1, false); |
77 | | /// assert_eq!(value, 8u32); |
78 | | /// ``` |
79 | | /// |
80 | | /// ## Panics |
81 | | /// |
82 | | /// This method will panic if the bit index is out of the bounds of the bit field. |
83 | | fn set_bit(&mut self, bit: usize, value: bool) -> &mut Self; |
84 | | |
85 | | /// Sets the range of bits defined by the range `range` to the lower bits of `value`; to be |
86 | | /// specific, if the range is N bits long, the N lower bits of `value` will be used; if any of |
87 | | /// the other bits in `value` are set to 1, this function will panic. |
88 | | /// |
89 | | /// ```rust |
90 | | /// use bit_field::BitField; |
91 | | /// |
92 | | /// let mut value = 0u32; |
93 | | /// |
94 | | /// value.set_bits(0..2, 0b11); |
95 | | /// assert_eq!(value, 0b11); |
96 | | /// |
97 | | /// value.set_bits(2..=3, 0b11); |
98 | | /// assert_eq!(value, 0b1111); |
99 | | /// |
100 | | /// value.set_bits(..4, 0b1010); |
101 | | /// assert_eq!(value, 0b1010); |
102 | | /// ``` |
103 | | /// |
104 | | /// ## Panics |
105 | | /// |
106 | | /// This method will panic if the range is out of bounds of the bit field, or if there are `1`s |
107 | | /// not in the lower N bits of `value`. |
108 | | fn set_bits<T: RangeBounds<usize>>(&mut self, range: T, value: Self) -> &mut Self; |
109 | | } |
110 | | |
111 | | pub trait BitArray<T: BitField> { |
112 | | /// Returns the length, eg number of bits, in this bit array. |
113 | | /// |
114 | | /// ```rust |
115 | | /// use bit_field::BitArray; |
116 | | /// |
117 | | /// assert_eq!([0u8, 4u8, 8u8].bit_length(), 24); |
118 | | /// assert_eq!([0u32, 5u32].bit_length(), 64); |
119 | | /// ``` |
120 | | fn bit_length(&self) -> usize; |
121 | | |
122 | | /// Obtains the bit at the index `bit`; note that index 0 is the least significant bit, while |
123 | | /// index `length() - 1` is the most significant bit. |
124 | | /// |
125 | | /// ```rust |
126 | | /// use bit_field::BitArray; |
127 | | /// |
128 | | /// let value: [u32; 1] = [0b110101]; |
129 | | /// |
130 | | /// assert_eq!(value.get_bit(1), false); |
131 | | /// assert_eq!(value.get_bit(2), true); |
132 | | /// ``` |
133 | | /// |
134 | | /// ## Panics |
135 | | /// |
136 | | /// This method will panic if the bit index is out of bounds of the bit array. |
137 | | fn get_bit(&self, bit: usize) -> bool; |
138 | | |
139 | | /// Obtains the range of bits specified by `range`; note that index 0 is the least significant |
140 | | /// bit, while index `length() - 1` is the most significant bit. |
141 | | /// |
142 | | /// ```rust |
143 | | /// use bit_field::BitArray; |
144 | | /// |
145 | | /// let value: [u32; 2] = [0b110101, 0b11]; |
146 | | /// |
147 | | /// assert_eq!(value.get_bits(0..3), 0b101); |
148 | | /// assert_eq!(value.get_bits(..6), 0b110101); |
149 | | /// assert_eq!(value.get_bits(31..33), 0b10); |
150 | | /// assert_eq!(value.get_bits(5..=32), 0b1_0000_0000_0000_0000_0000_0000_001); |
151 | | /// assert_eq!(value.get_bits(34..), 0); |
152 | | /// ``` |
153 | | /// |
154 | | /// ## Panics |
155 | | /// |
156 | | /// This method will panic if the start or end indexes of the range are out of bounds of the |
157 | | /// bit array, or if the range can't be contained by the bit field T. |
158 | | fn get_bits<U: RangeBounds<usize>>(&self, range: U) -> T; |
159 | | |
160 | | /// Sets the bit at the index `bit` to the value `value` (where true means a value of '1' and |
161 | | /// false means a value of '0'); note that index 0 is the least significant bit, while index |
162 | | /// `length() - 1` is the most significant bit. |
163 | | /// |
164 | | /// ```rust |
165 | | /// use bit_field::BitArray; |
166 | | /// |
167 | | /// let mut value = [0u32]; |
168 | | /// |
169 | | /// value.set_bit(1, true); |
170 | | /// assert_eq!(value, [2u32]); |
171 | | /// |
172 | | /// value.set_bit(3, true); |
173 | | /// assert_eq!(value, [10u32]); |
174 | | /// |
175 | | /// value.set_bit(1, false); |
176 | | /// assert_eq!(value, [8u32]); |
177 | | /// ``` |
178 | | /// |
179 | | /// ## Panics |
180 | | /// |
181 | | /// This method will panic if the bit index is out of the bounds of the bit array. |
182 | | fn set_bit(&mut self, bit: usize, value: bool); |
183 | | |
184 | | /// Sets the range of bits defined by the range `range` to the lower bits of `value`; to be |
185 | | /// specific, if the range is N bits long, the N lower bits of `value` will be used; if any of |
186 | | /// the other bits in `value` are set to 1, this function will panic. |
187 | | /// |
188 | | /// ```rust |
189 | | /// use bit_field::BitArray; |
190 | | /// |
191 | | /// let mut value = [0u32, 0u32]; |
192 | | /// |
193 | | /// value.set_bits(0..2, 0b11); |
194 | | /// assert_eq!(value, [0b11, 0u32]); |
195 | | /// |
196 | | /// value.set_bits(31..35, 0b1010); |
197 | | /// assert_eq!(value, [0x0003, 0b101]); |
198 | | /// ``` |
199 | | /// |
200 | | /// ## Panics |
201 | | /// |
202 | | /// This method will panic if the range is out of bounds of the bit array, |
203 | | /// if the range can't be contained by the bit field T, or if there are `1`s |
204 | | /// not in the lower N bits of `value`. |
205 | | fn set_bits<U: RangeBounds<usize>>(&mut self, range: U, value: T); |
206 | | } |
207 | | |
208 | | /// An internal macro used for implementing BitField on the standard integral types. |
209 | | macro_rules! bitfield_numeric_impl { |
210 | | ($($t:ty)*) => ($( |
211 | | impl BitField for $t { |
212 | | const BIT_LENGTH: usize = ::core::mem::size_of::<Self>() as usize * 8; |
213 | | |
214 | | #[track_caller] |
215 | | #[inline] |
216 | 165k | fn get_bit(&self, bit: usize) -> bool { |
217 | 165k | assert!(bit < Self::BIT_LENGTH); |
218 | | |
219 | 165k | (*self & (1 << bit)) != 0 |
220 | 165k | } <u32 as bit_field::BitField>::get_bit Line | Count | Source | 216 | 31.4k | fn get_bit(&self, bit: usize) -> bool { | 217 | 31.4k | assert!(bit < Self::BIT_LENGTH); | 218 | | | 219 | 31.4k | (*self & (1 << bit)) != 0 | 220 | 31.4k | } |
<u32 as bit_field::BitField>::get_bit Line | Count | Source | 216 | 133k | fn get_bit(&self, bit: usize) -> bool { | 217 | 133k | assert!(bit < Self::BIT_LENGTH); | 218 | | | 219 | 133k | (*self & (1 << bit)) != 0 | 220 | 133k | } |
<u32 as bit_field::BitField>::get_bit Line | Count | Source | 216 | 408 | fn get_bit(&self, bit: usize) -> bool { | 217 | 408 | assert!(bit < Self::BIT_LENGTH); | 218 | | | 219 | 408 | (*self & (1 << bit)) != 0 | 220 | 408 | } |
|
221 | | |
222 | | #[track_caller] |
223 | | #[inline] |
224 | 267k | fn get_bits<T: RangeBounds<usize>>(&self, range: T) -> Self { |
225 | 267k | let range = to_regular_range(&range, Self::BIT_LENGTH); |
226 | | |
227 | 267k | assert!(range.start < Self::BIT_LENGTH); |
228 | 267k | assert!(range.end <= Self::BIT_LENGTH); |
229 | 267k | assert!(range.start <= range.end); |
230 | | |
231 | 267k | if range.start == range.end { |
232 | 0 | 0 |
233 | | } else { |
234 | | // shift away high bits |
235 | 267k | let bits = *self << (Self::BIT_LENGTH - range.end) >> (Self::BIT_LENGTH - range.end); |
236 | | |
237 | | // shift away low bits |
238 | 267k | bits >> range.start |
239 | | } |
240 | 267k | } |
241 | | |
242 | | #[track_caller] |
243 | | #[inline] |
244 | 408 | fn set_bit(&mut self, bit: usize, value: bool) -> &mut Self { |
245 | 408 | assert!(bit < Self::BIT_LENGTH); |
246 | | |
247 | 408 | if value { |
248 | 102 | *self |= 1 << bit; |
249 | 306 | } else { |
250 | 306 | *self &= !(1 << bit); |
251 | 306 | } |
252 | | |
253 | 408 | self |
254 | 408 | } Unexecuted instantiation: <u32 as bit_field::BitField>::set_bit Unexecuted instantiation: <u32 as bit_field::BitField>::set_bit <u32 as bit_field::BitField>::set_bit Line | Count | Source | 244 | 408 | fn set_bit(&mut self, bit: usize, value: bool) -> &mut Self { | 245 | 408 | assert!(bit < Self::BIT_LENGTH); | 246 | | | 247 | 408 | if value { | 248 | 102 | *self |= 1 << bit; | 249 | 306 | } else { | 250 | 306 | *self &= !(1 << bit); | 251 | 306 | } | 252 | | | 253 | 408 | self | 254 | 408 | } |
|
255 | | |
256 | | #[track_caller] |
257 | | #[inline] |
258 | 0 | fn set_bits<T: RangeBounds<usize>>(&mut self, range: T, value: Self) -> &mut Self { |
259 | 0 | let range = to_regular_range(&range, Self::BIT_LENGTH); |
260 | | |
261 | 0 | assert!(range.start < Self::BIT_LENGTH); |
262 | 0 | assert!(range.end <= Self::BIT_LENGTH); |
263 | 0 | assert!(range.start <= range.end); |
264 | 0 | assert!(range.start == range.end && value == 0 || |
265 | 0 | value << (Self::BIT_LENGTH - (range.end - range.start)) >> |
266 | 0 | (Self::BIT_LENGTH - (range.end - range.start)) == value, |
267 | | "value does not fit into bit range"); |
268 | 0 | if range.start != range.end { |
269 | 0 | let bitmask: Self = !(!0 << (Self::BIT_LENGTH - range.end) >> |
270 | 0 | (Self::BIT_LENGTH - range.end) >> |
271 | 0 | range.start << range.start); |
272 | 0 |
|
273 | 0 | // set bits |
274 | 0 | *self = (*self & bitmask) | (value << range.start); |
275 | 0 | } |
276 | 0 | self |
277 | 0 | } |
278 | | } |
279 | | )*) |
280 | | } |
281 | | |
282 | | bitfield_numeric_impl! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } |
283 | | |
284 | | impl<T: BitField> BitArray<T> for [T] { |
285 | | #[inline] |
286 | | fn bit_length(&self) -> usize { |
287 | | self.len() * T::BIT_LENGTH |
288 | | } |
289 | | |
290 | | #[track_caller] |
291 | | #[inline] |
292 | | fn get_bit(&self, bit: usize) -> bool { |
293 | | let slice_index = bit / T::BIT_LENGTH; |
294 | | let bit_index = bit % T::BIT_LENGTH; |
295 | | self[slice_index].get_bit(bit_index) |
296 | | } |
297 | | |
298 | | #[track_caller] |
299 | | #[inline] |
300 | | fn get_bits<U: RangeBounds<usize>>(&self, range: U) -> T { |
301 | | let range = to_regular_range(&range, self.bit_length()); |
302 | | |
303 | | assert!(range.len() <= T::BIT_LENGTH); |
304 | | |
305 | | let slice_start = range.start / T::BIT_LENGTH; |
306 | | let slice_end = range.end / T::BIT_LENGTH; |
307 | | let bit_start = range.start % T::BIT_LENGTH; |
308 | | let bit_end = range.end % T::BIT_LENGTH; |
309 | | let len = range.len(); |
310 | | |
311 | | assert!(slice_end - slice_start <= 1); |
312 | | |
313 | | if slice_start == slice_end { |
314 | | self[slice_start].get_bits(bit_start..bit_end) |
315 | | } else if bit_end == 0 { |
316 | | self[slice_start].get_bits(bit_start..T::BIT_LENGTH) |
317 | | } else { |
318 | | let mut ret = self[slice_start].get_bits(bit_start..T::BIT_LENGTH); |
319 | | ret.set_bits( |
320 | | (T::BIT_LENGTH - bit_start)..len, |
321 | | self[slice_end].get_bits(0..bit_end), |
322 | | ); |
323 | | ret |
324 | | } |
325 | | } |
326 | | |
327 | | #[track_caller] |
328 | | #[inline] |
329 | | fn set_bit(&mut self, bit: usize, value: bool) { |
330 | | let slice_index = bit / T::BIT_LENGTH; |
331 | | let bit_index = bit % T::BIT_LENGTH; |
332 | | self[slice_index].set_bit(bit_index, value); |
333 | | } |
334 | | |
335 | | #[track_caller] |
336 | | #[inline] |
337 | | fn set_bits<U: RangeBounds<usize>>(&mut self, range: U, value: T) { |
338 | | let range = to_regular_range(&range, self.bit_length()); |
339 | | |
340 | | assert!(range.len() <= T::BIT_LENGTH); |
341 | | |
342 | | let slice_start = range.start / T::BIT_LENGTH; |
343 | | let slice_end = range.end / T::BIT_LENGTH; |
344 | | let bit_start = range.start % T::BIT_LENGTH; |
345 | | let bit_end = range.end % T::BIT_LENGTH; |
346 | | |
347 | | assert!(slice_end - slice_start <= 1); |
348 | | |
349 | | if slice_start == slice_end { |
350 | | self[slice_start].set_bits(bit_start..bit_end, value); |
351 | | } else if bit_end == 0 { |
352 | | self[slice_start].set_bits(bit_start..T::BIT_LENGTH, value); |
353 | | } else { |
354 | | self[slice_start].set_bits( |
355 | | bit_start..T::BIT_LENGTH, |
356 | | value.get_bits(0..T::BIT_LENGTH - bit_start), |
357 | | ); |
358 | | self[slice_end].set_bits( |
359 | | 0..bit_end, |
360 | | value.get_bits(T::BIT_LENGTH - bit_start..T::BIT_LENGTH), |
361 | | ); |
362 | | } |
363 | | } |
364 | | } |
365 | | |
366 | | #[inline] |
367 | 267k | fn to_regular_range<T: RangeBounds<usize>>(generic_rage: &T, bit_length: usize) -> Range<usize> { |
368 | 267k | let start = match generic_rage.start_bound() { |
369 | 0 | Bound::Excluded(&value) => value + 1, |
370 | 267k | Bound::Included(&value) => value, |
371 | 0 | Bound::Unbounded => 0, |
372 | | }; |
373 | 267k | let end = match generic_rage.end_bound() { |
374 | 267k | Bound::Excluded(&value) => value, |
375 | 0 | Bound::Included(&value) => value + 1, |
376 | 0 | Bound::Unbounded => bit_length, |
377 | | }; |
378 | | |
379 | 267k | start..end |
380 | 267k | } |