pauli_tracker/boolean_vector/
bitvec_simd.rs

1/*!
2A [BooleanVector] implementation for a SIMD vector.
3
4Compare the documentation of [bitvec_simd](https://docs.rs/bitvec_simd/latest/bitvec_simd/index.html).
5*/
6
7use bitvec_simd::BitVec;
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11use super::BooleanVector;
12
13/// A newtype wrapper around
14/// [bitvec_simd::BitVec](https://docs.rs/bitvec_simd/latest/bitvec_simd/type.BitVec.html).
15#[derive(Debug, Clone, PartialEq)]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17pub struct SimdBitVec(pub BitVec);
18
19impl FromIterator<bool> for SimdBitVec {
20    fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
21        let iter = iter.into_iter();
22        let mut res = SimdBitVec::new();
23        for f in iter {
24            res.push(f);
25        }
26        res
27    }
28}
29
30impl Default for SimdBitVec {
31    fn default() -> Self {
32        Self::zeros(0)
33    }
34}
35
36/// An [Iterator] over [SimdBitVec]. Create with [IntoIterator].
37#[derive(Debug, Clone, Default, PartialEq)]
38pub struct Iter {
39    vec: SimdBitVec,
40    current: usize,
41}
42impl Iterator for Iter {
43    type Item = bool;
44    fn next(&mut self) -> Option<Self::Item> {
45        self.current += 1;
46        self.vec.0.get(self.current - 1)
47    }
48}
49
50/// An [Iterator] over &[SimdBitVec]. Create with [BooleanVector::iter_vals].
51#[derive(Debug, Clone, Copy, PartialEq)]
52pub struct IterFromRef<'l> {
53    vec: &'l SimdBitVec,
54    current: usize,
55}
56impl Iterator for IterFromRef<'_> {
57    type Item = bool;
58    fn next(&mut self) -> Option<Self::Item> {
59        self.current += 1;
60        self.vec.0.get(self.current - 1)
61    }
62}
63
64impl IntoIterator for SimdBitVec {
65    type Item = bool;
66
67    type IntoIter = Iter;
68
69    fn into_iter(self) -> Self::IntoIter {
70        Iter { vec: self, current: 0 }
71    }
72}
73
74impl BooleanVector for SimdBitVec {
75    type IterVals<'l> = IterFromRef<'l>;
76
77    fn new() -> Self {
78        Self::zeros(0)
79    }
80
81    fn zeros(len: usize) -> Self {
82        Self(BitVec::zeros(len))
83    }
84
85    fn set(&mut self, idx: usize, flag: bool) {
86        assert!(idx < self.len());
87        self.0.set(idx, flag);
88    }
89
90    fn xor_inplace(&mut self, rhs: &Self) {
91        self.0.xor_inplace(&rhs.0);
92    }
93
94    fn or_inplace(&mut self, rhs: &Self) {
95        self.0.or_inplace(&rhs.0);
96    }
97
98    fn resize(&mut self, len: usize, flag: bool) {
99        self.0.resize(len, flag);
100    }
101
102    fn push(&mut self, flag: bool) {
103        // let len = self.num_bools();
104        // println!("test: {}, {}, {}", flag, self.num_bools(), self.0.count_ones());
105        // // why do we have to do that, is this a bug in bitvec_simd? okay I don't get
106        // the set function, it also // breaks (in the roundtrip proptest) when we reach
107        // len=256 (which is bitvec_simds "bucket" size)
108        // if len == 0 {
109        //     if flag {
110        //         self.0 = BitVec::ones(1);
111        //     } else {
112        //         self.0 = BitVec::zeros(1);
113        //     }
114        // } else {
115        //     self.0.set(len, flag);
116        // }
117        self.0.resize(self.len() + 1, flag)
118    }
119
120    fn pop(&mut self) -> Option<bool> {
121        let last = self.len().checked_sub(1)?;
122        // last > self.0.len is not possible because of the above
123        let res = self.0.get_unchecked(last);
124        self.0.shrink_to(last);
125        Some(res)
126    }
127
128    fn len(&self) -> usize {
129        self.0.len()
130    }
131
132    fn get(&self, idx: usize) -> Option<bool> {
133        self.0.get(idx)
134    }
135
136    fn iter_vals(&self) -> Self::IterVals<'_> {
137        IterFromRef { vec: self, current: 0 }
138    }
139}