algorithms_edu/data_structures/
bit.rs

1use num_traits::Unsigned;
2
3// pub struct BitArray<T: PrimInt> {
4//     inner: T,
5// }
6
7pub trait Bit: Unsigned {
8    fn set_bit(&mut self, pos: usize);
9    fn clear_bit(&mut self, pos: usize);
10    fn get_bit(&self, pos: usize) -> bool;
11    fn toggle_bit(&mut self, pos: usize);
12    /// Returns a number with the first n bits set to 1
13    fn set_all(&mut self, pos: usize);
14    fn is_power_of_two(&self) -> bool;
15}
16
17macro_rules! impl_bit {
18    ($type:ty) => {
19        impl Bit for $type {
20            fn set_bit(&mut self, pos: usize) {
21                *self |= (1 << pos);
22            }
23            fn clear_bit(&mut self, pos: usize) {
24                *self &= !(1 << pos);
25            }
26            fn get_bit(&self, pos: usize) -> bool {
27                (self >> pos) % 2 != 0
28            }
29            // Toggles the i'th bit from 0 -> 1 or 1 -> 0
30            fn toggle_bit(&mut self, pos: usize) {
31                *self ^= (1 << pos);
32            }
33            fn set_all(&mut self, pos: usize) {
34                *self = (1 << pos) - 1;
35            }
36            fn is_power_of_two(&self) -> bool {
37                *self > 0 && *self & (*self - 1) == 0
38            }
39        }
40    };
41}
42
43impl_bit!(u8);
44impl_bit!(u16);
45impl_bit!(u32);
46impl_bit!(u64);
47impl_bit!(u128);
48impl_bit!(usize);
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    #[test]
54    fn test_bit() {
55        let mut x = 0b10101010u8;
56        assert!(x.get_bit(1));
57        assert!(!x.get_bit(2));
58        x.set_bit(2);
59        assert!(x.get_bit(2));
60        x.clear_bit(2);
61        assert!(!x.get_bit(2));
62        x.toggle_bit(2);
63        assert!(x.get_bit(2));
64        x.set_all(5);
65        assert_eq!(x, 0b00011111);
66        assert!((x + 1).is_power_of_two());
67    }
68}