diff options
| author | blake2-ppc <blake2-ppc> | 2013-08-30 19:59:49 +0200 |
|---|---|---|
| committer | blake2-ppc <blake2-ppc> | 2013-08-30 20:03:40 +0200 |
| commit | 4b2cc22031d56a4846bc0ad4e65e19892db734c4 (patch) | |
| tree | fd0936df8c0f8eddda113da78792ceb18616fdf6 /src/libstd | |
| parent | 0ac3e023d86fa84ed38bca3d34003b494fd28acf (diff) | |
| download | rust-4b2cc22031d56a4846bc0ad4e65e19892db734c4.tar.gz rust-4b2cc22031d56a4846bc0ad4e65e19892db734c4.zip | |
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).
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/iterator.rs | 35 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 3 |
2 files changed, 38 insertions, 0 deletions
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 4af7b3e2425..19596421cb2 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -616,6 +616,26 @@ pub trait RandomAccessIterator<A>: Iterator<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 #[deriving(Clone)] 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> { #[inline] fn indexable(&self) -> uint { diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 12aebe20161..6ddb2a72286 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<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> { fn clone(&self) -> VecIterator<'self, T> { *self } } |
