diff options
| author | blake2-ppc <blake2-ppc> | 2013-09-30 20:59:46 +0200 |
|---|---|---|
| committer | blake2-ppc <blake2-ppc> | 2013-09-30 20:59:46 +0200 |
| commit | 8163cb53903dd09e920b6267eba72793394b77d0 (patch) | |
| tree | b68d1c18f17c947a08af5dcd462fac572474909c /src/libstd | |
| parent | 92e7bb67a8038ff73ad9dc88d8be3d3df4777282 (diff) | |
| download | rust-8163cb53903dd09e920b6267eba72793394b77d0.tar.gz rust-8163cb53903dd09e920b6267eba72793394b77d0.zip | |
std::iter: Introduce .by_ref() adaptor
Creates a wrapper around a mutable reference to the iterator. This is useful to allow applying iterator adaptors while still retaining ownership of the original iterator value. Example:: let mut xs = range(0, 10); // sum the first five values let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b); assert!(partial_sum == 10); // xs.next() is now `5` assert!(xs.next() == Some(5));
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/iter.rs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 4695123548b..255f869a905 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -405,6 +405,25 @@ pub trait Iterator<A> { Inspect{iter: self, f: f} } + /// Creates a wrapper around a mutable reference to the iterator. + /// + /// This is useful to allow applying iterator adaptors while still + /// retaining ownership of the original iterator value. + /// + /// # Example + /// + /// ```rust + /// let mut xs = range(0, 10); + /// // sum the first five values + /// let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b); + /// assert!(partial_sum == 10); + /// // xs.next() is now `5` + /// assert!(xs.next() == Some(5)); + /// ``` + fn by_ref<'r>(&'r mut self) -> ByRef<'r, Self> { + ByRef{iter: self} + } + /// An adaptation of an external iterator to the for-loop protocol of rust. /// /// # Example @@ -771,6 +790,22 @@ impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterato } } +/// A mutable reference to an iterator +pub struct ByRef<'self, T> { + priv iter: &'self mut T +} + +impl<'self, A, T: Iterator<A>> Iterator<A> for ByRef<'self, T> { + #[inline] + fn next(&mut self) -> Option<A> { self.iter.next() } + // FIXME: #9629 we cannot implement &self methods like size_hint on ByRef +} + +impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for ByRef<'self, T> { + #[inline] + fn next_back(&mut self) -> Option<A> { self.iter.next_back() } +} + /// A trait for iterators over elements which can be added together pub trait AdditiveIterator<A> { /// Iterates over the entire iterator, summing up all the elements @@ -2501,6 +2536,15 @@ mod tests { } #[test] + fn test_by_ref() { + let mut xs = range(0, 10); + // sum the first five values + let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b); + assert_eq!(partial_sum, 10); + assert_eq!(xs.next(), Some(5)); + } + + #[test] fn test_invert() { let xs = [2, 4, 6, 8, 10, 12, 14, 16]; let mut it = xs.iter(); |
