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 }
}