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
use std::cmp::Ordering; use super::{SortOrder, IsSorted}; pub struct Intersection<I, J> where I: Iterator + IsSorted, J: Iterator + IsSorted { i: I, j: J, a: Option<I::Item>, b: Option<J::Item>, } impl<I, J> IsSorted for Intersection<I, J> where I: Iterator + IsSorted, I::Ordering: SortOrder<I::Item>, J: Iterator<Item = I::Item> + IsSorted<Ordering = I::Ordering> { type Ordering = I::Ordering; } impl<I, J> Iterator for Intersection<I, J> where I: Iterator + IsSorted, I::Item: Ord, I::Ordering: SortOrder<I::Item>, J: Iterator<Item = I::Item> + IsSorted<Ordering = I::Ordering> { type Item = I::Item; fn next(&mut self) -> Option<Self::Item> { loop { let a = self.a.take().or_else(|| self.i.next()); let b = self.b.take().or_else(|| self.j.next()); match (a, b) { (Some(a), Some(b)) => { match I::Ordering::cmp(&a, &b) { Ordering::Equal => return Some(a), Ordering::Less => self.b = Some(b), Ordering::Greater => self.a = Some(a), } } _ => return None, } } } } pub trait IntersectionExt where Self: Sized + Iterator + IsSorted { fn intersection<J>(self, J) -> Intersection<Self, J> where J: Iterator<Item = Self::Item> + IsSorted<Ordering = Self::Ordering>; } impl<I> IntersectionExt for I where I: Sized + Iterator + IsSorted { fn intersection<J>(self, j: J) -> Intersection<Self, J> where J: Iterator<Item = Self::Item> + IsSorted<Ordering = Self::Ordering> { Intersection { i: self, j, a: None, b: None, } } }