Skip to content

Commit 8163cb5

Browse files
author
blake2-ppc
committed
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));
1 parent 92e7bb6 commit 8163cb5

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/libstd/iter.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,25 @@ pub trait Iterator<A> {
405405
Inspect{iter: self, f: f}
406406
}
407407

408+
/// Creates a wrapper around a mutable reference to the iterator.
409+
///
410+
/// This is useful to allow applying iterator adaptors while still
411+
/// retaining ownership of the original iterator value.
412+
///
413+
/// # Example
414+
///
415+
/// ```rust
416+
/// let mut xs = range(0, 10);
417+
/// // sum the first five values
418+
/// let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b);
419+
/// assert!(partial_sum == 10);
420+
/// // xs.next() is now `5`
421+
/// assert!(xs.next() == Some(5));
422+
/// ```
423+
fn by_ref<'r>(&'r mut self) -> ByRef<'r, Self> {
424+
ByRef{iter: self}
425+
}
426+
408427
/// An adaptation of an external iterator to the for-loop protocol of rust.
409428
///
410429
/// # Example
@@ -771,6 +790,22 @@ impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterato
771790
}
772791
}
773792

793+
/// A mutable reference to an iterator
794+
pub struct ByRef<'self, T> {
795+
priv iter: &'self mut T
796+
}
797+
798+
impl<'self, A, T: Iterator<A>> Iterator<A> for ByRef<'self, T> {
799+
#[inline]
800+
fn next(&mut self) -> Option<A> { self.iter.next() }
801+
// FIXME: #9629 we cannot implement &self methods like size_hint on ByRef
802+
}
803+
804+
impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for ByRef<'self, T> {
805+
#[inline]
806+
fn next_back(&mut self) -> Option<A> { self.iter.next_back() }
807+
}
808+
774809
/// A trait for iterators over elements which can be added together
775810
pub trait AdditiveIterator<A> {
776811
/// Iterates over the entire iterator, summing up all the elements
@@ -2500,6 +2535,15 @@ mod tests {
25002535
assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
25012536
}
25022537

2538+
#[test]
2539+
fn test_by_ref() {
2540+
let mut xs = range(0, 10);
2541+
// sum the first five values
2542+
let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b);
2543+
assert_eq!(partial_sum, 10);
2544+
assert_eq!(xs.next(), Some(5));
2545+
}
2546+
25032547
#[test]
25042548
fn test_invert() {
25052549
let xs = [2, 4, 6, 8, 10, 12, 14, 16];

0 commit comments

Comments
 (0)