simd_csv/select/
selection.rs1use std::iter::Copied;
2use std::ops::Index;
3use std::slice::Iter;
4
5type IndicesIter<'a> = Copied<Iter<'a, usize>>;
6
7pub 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}