Skip to main content

simd_csv/select/
selection.rs

1use std::iter::Copied;
2use std::ops::Index;
3use std::slice::Iter;
4
5type IndicesIter<'a> = Copied<Iter<'a, usize>>;
6
7/// A selection of column indices.
8pub struct Selection {
9    indices: Vec<usize>,
10    alignment: usize,
11}
12
13impl Selection {
14    pub(crate) fn new(indices: Vec<usize>, alignment: usize) -> Self {
15        debug_assert!(indices.iter().all(|i| *i < alignment));
16
17        Self { indices, alignment }
18    }
19
20    pub fn full(len: usize) -> Self {
21        Self::new((0..len).collect(), len)
22    }
23
24    pub fn without(i: usize, len: usize) -> Self {
25        Self::new((0..len).filter(|j| i != *j).collect(), len)
26    }
27
28    #[inline]
29    pub fn len(&self) -> usize {
30        self.indices.len()
31    }
32
33    #[inline]
34    pub fn is_empty(&self) -> bool {
35        self.indices.is_empty()
36    }
37
38    #[inline]
39    pub fn select<'a, 'b, T: 'b + ?Sized>(
40        &'a self,
41        row: &'b impl Index<usize, Output = T>,
42    ) -> impl Iterator<Item = &'b T>
43    where
44        'a: 'b,
45    {
46        self.indices.iter().map(|i| &row[*i])
47    }
48
49    #[inline]
50    pub fn iter(&self) -> IndicesIter<'_> {
51        self.indices.iter().copied()
52    }
53
54    #[inline]
55    pub fn indexed_mask(&self) -> Vec<Option<usize>> {
56        let mut mask = vec![None; self.alignment];
57
58        for (j, i) in self.iter().enumerate() {
59            if i < self.alignment {
60                mask[i] = Some(j);
61            }
62        }
63
64        mask
65    }
66
67    #[inline]
68    pub fn mask(&self) -> Vec<bool> {
69        let mut mask = vec![false; self.alignment];
70
71        for i in self {
72            if i < self.alignment {
73                mask[i] = true;
74            }
75        }
76
77        mask
78    }
79}
80
81impl<'a> IntoIterator for &'a Selection {
82    type Item = usize;
83    type IntoIter = IndicesIter<'a>;
84
85    #[inline]
86    fn into_iter(self) -> Self::IntoIter {
87        self.iter()
88    }
89}
90
91impl Index<usize> for Selection {
92    type Output = usize;
93
94    #[inline]
95    fn index(&self, index: usize) -> &Self::Output {
96        &self.indices[index]
97    }
98}