mimalloc_rust_sys/
utils.rs

1#[repr(C)]
2#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
3pub struct BitField<Storage> {
4    storage: Storage,
5}
6impl<Storage> BitField<Storage> {
7    #[inline]
8    pub const fn new(storage: Storage) -> Self {
9        Self { storage }
10    }
11}
12impl<Storage> BitField<Storage>
13where
14    Storage: AsRef<[u8]> + AsMut<[u8]>,
15{
16    #[inline]
17    pub fn get_bit(&self, index: usize) -> bool {
18        debug_assert!(index / 8 < self.storage.as_ref().len());
19        let byte_index = index / 8;
20        let byte = self.storage.as_ref()[byte_index];
21        let bit_index = if cfg!(target_endian = "big") {
22            7 - (index % 8)
23        } else {
24            index % 8
25        };
26        let mask = 1 << bit_index;
27        byte & mask == mask
28    }
29    #[inline]
30    pub fn set_bit(&mut self, index: usize, val: bool) {
31        debug_assert!(index / 8 < self.storage.as_ref().len());
32        let byte_index = index / 8;
33        let byte = &mut self.storage.as_mut()[byte_index];
34        let bit_index = if cfg!(target_endian = "big") {
35            7 - (index % 8)
36        } else {
37            index % 8
38        };
39        let mask = 1 << bit_index;
40        if val {
41            *byte |= mask;
42        } else {
43            *byte &= !mask;
44        }
45    }
46    #[inline]
47    pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
48        debug_assert!(bit_width <= 64);
49        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
50        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
51        let mut val = 0;
52        for i in 0..(bit_width as usize) {
53            if self.get_bit(i + bit_offset) {
54                let index = if cfg!(target_endian = "big") {
55                    bit_width as usize - 1 - i
56                } else {
57                    i
58                };
59                val |= 1 << index;
60            }
61        }
62        val
63    }
64    #[inline]
65    pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
66        debug_assert!(bit_width <= 64);
67        debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
68        debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
69        for i in 0..(bit_width as usize) {
70            let mask = 1 << i;
71            let val_bit_is_set = val & mask == mask;
72            let index = if cfg!(target_endian = "big") {
73                bit_width as usize - 1 - i
74            } else {
75                i
76            };
77            self.set_bit(index + bit_offset, val_bit_is_set);
78        }
79    }
80}