Skip to content

Commit 4b2cc22

Browse files
author
blake2-ppc
committed
std::iterator: Introduce trait ExactSizeHint
The trait `ExactSizeHint` is introduced to solve a few small niggles: * We can't reverse (`.invert()`) an enumeration iterator * for a vector, we have `v.iter().position(f)` but `v.rposition(f)`. * We can't reverse `Zip` even if both iterators are from vectors `ExactSizeHint` is an empty trait that is intended to indicate that an iterator, for example `VecIterator`, knows its exact finite size and reports it correctly using `.size_hint()`. Only adaptors that preserve this at all times, can expose this trait further. (Where here we say finite for fitting in uint).
1 parent 0ac3e02 commit 4b2cc22

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

src/libstd/iterator.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,26 @@ pub trait RandomAccessIterator<A>: Iterator<A> {
616616
fn idx(&self, index: uint) -> Option<A>;
617617
}
618618

619+
/// An iterator that knows its exact length
620+
///
621+
/// This trait is a helper for iterators like the vector iterator, so that
622+
/// it can support double-ended enumeration.
623+
///
624+
/// `Iterator::size_hint` *must* return the exact size of the iterator.
625+
/// Note that the size must fit in `uint`.
626+
pub trait ExactSizeHint {}
627+
628+
// All adaptors that preserve the size of the wrapped iterator are fine
629+
// Adaptors that may overflow in `size_hint` are not, i.e. `Chain`.
630+
impl<T: ExactSizeHint> ExactSizeHint for Enumerate<T> {}
631+
impl<'self, A, T: ExactSizeHint> ExactSizeHint for Inspect<'self, A, T> {}
632+
impl<T: ExactSizeHint> ExactSizeHint for Invert<T> {}
633+
impl<'self, A, B, T: ExactSizeHint> ExactSizeHint for Map<'self, A, B, T> {}
634+
impl<A, T: ExactSizeHint> ExactSizeHint for Peekable<A, T> {}
635+
impl<T: ExactSizeHint> ExactSizeHint for Skip<T> {}
636+
impl<T: ExactSizeHint> ExactSizeHint for Take<T> {}
637+
impl<T: ExactSizeHint, U: ExactSizeHint> ExactSizeHint for Zip<T, U> {}
638+
619639
/// An double-ended iterator with the direction inverted
620640
#[deriving(Clone)]
621641
pub struct Invert<T> {
@@ -1094,6 +1114,21 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for Enumerate<T> {
10941114
}
10951115
}
10961116

1117+
impl<A, T: DoubleEndedIterator<A> + ExactSizeHint> DoubleEndedIterator<(uint, A)>
1118+
for Enumerate<T> {
1119+
#[inline]
1120+
fn next_back(&mut self) -> Option<(uint, A)> {
1121+
match self.iter.next_back() {
1122+
Some(a) => {
1123+
let (len, _) = self.iter.size_hint();
1124+
let ret = Some((self.count + len, a));
1125+
ret
1126+
}
1127+
_ => None
1128+
}
1129+
}
1130+
}
1131+
10971132
impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<(uint, A)> for Enumerate<T> {
10981133
#[inline]
10991134
fn indexable(&self) -> uint {

src/libstd/vec.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,9 @@ iterator!{impl VecIterator -> &'self T}
23192319
double_ended_iterator!{impl VecIterator -> &'self T}
23202320
pub type RevIterator<'self, T> = Invert<VecIterator<'self, T>>;
23212321

2322+
impl<'self, T> ExactSizeHint for VecIterator<'self, T> {}
2323+
impl<'self, T> ExactSizeHint for VecMutIterator<'self, T> {}
2324+
23222325
impl<'self, T> Clone for VecIterator<'self, T> {
23232326
fn clone(&self) -> VecIterator<'self, T> { *self }
23242327
}

0 commit comments

Comments
 (0)