iterator: impl DoubleEndedIterator for adaptors
This commit is contained in:
parent
0d04aa78e5
commit
404de4f4ae
@ -773,6 +773,17 @@ impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for ChainIterator<A, T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, T: DoubleEndedIterator<A>, U: DoubleEndedIterator<A>> DoubleEndedIterator<A>
|
||||
for ChainIterator<A, T, U> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
match self.b.next_back() {
|
||||
Some(x) => Some(x),
|
||||
None => self.a.next_back()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which iterates two other iterators simultaneously
|
||||
// FIXME #6967: Dummy A & B parameters to get around type inference bug
|
||||
pub struct ZipIterator<A, T, B, U> {
|
||||
@ -828,6 +839,17 @@ impl<'self, A, B, T: Iterator<A>> Iterator<B> for MapIterator<'self, A, B, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
|
||||
for MapIterator<'self, A, B, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<B> {
|
||||
match self.iter.next_back() {
|
||||
Some(a) => Some((self.f)(a)),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which filters the elements of `iter` with `predicate`
|
||||
pub struct FilterIterator<'self, A, T> {
|
||||
priv iter: T,
|
||||
@ -854,6 +876,24 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for FilterIterator<'self, A, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
loop {
|
||||
match self.iter.next_back() {
|
||||
None => return None,
|
||||
Some(x) => {
|
||||
if (self.predicate)(&x) {
|
||||
return Some(x);
|
||||
} else {
|
||||
loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which uses `f` to both filter and map elements from `iter`
|
||||
pub struct FilterMapIterator<'self, A, B, T> {
|
||||
priv iter: T,
|
||||
@ -879,6 +919,24 @@ impl<'self, A, B, T: Iterator<A>> Iterator<B> for FilterMapIterator<'self, A, B,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
|
||||
for FilterMapIterator<'self, A, B, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<B> {
|
||||
loop {
|
||||
match self.iter.next_back() {
|
||||
None => return None,
|
||||
Some(x) => {
|
||||
match (self.f)(x) {
|
||||
Some(y) => return Some(y),
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which yields the current count and the element during iteration
|
||||
// FIXME #6967: Dummy A parameter to get around type inference bug
|
||||
pub struct EnumerateIterator<A, T> {
|
||||
@ -1135,6 +1193,20 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for PeekIterator<'self, A, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for PeekIterator<'self, A, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
let next = self.iter.next_back();
|
||||
|
||||
match next {
|
||||
Some(ref a) => (self.f)(a),
|
||||
None => ()
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which just modifies the contained state throughout iteration.
|
||||
pub struct UnfoldrIterator<'self, A, St> {
|
||||
priv f: &'self fn(&mut St) -> Option<A>,
|
||||
@ -1526,4 +1598,53 @@ mod tests {
|
||||
it.next();
|
||||
assert_eq!(it.invert().transform(|&x| x).collect::<~[int]>(), ~[16, 14, 12, 10, 8, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_map() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().transform(|&x| x * -1);
|
||||
assert_eq!(it.next(), Some(-1));
|
||||
assert_eq!(it.next(), Some(-2));
|
||||
assert_eq!(it.next_back(), Some(-6));
|
||||
assert_eq!(it.next_back(), Some(-5));
|
||||
assert_eq!(it.next(), Some(-3));
|
||||
assert_eq!(it.next_back(), Some(-4));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_filter() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().filter(|&x| *x & 1 == 0);
|
||||
assert_eq!(it.next_back().unwrap(), &6);
|
||||
assert_eq!(it.next_back().unwrap(), &4);
|
||||
assert_eq!(it.next().unwrap(), &2);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_filter_map() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
|
||||
assert_eq!(it.next_back().unwrap(), 12);
|
||||
assert_eq!(it.next_back().unwrap(), 8);
|
||||
assert_eq!(it.next().unwrap(), 4);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_chain() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let ys = ~[7, 9, 11];
|
||||
let mut it = xs.iter().chain_(ys.iter()).invert();
|
||||
assert_eq!(it.next().unwrap(), &11)
|
||||
assert_eq!(it.next().unwrap(), &9)
|
||||
assert_eq!(it.next_back().unwrap(), &1)
|
||||
assert_eq!(it.next_back().unwrap(), &2)
|
||||
assert_eq!(it.next_back().unwrap(), &3)
|
||||
assert_eq!(it.next_back().unwrap(), &4)
|
||||
assert_eq!(it.next_back().unwrap(), &5)
|
||||
assert_eq!(it.next_back().unwrap(), &7)
|
||||
assert_eq!(it.next_back(), None)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user