vortex_mask/
iter_bools.rs

1use std::iter;
2
3use crate::{AllOr, Mask};
4
5impl Mask {
6    /// Provides a closure with an iterator over the boolean values of the mask.
7    ///
8    /// This allows us to provide different implementations of the iterator based on the underlying
9    /// representation of the mask, while avoiding a heap allocation to return a boxed iterator.
10    ///
11    /// Note that bool iteration might not be the fastest way to achieve whatever is it you're
12    /// trying to do!
13    pub fn iter_bools<F, T>(&self, mut f: F) -> T
14    where
15        F: FnMut(&mut dyn Iterator<Item = bool>) -> T,
16    {
17        match self.boolean_buffer() {
18            AllOr::All => f(&mut iter::repeat_n(true, self.len())),
19            AllOr::None => f(&mut iter::repeat_n(false, self.len())),
20            AllOr::Some(buffer) => f(&mut buffer.iter()),
21        }
22    }
23}
24
25#[cfg(test)]
26mod test {
27    use itertools::Itertools;
28
29    use crate::Mask;
30
31    #[test]
32    fn iter_bools_all_true() {
33        let mask = Mask::new_true(10);
34        assert_eq!(mask.iter_bools(|iter| iter.collect_vec()), vec![true; 10]);
35    }
36
37    #[test]
38    fn iter_bools_all_false() {
39        let mask = Mask::new_false(10);
40        assert_eq!(mask.iter_bools(|iter| iter.collect_vec()), vec![false; 10]);
41    }
42
43    #[test]
44    fn iter_bools_indices() {
45        assert_eq!(
46            Mask::from_indices(5, vec![]).iter_bools(|iter| iter.collect_vec()),
47            vec![false; 5],
48        );
49        assert_eq!(
50            Mask::from_indices(5, vec![0, 1, 2, 3, 4]).iter_bools(|iter| iter.collect_vec()),
51            vec![true; 5],
52        );
53        assert_eq!(
54            Mask::from_indices(5, vec![0, 4]).iter_bools(|iter| iter.collect_vec()),
55            vec![true, false, false, false, true],
56        );
57        assert_eq!(
58            Mask::from_indices(5, vec![1, 2, 3]).iter_bools(|iter| iter.collect_vec()),
59            vec![false, true, true, true, false],
60        );
61    }
62
63    #[test]
64    fn iter_bools_slices() {
65        assert_eq!(
66            Mask::from_slices(5, vec![]).iter_bools(|iter| iter.collect_vec()),
67            vec![false; 5],
68        );
69        assert_eq!(
70            Mask::from_slices(5, vec![(0, 5)]).iter_bools(|iter| iter.collect_vec()),
71            vec![true; 5],
72        );
73        assert_eq!(
74            Mask::from_slices(5, vec![(0, 1), (4, 5)]).iter_bools(|iter| iter.collect_vec()),
75            vec![true, false, false, false, true],
76        );
77        assert_eq!(
78            Mask::from_slices(5, vec![(1, 4)]).iter_bools(|iter| iter.collect_vec()),
79            vec![false, true, true, true, false],
80        );
81    }
82}