use std::marker::PhantomData; use std::ops::Deref; pub trait RawIterator { type View; fn is_end(&self) -> bool; fn next(&mut self); fn as_view(&self) -> Self::View; fn release(&mut self); } pub struct CIterator where R: RawIterator, { pub first: bool, pub raw: R, } impl Drop for CIterator where R: RawIterator, { fn drop(&mut self) { self.raw.release(); } } pub struct Borrowed<'i, R> where R: 'i + RawIterator, { it: PhantomData<&'i CIterator>, val: R::View, } impl<'i, R> Deref for Borrowed<'i, R> where R: RawIterator, { type Target = R::View; fn deref(&self) -> &R::View { &self.val } } impl CIterator where R: RawIterator, { pub fn next(&mut self) -> Option> { if self.raw.is_end() { return None; } if !self.first { self.raw.next(); } self.first = false; // we don't want to observe the end marker if self.raw.is_end() { None } else { Some(Borrowed { it: PhantomData, val: self.raw.as_view(), }) } } pub fn map(self, f: F) -> CMap where F: FnMut(&R::View) -> B, { CMap { it: self, f } } pub fn filter_map(self, f: F) -> CFilterMap where F: FnMut(&R::View) -> Option, { CFilterMap { it: self, f } } pub fn any(mut self, mut f: F) -> bool where F: FnMut(&R::View) -> bool, { while let Some(view) = self.next() { if (f)(&view) { return true; } } false } pub fn all(mut self, mut f: F) -> bool where F: FnMut(&R::View) -> bool, { while let Some(view) = self.next() { if !(f)(&view) { return false; } } true } pub fn count(mut self) -> usize { // Not sure this is actually better than self.map(|_| ()).count() let mut count = 0; while !self.raw.is_end() { self.raw.next(); count += 1; } count } } #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct CMap where R: RawIterator, { it: CIterator, f: F, } impl Iterator for CMap where R: RawIterator, F: FnMut(&R::View) -> B, { type Item = B; fn next(&mut self) -> Option { match self.it.next() { Some(ref x) => Some((self.f)(x)), None => None, } } } #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct CFilterMap where R: RawIterator, { it: CIterator, f: F, } impl Iterator for CFilterMap where R: RawIterator, F: FnMut(&R::View) -> Option, { type Item = B; fn next(&mut self) -> Option { loop { match self.it.next() { Some(ref x) => { if let Some(y) = (self.f)(x) { return Some(y); } } None => return None, } } } }