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).
This commit is contained in:
parent
0ac3e023d8
commit
4b2cc22031
2 changed files with 38 additions and 0 deletions
|
@ -616,6 +616,26 @@ pub trait RandomAccessIterator<A>: Iterator<A> {
|
||||||
fn idx(&self, index: uint) -> Option<A>;
|
fn idx(&self, index: uint) -> Option<A>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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<T: ExactSizeHint> ExactSizeHint for Enumerate<T> {}
|
||||||
|
impl<'self, A, T: ExactSizeHint> ExactSizeHint for Inspect<'self, A, T> {}
|
||||||
|
impl<T: ExactSizeHint> ExactSizeHint for Invert<T> {}
|
||||||
|
impl<'self, A, B, T: ExactSizeHint> ExactSizeHint for Map<'self, A, B, T> {}
|
||||||
|
impl<A, T: ExactSizeHint> ExactSizeHint for Peekable<A, T> {}
|
||||||
|
impl<T: ExactSizeHint> ExactSizeHint for Skip<T> {}
|
||||||
|
impl<T: ExactSizeHint> ExactSizeHint for Take<T> {}
|
||||||
|
impl<T: ExactSizeHint, U: ExactSizeHint> ExactSizeHint for Zip<T, U> {}
|
||||||
|
|
||||||
/// An double-ended iterator with the direction inverted
|
/// An double-ended iterator with the direction inverted
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct Invert<T> {
|
pub struct Invert<T> {
|
||||||
|
@ -1094,6 +1114,21 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for Enumerate<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<A, T: DoubleEndedIterator<A> + ExactSizeHint> DoubleEndedIterator<(uint, A)>
|
||||||
|
for Enumerate<T> {
|
||||||
|
#[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<A, T: RandomAccessIterator<A>> RandomAccessIterator<(uint, A)> for Enumerate<T> {
|
impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<(uint, A)> for Enumerate<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn indexable(&self) -> uint {
|
fn indexable(&self) -> uint {
|
||||||
|
|
|
@ -2319,6 +2319,9 @@ iterator!{impl VecIterator -> &'self T}
|
||||||
double_ended_iterator!{impl VecIterator -> &'self T}
|
double_ended_iterator!{impl VecIterator -> &'self T}
|
||||||
pub type RevIterator<'self, T> = Invert<VecIterator<'self, T>>;
|
pub type RevIterator<'self, T> = Invert<VecIterator<'self, T>>;
|
||||||
|
|
||||||
|
impl<'self, T> ExactSizeHint for VecIterator<'self, T> {}
|
||||||
|
impl<'self, T> ExactSizeHint for VecMutIterator<'self, T> {}
|
||||||
|
|
||||||
impl<'self, T> Clone for VecIterator<'self, T> {
|
impl<'self, T> Clone for VecIterator<'self, T> {
|
||||||
fn clone(&self) -> VecIterator<'self, T> { *self }
|
fn clone(&self) -> VecIterator<'self, T> { *self }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue