Skip to content

Instantly share code, notes, and snippets.

@SimonSapin
Created August 8, 2013 18:31
Show Gist options
  • Save SimonSapin/6187341 to your computer and use it in GitHub Desktop.
Save SimonSapin/6187341 to your computer and use it in GitHub Desktop.
Add a .peekable() to iterators. It returns a new iterators that has an additional .peek() function returning a &ref to the next item.
trait Peekable<I, T> {
fn peekable(self) -> PeekingIterator<I, T>;
}
impl<I: Iterator<T>, T> Peekable<I, T> for I {
fn peekable(self) -> PeekingIterator<I, T> {
PeekingIterator{ iter: self, peeked: None }
}
}
struct PeekingIterator<I, T> {
iter: I,
peeked: Option<T>,
}
impl<I: Iterator<T>, T> Iterator<T> for PeekingIterator<I, T> {
fn next(&mut self) -> Option<T> {
if self.peeked.is_some() { self.peeked.take() }
else { self.iter.next() }
}
}
impl<'self, I: Iterator<T>, T> PeekingIterator<I, T> {
fn peek(&'self mut self) -> Option<&'self T> {
match self.peeked {
Some(ref value) => Some(value),
None => {
self.peeked = self.iter.next();
match self.peeked {
Some(ref value) => Some(value),
None => None,
}
},
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment