1use core::iter;
2
3use crate::utils::{checked, min_and_1, saturating};
4#[allow(unused_imports)]
5use crate::AlternatingExt;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct AlternatingNoRemainder<I, J> {
12 i: I,
13 j: J,
14 last_i: bool,
15}
16
17impl<I, J> AlternatingNoRemainder<I, J>
18where
19 I: Iterator,
20 J: Iterator<Item = I::Item>,
21{
22 pub fn new(i: impl IntoIterator<IntoIter = I>, j: impl IntoIterator<IntoIter = J>) -> Self {
26 Self {
27 i: i.into_iter(),
28 j: j.into_iter(),
29 last_i: false,
30 }
31 }
32}
33
34impl<I, J> Iterator for AlternatingNoRemainder<I, J>
35where
36 I: Iterator,
37 J: Iterator<Item = I::Item>,
38{
39 type Item = I::Item;
40 fn next(&mut self) -> Option<Self::Item> {
41 if self.last_i {
42 if let Some(item) = self.j.next() {
43 self.last_i = false;
44 Some(item)
45 } else {
46 None
47 }
48 } else {
49 if let Some(item) = self.i.next() {
50 self.last_i = true;
51 Some(item)
52 } else {
53 None
54 }
55 }
56 }
57
58 fn size_hint(&self) -> (usize, Option<usize>) {
59 let (i_lower, i_upper) = self.i.size_hint();
60 let (j_lower, j_upper) = self.j.size_hint();
61
62 let lower = saturating(min_and_1(i_lower, j_lower, self.last_i));
68 let upper = match (i_upper, j_upper) {
69 (Some(i_upper), Some(j_upper)) => checked(min_and_1(i_upper, j_upper, self.last_i)),
70 (Some(i_upper), None) => checked((i_upper, self.last_i)),
71 (None, Some(j_upper)) => checked((j_upper, !self.last_i)),
72 (None, None) => None,
76 };
77 (lower, upper)
78 }
79}
80
81impl<I, J> iter::FusedIterator for AlternatingNoRemainder<I, J>
95where
96 I: iter::FusedIterator,
97 J: iter::FusedIterator<Item = I::Item>,
98{
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn is_fused() {
107 let a = 1..3;
108 let b = iter::repeat(0);
109
110 let mut iter = a.alternate_with_no_remainder(b);
111
112 assert_eq!(iter.next(), Some(1));
113 assert_eq!(iter.next(), Some(0));
114 assert_eq!(iter.next(), Some(2));
115 assert_eq!(iter.next(), Some(0));
116 assert_eq!(iter.next(), None);
117 assert_eq!(iter.next(), None);
118 assert_eq!(iter.next(), None);
119 }
120
121 #[test]
122 fn same_lengths() {
123 let a = [1, 2];
124 let b = [3, 4];
125
126 let mut iter = a.iter().alternate_with_no_remainder(b.iter());
127
128 assert_eq!(iter.next(), Some(&1));
129 assert_eq!(iter.next(), Some(&3));
130 assert_eq!(iter.next(), Some(&2));
131 assert_eq!(iter.next(), Some(&4));
132 assert_eq!(iter.next(), None);
133 }
134
135 #[test]
136 fn different_lengths_1more() {
137 let a = [1, 2];
138 let b = [3, 4, 5];
139
140 let mut iter = a.iter().alternate_with_no_remainder(b.iter());
141
142 assert_eq!(iter.next(), Some(&1));
143 assert_eq!(iter.next(), Some(&3));
144 assert_eq!(iter.next(), Some(&2));
145 assert_eq!(iter.next(), Some(&4));
146 assert_eq!(iter.next(), None);
147 }
148
149 #[test]
150 fn different_lengths_2more() {
151 let a = [1, 2];
152 let b = [3, 4, 5, 6];
153
154 let mut iter = a.iter().alternate_with_no_remainder(b.iter());
155
156 assert_eq!(iter.next(), Some(&1));
157 assert_eq!(iter.next(), Some(&3));
158 assert_eq!(iter.next(), Some(&2));
159 assert_eq!(iter.next(), Some(&4));
160 assert_eq!(iter.next(), None);
161 }
162
163 #[test]
164 fn empty_iterators() {
165 let a: [i32; 0] = [];
166 let b: [i32; 0] = [];
167
168 let mut iter = a.iter().alternate_with_no_remainder(b.iter());
169
170 assert_eq!(iter.next(), None);
171 }
172
173 #[test]
174 fn one_empty_iterator() {
175 let a = [1, 2, 3];
176 let b: [i32; 0] = [];
177
178 let mut iter = a.iter().alternate_with_no_remainder(b.iter());
179
180 assert_eq!(iter.next(), Some(&1));
181 assert_eq!(iter.next(), None);
182 }
183
184 #[test]
185 fn same_iterator() {
186 let a = [1, 2, 3];
187
188 let mut iter = a.iter().alternate_with_no_remainder(a.iter());
189
190 assert_eq!(iter.next(), Some(&1));
191 assert_eq!(iter.next(), Some(&1));
192 assert_eq!(iter.next(), Some(&2));
193 assert_eq!(iter.next(), Some(&2));
194 assert_eq!(iter.next(), Some(&3));
195 assert_eq!(iter.next(), Some(&3));
196 assert_eq!(iter.next(), None);
197 }
198
199 #[test]
200 fn size_hint_accurate() {
201 let a = [1, 2, 3];
202 let b = [4, 5];
203
204 assert_eq!(
205 a.iter().size_hint().1,
206 Some(a.iter().count()),
207 "Sanity check failed"
208 );
209 assert_eq!(
210 b.iter().size_hint().1,
211 Some(b.iter().count()),
212 "Sanity check failed"
213 );
214
215 let iter = a.iter().alternate_with_no_remainder(b.iter());
216
217 assert_eq!(iter.size_hint().1, Some(iter.count()));
218 }
219 #[test]
220 fn size_hint() {
221 let a = [1, 2, 3];
222 let b = [4, 5];
223
224 assert_eq!(a.iter().size_hint(), (3, Some(3)), "Sanity check failed");
225 assert_eq!(b.iter().size_hint(), (2, Some(2)), "Sanity check failed");
226
227 let iter = a.iter().alternate_with_no_remainder(b.iter());
228
229 assert_eq!(iter.size_hint(), (5, Some(5)));
230 assert_eq!(iter.count(), 5, "Inaccurate size hint");
231 }
232 #[test]
233 fn size_hint_unbounded_right() {
234 let a = [1, 2, 3];
235 let b = iter::repeat(&0);
236
237 assert_eq!(a.iter().size_hint(), (3, Some(3)), "Sanity check failed");
238 assert_eq!(b.size_hint(), (usize::MAX, None), "Sanity check failed");
239
240 let iter = a.iter().alternate_with_no_remainder(b);
241
242 assert_eq!(iter.size_hint(), (6, Some(6)));
243 assert_eq!(iter.count(), 6, "Inaccurate size hint");
244 }
245 #[test]
246 fn size_hint_unbounded_left() {
247 let a = iter::repeat(&0);
248 let b = [1, 2, 3];
249
250 assert_eq!(a.size_hint(), (usize::MAX, None), "Sanity check failed");
251 assert_eq!(b.iter().size_hint(), (3, Some(3)), "Sanity check failed");
252
253 let iter = a.alternate_with_no_remainder(b.iter());
254
255 assert_eq!(iter.size_hint(), (7, Some(7)));
256 assert_eq!(iter.count(), 7, "Inaccurate size hint");
257 }
258 #[test]
259 fn size_hint_bound_exceed_max() {
260 let a = 0..usize::MAX;
261 let b = 0..usize::MAX;
262
263 assert_eq!(
264 a.size_hint(),
265 (usize::MAX, Some(usize::MAX)),
266 "Sanity check failed"
267 );
268 assert_eq!(
269 b.size_hint(),
270 (usize::MAX, Some(usize::MAX)),
271 "Sanity check failed"
272 );
273
274 let iter = a.alternate_with_no_remainder(b);
275
276 assert_eq!(iter.size_hint(), (usize::MAX, None));
277 }
278 #[test]
279 fn size_hint_bound_half_max_left() {
280 let a = 0..usize::MAX / 2;
281 let b = 0..usize::MAX / 2 + 1;
282
283 assert_eq!(
284 a.size_hint(),
285 (usize::MAX / 2, Some(usize::MAX / 2)),
286 "Sanity check failed"
287 );
288 assert_eq!(
289 b.size_hint(),
290 (usize::MAX / 2 + 1, Some(usize::MAX / 2 + 1)),
291 "Sanity check failed"
292 );
293
294 let iter = a.alternate_with_no_remainder(b);
295
296 assert_eq!(iter.size_hint(), (usize::MAX - 1, Some(usize::MAX - 1)));
297 }
298 #[test]
299 fn size_hint_bound_half_max_right() {
300 let a = 0..usize::MAX / 2 + 1;
301 let b = 0..usize::MAX / 2;
302
303 assert_eq!(
304 a.size_hint(),
305 (usize::MAX / 2 + 1, Some(usize::MAX / 2 + 1)),
306 "Sanity check failed"
307 );
308 assert_eq!(
309 b.size_hint(),
310 (usize::MAX / 2, Some(usize::MAX / 2)),
311 "Sanity check failed"
312 );
313
314 let iter = a.alternate_with_no_remainder(b);
315
316 assert_eq!(iter.size_hint(), (usize::MAX, Some(usize::MAX)));
317 }
318 #[test]
319 fn size_hint_both_unbounded() {
320 let a = iter::repeat(0);
321 let b = iter::repeat(0);
322
323 assert_eq!(a.size_hint(), (usize::MAX, None), "Sanity check failed");
324 assert_eq!(b.size_hint(), (usize::MAX, None), "Sanity check failed");
325
326 let iter = a.alternate_with_no_remainder(b);
327
328 assert_eq!(iter.size_hint(), (usize::MAX, None));
329 }
330}