azul_glium/utils/
bitsfield.rs

1const NUM_DWORDS: usize = 8;
2
3/// 64-bits bitsfield
4pub struct Bitsfield {
5    data: [u32; NUM_DWORDS],
6}
7
8impl Bitsfield {
9    #[inline]
10    pub fn new() -> Bitsfield {
11        Bitsfield {
12            data: [0xffffffff; NUM_DWORDS],
13        }
14    }
15
16    #[inline]
17    pub fn set_used(&mut self, mut bit: u16) {
18        let mut offset = 0;
19
20        loop {
21            if offset >= NUM_DWORDS {
22                unimplemented!();
23            }
24
25            if bit < 32 {
26                let mask: u32 = 1 << bit;
27                let mask = !mask;
28                self.data[offset] &= mask;
29                return;
30            }
31
32            bit -= 32;
33            offset += 1;
34        }
35    }
36
37    #[inline]
38    pub fn set_unused(&mut self, mut bit: u16) {
39        let mut offset = 0;
40
41        loop {
42            if offset >= NUM_DWORDS {
43                unimplemented!();
44            }
45
46            if bit < 32 {
47                let mask: u32 = 1 << bit;
48                self.data[offset] |= mask;
49                return;
50            }
51
52            bit -= 32;
53            offset += 1;
54        }
55    }
56
57    #[inline]
58    pub fn is_used(&self, mut bit: u16) -> bool {
59        let mut offset = 0;
60
61        loop {
62            if offset >= NUM_DWORDS {
63                unimplemented!();
64            }
65
66            if bit < 32 {
67                let mask: u32 = 1 << bit;
68                return self.data[offset] & mask == 0;
69            }
70
71            bit -= 32;
72            offset += 1;
73        }
74    }
75
76    #[inline]
77    pub fn get_unused(&self) -> Option<u16> {
78        let mut offset = 0;
79
80        loop {
81            if offset >= NUM_DWORDS {
82                return None;
83            }
84
85            let v = self.data[offset].trailing_zeros() as u16;
86            if v < 32 {
87                return Some(v + offset as u16 * 32);
88            }
89
90            offset += 1;
91        }
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use super::Bitsfield;
98
99    #[test]
100    fn get_unused() {
101        let mut bitsfield = Bitsfield::new();
102        bitsfield.set_used(0);
103        bitsfield.set_used(1);
104        assert_eq!(bitsfield.get_unused(), Some(2))
105    }
106
107    #[test]
108    fn get_unused2() {
109        let mut bitsfield = Bitsfield::new();
110        for i in 0 .. 34 {
111            bitsfield.set_used(i);
112        }
113        assert_eq!(bitsfield.get_unused(), Some(34))
114    }
115
116    #[test]
117    fn is_used() {
118        let mut bitsfield = Bitsfield::new();
119        bitsfield.set_used(5);
120        bitsfield.set_used(6);
121        bitsfield.set_used(37);
122        assert!(!bitsfield.is_used(4));
123        assert!(bitsfield.is_used(5));
124        assert!(bitsfield.is_used(6));
125        assert!(!bitsfield.is_used(7));
126        assert!(!bitsfield.is_used(36));
127        assert!(bitsfield.is_used(37));
128        assert!(!bitsfield.is_used(38));
129    }
130}