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