Skip to main content

bv/
prims.rs

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}