1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
pub struct LookAhead<const C: usize, T, U>
where
U: Iterator<Item=T> + Sized
{
iter: U,
data: [Option<T>;C],
cur: usize,
fill: usize,
}
impl<const C: usize, T, U> LookAhead<C,T,U>
where
U: Iterator<Item=T> + Sized
{
pub fn new(iter: U) -> Self {
Self {
iter,
data: [const {None};C],
cur: 0,
fill: 0,
}
}
pub fn peek(&mut self, offset: usize) -> Option<&T> {
assert!(offset<C);
self.fill_to( offset );
self.data[(self.cur+offset)%C].as_ref()
}
fn fill_to(&mut self, qty: usize) {
for i in self.fill..=qty {
if let Some(x) = self.iter.next() {
self.data[(self.cur+i)%C].replace( x );
self.fill += 1;
}
}
}
}
impl<const C: usize, T, U> std::iter::Iterator for LookAhead<C,T,U>
where
U: Iterator<Item=T> + Sized
{
type Item=T;
fn next(&mut self) -> Option<T> {
if self.fill == 0 {
self.iter.next()
} else {
let old = self.cur;
self.cur = (self.cur+1)%C;
self.fill -= 1;
self.data[old].take()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic() {
let data = [1, 2, 3, 4, 5, 6, 7, 8];
let mut i = LookAhead::<3,_,_>::new(data.iter());
assert_eq!(i.next(), Some(&1));
assert_eq!(i.peek(1), Some(&&3));
assert_eq!(i.peek(0), Some(&&2));
assert_eq!(i.next(), Some(&2));
assert_eq!(i.peek(0), Some(&&3));
assert_eq!(i.next(), Some(&3));
assert_eq!(i.next(), Some(&4));
assert_eq!(i.next(), Some(&5));
assert_eq!(i.peek(0), Some(&&6));
assert_eq!(i.peek(1), Some(&&7));
assert_eq!(i.peek(2), Some(&&8));
assert_eq!(i.next(), Some(&6));
assert_eq!(i.peek(2), None);
assert_eq!(i.next(), Some(&7));
assert_eq!(i.peek(2), None);
assert_eq!(i.next(), Some(&8));
assert_eq!(i.next(), None);
}
}
|