nostd_bv/
prims.rs

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}