Coverage Report

Created: 2026-02-26 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}