1use std::ops::{ BitAnd, BitOr, Not };
2
3pub trait BitField: BitAnd<Output = Self> + BitOr<Output = Self> + Not<Output = Self> + Sized + Copy {
6 fn empty() -> Self;
9
10 fn set_bit(&mut self, n: usize, state: bool);
13
14 fn get_bit(&self, n: usize) -> bool;
17
18 fn n_bits() -> usize;
20}
21
22macro_rules! impl_bitfield {
24 ($t:ty, $bits:expr) => {
25 impl BitField for $t {
26 fn empty() -> Self { 0 }
27
28 fn set_bit(&mut self, n: usize, state: bool) {
29 if state {
30 *self |= (1 << n);
31 }else{
32 *self &= !(1 << n);
33 }
34 }
35
36 fn get_bit(&self, n: usize) -> bool {
37 *self & (1 << n) > 0
38 }
39
40 #[inline(always)]
41 fn n_bits() -> usize { $bits }
42 }
43 }
44}
45
46impl_bitfield!(u8, 8);
47impl_bitfield!(u16, 16);
48impl_bitfield!(u32, 32);
49impl_bitfield!(u64, 64);
50impl_bitfield!(u128, 128);
51
52#[cfg(test)]
53mod test {
54 use super::*;
55
56 #[test]
57 fn get_bits() {
58 assert_eq!(0b00101u32.get_bit(0), true);
59 assert_eq!(0b00101u32.get_bit(1), false);
60 assert_eq!(0b00101u32.get_bit(2), true);
61 assert_eq!(0b00101u32.get_bit(3), false);
62 }
63
64 #[test]
65 fn set_bits() {
66 let mut bits = 0b00000u32;
67 bits.set_bit(5, true);
68 assert_eq!(bits.get_bit(5), true);
69 bits.set_bit(5, false);
70 assert_eq!(bits.get_bit(5), false);
71 }
72}