diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 4af7b3e24259..19596421cb28 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -616,6 +616,26 @@ pub trait RandomAccessIterator: Iterator { fn idx(&self, index: uint) -> Option; } +/// An iterator that knows its exact length +/// +/// This trait is a helper for iterators like the vector iterator, so that +/// it can support double-ended enumeration. +/// +/// `Iterator::size_hint` *must* return the exact size of the iterator. +/// Note that the size must fit in `uint`. +pub trait ExactSizeHint {} + +// All adaptors that preserve the size of the wrapped iterator are fine +// Adaptors that may overflow in `size_hint` are not, i.e. `Chain`. +impl ExactSizeHint for Enumerate {} +impl<'self, A, T: ExactSizeHint> ExactSizeHint for Inspect<'self, A, T> {} +impl ExactSizeHint for Invert {} +impl<'self, A, B, T: ExactSizeHint> ExactSizeHint for Map<'self, A, B, T> {} +impl ExactSizeHint for Peekable {} +impl ExactSizeHint for Skip {} +impl ExactSizeHint for Take {} +impl ExactSizeHint for Zip {} + /// An double-ended iterator with the direction inverted #[deriving(Clone)] pub struct Invert { @@ -1094,6 +1114,21 @@ impl> Iterator<(uint, A)> for Enumerate { } } +impl + ExactSizeHint> DoubleEndedIterator<(uint, A)> +for Enumerate { + #[inline] + fn next_back(&mut self) -> Option<(uint, A)> { + match self.iter.next_back() { + Some(a) => { + let (len, _) = self.iter.size_hint(); + let ret = Some((self.count + len, a)); + ret + } + _ => None + } + } +} + impl> RandomAccessIterator<(uint, A)> for Enumerate { #[inline] fn indexable(&self) -> uint { diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 12aebe20161a..6ddb2a722865 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -2319,6 +2319,9 @@ iterator!{impl VecIterator -> &'self T} double_ended_iterator!{impl VecIterator -> &'self T} pub type RevIterator<'self, T> = Invert>; +impl<'self, T> ExactSizeHint for VecIterator<'self, T> {} +impl<'self, T> ExactSizeHint for VecMutIterator<'self, T> {} + impl<'self, T> Clone for VecIterator<'self, T> { fn clone(&self) -> VecIterator<'self, T> { *self } }