irox_tools/iterators/
zip.rs1use crate::array;
6use crate::buf::{Buffer, RoundBuffer};
7use crate::iterators::LendingIterator;
8
9pub struct Zipping<'a, const N: usize, T> {
12 iters: [core::slice::Iter<'a, T>; N],
13}
14
15macro_rules! impl_zipping {
16 (<$n: tt>) => {
17 impl<'a, T: Copy> Iterator for Zipping<'a, $n, T> {
18 type Item = [T;$n];
19
20 fn next(&mut self) -> Option<Self::Item> {
21 let mut i = self.iters.iter_mut();
22 let out : [T;$n] = array![
23 i.next()?.next().copied()?;$n
24 ];
25 Some(out)
26 }
27 }
28 impl<'a, T> From<[core::slice::Iter<'a, T>; $n]> for Zipping<'a, $n, T> {
29 fn from(iters: [core::slice::Iter<'a, T>; $n]) -> Self {
30 Self {
31 iters
32 }
33 }
34 }
35 };
36 ($($n:tt),+) => (
37 $(
38 impl_zipping!(<$n>);
39 )*
40 )
41 ;
42}
43impl_zipping!(2, 3, 4, 5, 6, 7, 8, 16, 32, 64);
44
45pub struct Windows<'a, const N: usize, T> {
46 iter: core::slice::Iter<'a, T>,
47 buf: RoundBuffer<N, T>,
48}
49impl<'a, const N: usize, T> Windows<'a, N, T> {
50 pub fn new(iter: core::slice::Iter<'a, T>) -> Self {
51 Self {
52 iter,
53 buf: RoundBuffer::new(),
54 }
55 }
56}
57
58macro_rules! impl_windows {
59 (<$n: tt>) => {
60 impl<'a, T: Copy> LendingIterator for Windows<'a, $n, T> where Self: 'a {
61 type Item<'b> = [&'b T; $n] where Self: 'b;
62
63 fn next_ref(&mut self) -> Option<Self::Item<'_>> {
64 if !self.buf.is_full() {
65 while !self.buf.is_full() {
66 self.buf.push(self.iter.next().copied()?).ok()?;
67 }
68 } else {
69 self.buf.pop_front()?;
70 self.buf.push(self.iter.next().copied()?).ok()?;
71 }
72 let mut iter = self.buf.iter();
73 let arr = array![iter.next()?;$n];
74 Some(arr)
75 }
76 }
77 };
78 ($($n:tt),+) => (
79 $(
80 impl_windows!(<$n>);
81 )*
82 )
83 ;
84}
85impl_windows!(2, 3, 4, 5, 6, 7, 8, 16, 32, 64);
86#[cfg(test)]
87mod tests {
88 use crate::hex;
89 use crate::iterators::{LendingIterator, Windows};
90
91 #[test]
92 pub fn testwindows() {
93 let a: [u8; 16] = hex!("000102030405060708090A0B0C0D0E0F");
94 let mut iter = Windows::<2, _>::new(a.iter());
95 assert_eq!(iter.next_ref(), Some([&0x00, &0x01]));
96 assert_eq!(iter.next_ref(), Some([&0x01, &0x02]));
97 assert_eq!(iter.next_ref(), Some([&0x02, &0x03]));
98 assert_eq!(iter.next_ref(), Some([&0x03, &0x04]));
99 assert_eq!(iter.next_ref(), Some([&0x04, &0x05]));
100 assert_eq!(iter.next_ref(), Some([&0x05, &0x06]));
101 assert_eq!(iter.next_ref(), Some([&0x06, &0x07]));
102 assert_eq!(iter.next_ref(), Some([&0x07, &0x08]));
103 assert_eq!(iter.next_ref(), Some([&0x08, &0x09]));
104 assert_eq!(iter.next_ref(), Some([&0x09, &0x0A]));
105 assert_eq!(iter.next_ref(), Some([&0x0A, &0x0B]));
106 assert_eq!(iter.next_ref(), Some([&0x0B, &0x0C]));
107 assert_eq!(iter.next_ref(), Some([&0x0C, &0x0D]));
108 assert_eq!(iter.next_ref(), Some([&0x0D, &0x0E]));
109 assert_eq!(iter.next_ref(), Some([&0x0E, &0x0F]));
110 }
111}