intersect_iter/
tpl_intersect.rs

1use std::{cmp::Ordering, iter::Peekable};
2
3/// Intersect over Tuples where the first tuple item serves the order
4pub struct TupleIntersect<A, B, K, T>
5where
6    A: Iterator<Item = (K, T)>,
7    B: Iterator<Item = (K, T)>,
8{
9    a: Peekable<A>,
10    b: Peekable<B>,
11}
12
13impl<A, B, K, T> TupleIntersect<A, B, K, T>
14where
15    A: Iterator<Item = (K, T)>,
16    B: Iterator<Item = (K, T)>,
17{
18    #[inline]
19    pub fn new(a: A, b: B) -> Self {
20        Self {
21            a: a.peekable(),
22            b: b.peekable(),
23        }
24    }
25}
26
27impl<A, B, K, T> Iterator for TupleIntersect<A, B, K, T>
28where
29    A: Iterator<Item = (K, T)>,
30    B: Iterator<Item = (K, T)>,
31    K: Ord,
32{
33    type Item = (K, T, T);
34
35    #[inline]
36    fn next(&mut self) -> Option<Self::Item> {
37        loop {
38            let a_peek = self.a.peek()?;
39            let b_peek = self.b.peek()?;
40
41            match a_peek.0.cmp(&b_peek.0) {
42                Ordering::Less => {
43                    self.a.next()?;
44                }
45                Ordering::Greater => {
46                    self.b.next()?;
47                }
48                Ordering::Equal => {
49                    let (dim, value_a) = unsafe { self.a.next().unwrap_unchecked() };
50                    let (_, value_b) = unsafe { self.b.next().unwrap_unchecked() };
51                    return Some((dim, value_a, value_b));
52                }
53            }
54        }
55    }
56}