1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::fmt::Binary;
pub trait FixedSizeBitSet : Default + Binary {
const NUM_BITS: usize;
fn get(&self, i: usize) -> bool;
fn insert(&mut self, i: usize);
fn remove(&mut self, i: usize);
}
macro_rules! impl_bit_set {
(
$type:ty, $num_bits:expr
) => {
impl FixedSizeBitSet for $type {
const NUM_BITS: usize = $num_bits;
#[inline(always)]
fn get(&self, i: usize) -> bool {
if i >= Self::NUM_BITS {
panic!("index is out of bounds: the len is {} but the index is {}",
Self::NUM_BITS, i);
}
(*self >> i & 0b_1) == 1
}
#[inline(always)]
fn insert(&mut self, i: usize) {
if i >= Self::NUM_BITS {
panic!("index is out of bounds: the len is {} but the index is {}",
Self::NUM_BITS, i);
}
*self |= 1 << i;
}
#[inline(always)]
fn remove(&mut self, i: usize) {
if i >= Self::NUM_BITS {
panic!("index is out of bounds: the len is {} but the index is {}",
Self::NUM_BITS, i);
}
*self &= !(1 << i);
}
}
};
}
impl_bit_set!(u8, 8);
impl_bit_set!(u16, 16);
impl_bit_set!(u32, 32);
impl_bit_set!(u64, 64);
#[cfg(test)]
mod tests {
mod bitset {
#[test]
fn test_bitset() {
use bitset::FixedSizeBitSet;
let mut bitset: u64 = 0;
bitset.insert(3);
bitset.insert(10);
bitset.insert(13);
bitset.insert(35);
for i in 0..32 {
match i {
3 | 10 | 13 | 35 => { assert!(bitset.get(i)); },
_ => { assert!(!bitset.get(i)); },
}
}
}
}
}