monistode_emulator/
tightly_packed_array.rs

1use std::{
2    marker::PhantomData,
3    ops::{AddAssign, ShlAssign},
4};
5
6use bitvec::vec::BitVec;
7use num_traits::Zero;
8
9pub struct TightlyPackedArray<T> {
10    data: BitVec,
11    byte_size: usize,
12    _phantom: PhantomData<T>,
13}
14
15impl<T> TightlyPackedArray<T>
16where
17    T: Zero + From<u8> + AddAssign + ShlAssign,
18{
19    pub fn new(data: BitVec, byte_size: usize) -> TightlyPackedArray<T> {
20        TightlyPackedArray {
21            data,
22            byte_size,
23            _phantom: PhantomData,
24        }
25    }
26
27    pub fn at(&self, index: usize) -> T {
28        // We find all the bytes that can contribute - the size of our T doesn't have
29        // to be a multiple of 8, so we have to be careful.
30        let start = index * self.byte_size;
31        let end = start + self.byte_size;
32        let mut value = T::zero();
33        for i in start..end {
34            value <<= T::from(1);
35            if self.data[i] {
36                value += T::from(1);
37            }
38        }
39        value
40    }
41}