mimalloc_rust_sys/
utils.rs1#[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}