iterator: impl DoubleEndedIterator for adaptors
This commit is contained in:
@@ -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
|
/// An iterator which iterates two other iterators simultaneously
|
||||||
// FIXME #6967: Dummy A & B parameters to get around type inference bug
|
// FIXME #6967: Dummy A & B parameters to get around type inference bug
|
||||||
pub struct ZipIterator<A, T, B, U> {
|
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`
|
/// An iterator which filters the elements of `iter` with `predicate`
|
||||||
pub struct FilterIterator<'self, A, T> {
|
pub struct FilterIterator<'self, A, T> {
|
||||||
priv iter: 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`
|
/// An iterator which uses `f` to both filter and map elements from `iter`
|
||||||
pub struct FilterMapIterator<'self, A, B, T> {
|
pub struct FilterMapIterator<'self, A, B, T> {
|
||||||
priv iter: 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
|
/// An iterator which yields the current count and the element during iteration
|
||||||
// FIXME #6967: Dummy A parameter to get around type inference bug
|
// FIXME #6967: Dummy A parameter to get around type inference bug
|
||||||
pub struct EnumerateIterator<A, T> {
|
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.
|
/// An iterator which just modifies the contained state throughout iteration.
|
||||||
pub struct UnfoldrIterator<'self, A, St> {
|
pub struct UnfoldrIterator<'self, A, St> {
|
||||||
priv f: &'self fn(&mut St) -> Option<A>,
|
priv f: &'self fn(&mut St) -> Option<A>,
|
||||||
@@ -1526,4 +1598,53 @@ mod tests {
|
|||||||
it.next();
|
it.next();
|
||||||
assert_eq!(it.invert().transform(|&x| x).collect::<~[int]>(), ~[16, 14, 12, 10, 8, 6]);
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user