tokio/util/
bit.rs

1use std::fmt;
2
3#[derive(Clone, Copy, PartialEq)]
4pub(crate) struct Pack {
5    mask: usize,
6    shift: u32,
7}
8
9impl Pack {
10    /// Value is packed in the `width` least-significant bits.
11    pub(crate) const fn least_significant(width: u32) -> Pack {
12        let mask = mask_for(width);
13
14        Pack { mask, shift: 0 }
15    }
16
17    /// Value is packed in the `width` more-significant bits.
18    pub(crate) const fn then(&self, width: u32) -> Pack {
19        let shift = usize::BITS - self.mask.leading_zeros();
20        let mask = mask_for(width) << shift;
21
22        Pack { mask, shift }
23    }
24
25    /// Width, in bits, dedicated to storing the value.
26    pub(crate) const fn width(&self) -> u32 {
27        usize::BITS - (self.mask >> self.shift).leading_zeros()
28    }
29
30    /// Max representable value.
31    pub(crate) const fn max_value(&self) -> usize {
32        (1 << self.width()) - 1
33    }
34
35    pub(crate) fn pack(&self, value: usize, base: usize) -> usize {
36        assert!(value <= self.max_value());
37        (base & !self.mask) | (value << self.shift)
38    }
39
40    pub(crate) fn unpack(&self, src: usize) -> usize {
41        unpack(src, self.mask, self.shift)
42    }
43}
44
45impl fmt::Debug for Pack {
46    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
47        write!(
48            fmt,
49            "Pack {{ mask: {:b}, shift: {} }}",
50            self.mask, self.shift
51        )
52    }
53}
54
55/// Returns a `usize` with the right-most `n` bits set.
56pub(crate) const fn mask_for(n: u32) -> usize {
57    let shift = 1usize.wrapping_shl(n - 1);
58    shift | (shift - 1)
59}
60
61/// Unpacks a value using a mask & shift.
62pub(crate) const fn unpack(src: usize, mask: usize, shift: u32) -> usize {
63    (src & mask) >> shift
64}