1#[derive(Debug, Clone)]
8pub struct SlidingO<T> {
9 pub(crate) data: Vec<T>,
10 pub(crate) window_size: usize,
11 pub(crate) step: usize,
12 pub(crate) pos: usize,
13}
14
15impl<T: Clone> Iterator for SlidingO<T> {
16 type Item = Vec<T>;
17
18 fn next(&mut self) -> Option<Self::Item> {
19 if self.pos + self.window_size > self.data.len() {
20 return None;
21 }
22 let window = self.data[self.pos..self.pos + self.window_size].to_vec();
23 self.pos += self.step;
24 Some(window)
25 }
26
27 fn size_hint(&self) -> (usize, Option<usize>) {
28 let remaining = if self.pos + self.window_size > self.data.len() {
29 0
30 } else {
31 (self.data.len() - self.pos - self.window_size) / self.step + 1
32 };
33 (remaining, Some(remaining))
34 }
35}
36
37impl<T: Clone> ExactSizeIterator for SlidingO<T> {}
38
39fn rotate_clone<T: Clone>(ring: &[T], i: usize) -> Vec<T> {
44 let n = ring.len();
45 if n == 0 {
46 return vec![];
47 }
48 let i = i % n;
49 let mut v = Vec::with_capacity(n);
50 v.extend_from_slice(&ring[i..]);
51 v.extend_from_slice(&ring[..i]);
52 v
53}
54
55fn reflect_at_zero<T: Clone>(ring: &[T]) -> Vec<T> {
56 if ring.is_empty() {
57 return vec![];
58 }
59 let mut v = Vec::with_capacity(ring.len());
61 v.extend_from_slice(&ring[1..]);
62 v.extend_from_slice(&ring[..1]);
63 v.reverse();
64 v
65}
66
67#[derive(Debug, Clone)]
77pub struct Rotations<'a, T> {
78 pub(crate) ring: &'a [T],
79 pub(crate) index: usize,
80 pub(crate) total: usize,
81}
82
83impl<T: Clone> Iterator for Rotations<'_, T> {
84 type Item = Vec<T>;
85
86 fn next(&mut self) -> Option<Self::Item> {
87 if self.index >= self.total {
88 return None;
89 }
90 let result = rotate_clone(self.ring, self.index);
91 self.index += 1;
92 Some(result)
93 }
94
95 fn size_hint(&self) -> (usize, Option<usize>) {
96 let r = self.total - self.index;
97 (r, Some(r))
98 }
99}
100
101impl<T: Clone> ExactSizeIterator for Rotations<'_, T> {}
102
103#[derive(Debug, Clone)]
114pub struct Reflections<'a, T> {
115 pub(crate) ring: &'a [T],
116 pub(crate) state: u8,
117}
118
119impl<T: Clone> Iterator for Reflections<'_, T> {
120 type Item = Vec<T>;
121
122 fn next(&mut self) -> Option<Self::Item> {
123 match self.state {
124 0 => {
125 self.state = if self.ring.is_empty() { 2 } else { 1 };
126 Some(self.ring.to_vec())
127 }
128 1 => {
129 self.state = 2;
130 Some(reflect_at_zero(self.ring))
131 }
132 _ => None,
133 }
134 }
135
136 fn size_hint(&self) -> (usize, Option<usize>) {
137 let r = match self.state {
138 0 => {
139 if self.ring.is_empty() {
140 1
141 } else {
142 2
143 }
144 }
145 1 => 1,
146 _ => 0,
147 };
148 (r, Some(r))
149 }
150}
151
152impl<T: Clone> ExactSizeIterator for Reflections<'_, T> {}
153
154#[derive(Debug, Clone)]
165pub struct Reversions<'a, T> {
166 pub(crate) ring: &'a [T],
167 pub(crate) state: u8,
168}
169
170impl<T: Clone> Iterator for Reversions<'_, T> {
171 type Item = Vec<T>;
172
173 fn next(&mut self) -> Option<Self::Item> {
174 match self.state {
175 0 => {
176 self.state = if self.ring.is_empty() { 2 } else { 1 };
177 Some(self.ring.to_vec())
178 }
179 1 => {
180 self.state = 2;
181 let mut v = self.ring.to_vec();
182 v.reverse();
183 Some(v)
184 }
185 _ => None,
186 }
187 }
188
189 fn size_hint(&self) -> (usize, Option<usize>) {
190 let r = match self.state {
191 0 => {
192 if self.ring.is_empty() {
193 1
194 } else {
195 2
196 }
197 }
198 1 => 1,
199 _ => 0,
200 };
201 (r, Some(r))
202 }
203}
204
205impl<T: Clone> ExactSizeIterator for Reversions<'_, T> {}
206
207#[derive(Debug, Clone)]
219pub struct RotationsAndReflections<'a, T> {
220 pub(crate) ring: &'a [T],
221 pub(crate) reflected: Vec<T>,
222 pub(crate) index: usize,
223 pub(crate) total: usize,
224}
225
226impl<T: Clone> Iterator for RotationsAndReflections<'_, T> {
227 type Item = Vec<T>;
228
229 fn next(&mut self) -> Option<Self::Item> {
230 if self.index >= self.total {
231 return None;
232 }
233 let n = self.ring.len();
234 if n == 0 {
235 self.index += 1;
237 return Some(vec![]);
238 }
239 let (source, rot) = if self.index < n {
240 (self.ring, self.index)
241 } else {
242 (self.reflected.as_slice(), self.index - n)
243 };
244 self.index += 1;
245 Some(rotate_clone(source, rot))
246 }
247
248 fn size_hint(&self) -> (usize, Option<usize>) {
249 let r = self.total - self.index;
250 (r, Some(r))
251 }
252}
253
254impl<T: Clone> ExactSizeIterator for RotationsAndReflections<'_, T> {}