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
use std::cmp::Ordering; use super::{SortOrder, IsSorted}; pub struct Difference<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 Difference<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 Difference<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::Less => { self.b = Some(b); return Some(a); } Ordering::Greater => { self.a = Some(a); } Ordering::Equal => { self.b = Some(b); } } } (None, None) => return None, (a, None) => return a, (None, _) => (), } } } } pub trait DifferenceExt where Self: Sized + Iterator + IsSorted { fn difference<J>(self, j: J) -> Difference<Self, J> where J: Sized + Iterator<Item = Self::Item> + IsSorted<Ordering = Self::Ordering>; } impl<I> DifferenceExt for I where I: Sized + Iterator + IsSorted { fn difference<J>(self, j: J) -> Difference<Self, J> where J: Sized + Iterator<Item = Self::Item> + IsSorted<Ordering = Self::Ordering> { Difference { i: self, j, a: None, b: None, } } }