1use crate::storage::BlockType;
2use crate::traits::*;
3
4macro_rules! impl_bits_prim {
5 ( $t:ident ) => {
6 impl Bits for $t {
7 type Block = $t;
8
9 #[inline]
10 fn bit_len(&self) -> u64 {
11 Self::nbits() as u64
12 }
13
14 #[inline]
15 fn block_len(&self) -> usize {
16 1
17 }
18
19 #[inline]
20 fn get_bit(&self, position: u64) -> bool {
21 assert!(position < self.bit_len(), "prim::get_bit: out of bounds");
22 BlockType::get_bit(*self, position as usize)
23 }
24
25 #[inline]
26 fn get_block(&self, position: usize) -> Self::Block {
27 assert!(position == 0, "prim::get_block: out of bounds");
28 *self
29 }
30
31 #[inline]
32 fn get_bits(&self, start: u64, count: usize) -> Self {
33 assert!(
34 start + count as u64 <= Self::nbits() as u64,
35 "prim::get_bits: out of bounds"
36 );
37 BlockType::get_bits(*self, start as usize, count)
38 }
39 }
40
41 impl BitsMut for $t {
42 #[inline]
43 fn set_bit(&mut self, position: u64, value: bool) {
44 assert!(position < self.bit_len(), "prim::set_bit: out of bounds");
45 *self = self.with_bit(position as usize, value);
46 }
47
48 #[inline]
49 fn set_block(&mut self, position: usize, value: Self::Block) {
50 assert!(position == 0, "prim::set_block: out of bounds");
51 *self = value;
52 }
53
54 #[inline]
55 fn set_bits(&mut self, start: u64, count: usize, value: Self::Block) {
56 assert!(
57 start + count as u64 <= Self::nbits() as u64,
58 "prim::set_bits: out of bounds"
59 );
60 *self = self.with_bits(start as usize, count, value);
61 }
62 }
63 };
64}
65
66impl_bits_prim!(u8);
67impl_bits_prim!(u16);
68impl_bits_prim!(u32);
69impl_bits_prim!(u64);
70impl_bits_prim!(u128);
71impl_bits_prim!(usize);
72
73#[cfg(test)]
74mod test {
75 use super::*;
76 #[test]
77 fn bit_len() {
78 assert_eq!(30u8.bit_len(), 8);
79 assert_eq!(30u16.bit_len(), 16);
80 assert_eq!(30u32.bit_len(), 32);
81 assert_eq!(30u64.bit_len(), 64);
82 }
83
84 #[test]
85 fn block_len() {
86 assert_eq!(30u8.block_len(), 1);
87 assert_eq!(30u16.block_len(), 1);
88 assert_eq!(30u32.block_len(), 1);
89 assert_eq!(30u64.block_len(), 1);
90 }
91
92 #[test]
93 fn get_bit() {
94 assert!(0b01010101u8.get_bit(0));
95 assert!(!0b01010101u8.get_bit(1));
96 assert!(0b01010101u8.get_bit(2));
97 assert!(!0b01010101u8.get_bit(3));
98 }
99
100 quickcheck! {
101 fn prop_get_block_u8(value: u8) -> bool {
102 value.get_block(0) == value
103 }
104
105 fn prop_get_block_u32(value: u32) -> bool {
106 value.get_block(0) == value
107 }
108 }
109
110 #[test]
111 fn get_bits() {
112 assert_eq!(0b01010101u8.get_bits(1, 4), 0b00001010);
113 assert_eq!(0b01010101u8.get_bits(2, 4), 0b00000101);
114 }
115
116 #[test]
117 fn set_bit() {
118 let mut x = 0b01010101u8;
119
120 x.set_bit(0, false);
121 assert_eq!(x, 0b01010100);
122
123 x.set_bit(1, true);
124 assert_eq!(x, 0b01010110);
125
126 x.set_block(0, 0b00000000);
127 assert_eq!(x, 0b00000000);
128
129 x.set_bits(2, 4, 0b00001111);
130 assert_eq!(x, 0b00111100);
131 }
132
133 #[test]
134 fn u128_feature() {
135 assert_eq!(30u128.block_len(), 1);
136 }
137}