1use std::ops::BitOrAssign;
2
3#[derive(Debug, Clone, Copy, Default)]
4pub struct Bitmap {
6 low: u128,
7 high: u128,
8}
9
10impl Bitmap {
11 const HALF: u8 = 128;
12
13 pub fn new() -> Self {
14 Self::default()
15 }
16
17 fn mask(bit: u8) -> u128 {
18 1u128 << (bit & 127)
19 }
20
21 fn get_half(&self, bit: u8) -> u128 {
22 if bit < Self::HALF {
23 self.low
24 } else {
25 self.high
26 }
27 }
28
29 fn get_half_mut(&mut self, bit: u8) -> &mut u128 {
30 if bit < Self::HALF {
31 &mut self.low
32 } else {
33 &mut self.high
34 }
35 }
36
37 #[must_use]
38 #[inline(always)]
39 pub fn get(&self, bit: u8) -> bool {
40 let mask = Self::mask(bit);
41 let half = self.get_half(bit);
42 half & mask != 0
43 }
44
45 #[inline(always)]
46 pub fn set(&mut self, bit: u8) {
47 let mask = Self::mask(bit);
48 let half = self.get_half_mut(bit);
49 *half |= mask;
50 }
51
52 #[inline(always)]
53 pub fn invert(&mut self) {
54 self.low = !self.low;
55 self.high = !self.high;
56 }
57
58 #[inline(always)]
59 pub fn count_ones(&self) -> usize {
60 (self.low.count_ones() + self.high.count_ones()) as usize
61 }
62
63 pub fn iter(&self) -> Iter {
64 Iter(*self)
65 }
66}
67
68impl BitOrAssign for Bitmap {
70 fn bitor_assign(&mut self, rhs: Self) {
71 self.low |= rhs.low;
72 self.high |= rhs.high;
73 }
74}
75
76pub struct Iter(Bitmap);
77
78impl Iterator for Iter {
79 type Item = u8;
80
81 fn next(&mut self) -> Option<Self::Item> {
82 let (v, offset) = if self.0.low != 0 {
83 (&mut self.0.low, 0)
84 } else if self.0.high != 0 {
85 (&mut self.0.high, 128)
86 } else {
87 return None;
88 };
89
90 let t: u8 = v.trailing_zeros().try_into().unwrap();
92 *v &= !(1 << t);
93 Some(offset + t)
94 }
95}
96
97#[cfg(test)]
98mod test {
99 use super::Bitmap;
100
101 #[test]
102
103 fn test_bitmap() {
104 let mut bitmap = Bitmap::new();
105
106 let indexes = vec![0, 10, 17, 120, 127, 128, 129, 200, 255];
107 for i in &indexes {
108 bitmap.set(*i);
109 assert!(bitmap.get(*i));
110 }
111
112 for i in 0..=255 {
113 assert_eq!(bitmap.get(i), indexes.contains(&i));
114 }
115 assert_eq!(bitmap.count_ones(), indexes.len());
116
117 let value = bitmap.iter().collect::<Vec<_>>();
118 assert_eq!(value, indexes);
119
120 bitmap.invert();
121 for i in 0..=255 {
122 assert_eq!(bitmap.get(i), !indexes.contains(&i));
123 }
124 }
125
126 #[test]
127 fn test_bitmap_all() {
128 let mut bitmap = Bitmap::new();
129 assert_eq!(bitmap.iter().count(), 0);
130 bitmap.invert();
131 assert_eq!(bitmap.iter().count(), 256);
132 }
133
134 #[test]
135 fn test_bitmap_or_assign() {
136 let mut bitmap = Bitmap::new();
137 bitmap.set(10);
138 bitmap.set(30);
139
140 let mut bitmap2 = Bitmap::new();
141 bitmap2.set(20);
142 bitmap2 |= bitmap;
143
144 assert_eq!(vec![10, 20, 30], bitmap2.iter().collect::<Vec<_>>());
145 }
146}