Skip to content

Commit

Permalink
std::iter: Introduce .by_ref() adaptor
Browse files Browse the repository at this point in the history
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));
  • Loading branch information
blake2-ppc committed Sep 30, 2013
1 parent 92e7bb6 commit 8163cb5
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/libstd/iter.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -2500,6 +2535,15 @@ mod tests {
assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
}

#[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];
Expand Down

5 comments on commit 8163cb5

@bors
Copy link
Contributor

@bors bors commented on 8163cb5 Oct 17, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 8163cb5 Oct 17, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging blake2-ppc/rust/by-ref-iter = 8163cb5 into auto

@bors
Copy link
Contributor

@bors bors commented on 8163cb5 Oct 17, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blake2-ppc/rust/by-ref-iter = 8163cb5 merged ok, testing candidate = 63e097d

@bors
Copy link
Contributor

@bors bors commented on 8163cb5 Oct 17, 2013

@bors
Copy link
Contributor

@bors bors commented on 8163cb5 Oct 17, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 63e097d

Please sign in to comment.