tag_vec/
bit_field.rs

1use std::ops::{ BitAnd, BitOr, Not };
2
3/// A trait for a type that can
4/// work as a bitfield.
5pub trait BitField: BitAnd<Output = Self> + BitOr<Output = Self> + Not<Output = Self> + Sized + Copy {
6	/// Creates a bitfield with no bits
7	/// set
8	fn empty() -> Self;
9
10	/// Sets a bit. Assumes that n is less than
11	/// n_bits
12	fn set_bit(&mut self, n: usize, state: bool);
13
14	/// Gets a bit. Assumes that n is less than
15	/// n_bits
16	fn get_bit(&self, n: usize) -> bool;
17
18	/// Returns the number of bits.
19	fn n_bits() -> usize;
20}
21
22/// Implements the BitField trait for a numeric type
23macro_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}