sim_lib_discrete_comb/
bit_vector.rs1use crate::error::CombError;
7use num_bigint::BigUint;
8
9const MAX_WIDTH: usize = 127;
11
12#[derive(Debug, Clone)]
14pub struct BitVectorIter {
15 width: usize,
16 next: u128,
17 total: u128,
18}
19
20pub fn bit_vectors(width: usize) -> Result<BitVectorIter, CombError> {
23 if width > MAX_WIDTH {
24 return Err(CombError::LimitExceeded(format!(
25 "bit-vector width {width} exceeds {MAX_WIDTH}"
26 )));
27 }
28 let total = if width == MAX_WIDTH {
29 u128::MAX } else {
31 1u128 << width
32 };
33 Ok(BitVectorIter {
34 width,
35 next: 0,
36 total,
37 })
38}
39
40impl Iterator for BitVectorIter {
41 type Item = Vec<bool>;
42
43 fn next(&mut self) -> Option<Self::Item> {
44 if self.next >= self.total {
45 return None;
46 }
47 let r = self.next;
48 self.next += 1;
49 Some((0..self.width).map(|j| (r >> j) & 1 == 1).collect())
50 }
51}
52
53pub fn bit_vector_rank(bits: &[bool]) -> BigUint {
55 let mut rank = BigUint::from(0u32);
56 for (j, &b) in bits.iter().enumerate() {
57 if b {
58 rank.set_bit(j as u64, true);
59 }
60 }
61 rank
62}
63
64pub fn bit_vector_unrank(rank: &BigUint, width: usize) -> Vec<bool> {
66 (0..width).map(|j| rank.bit(j as u64)).collect()
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn iterates_all_in_order() {
75 let all: Vec<_> = bit_vectors(2).unwrap().collect();
76 assert_eq!(all.len(), 4);
77 assert_eq!(all[0], vec![false, false]);
78 assert_eq!(all[1], vec![true, false]); assert_eq!(all[3], vec![true, true]);
80 }
81
82 #[test]
83 fn rank_unrank_round_trip() {
84 for (i, bits) in bit_vectors(5).unwrap().enumerate() {
85 let r = bit_vector_rank(&bits);
86 assert_eq!(r, BigUint::from(i as u32));
87 assert_eq!(bit_vector_unrank(&r, 5), bits);
88 }
89 }
90
91 #[test]
92 fn width_limit_enforced() {
93 assert!(matches!(bit_vectors(200), Err(CombError::LimitExceeded(_))));
94 }
95}