@@ -405,6 +405,25 @@ pub trait Iterator<A> {
405
405
Inspect { iter : self , f : f}
406
406
}
407
407
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
+
408
427
/// An adaptation of an external iterator to the for-loop protocol of rust.
409
428
///
410
429
/// # Example
@@ -771,6 +790,22 @@ impl<A, T: DoubleEndedIterator<A> + RandomAccessIterator<A>> RandomAccessIterato
771
790
}
772
791
}
773
792
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
+
774
809
/// A trait for iterators over elements which can be added together
775
810
pub trait AdditiveIterator < A > {
776
811
/// Iterates over the entire iterator, summing up all the elements
@@ -2500,6 +2535,15 @@ mod tests {
2500
2535
assert_eq ! ( * xs. iter( ) . min_by( |x| x. abs( ) ) . unwrap( ) , 0 ) ;
2501
2536
}
2502
2537
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
+
2503
2547
#[ test]
2504
2548
fn test_invert ( ) {
2505
2549
let xs = [ 2 , 4 , 6 , 8 , 10 , 12 , 14 , 16 ] ;
0 commit comments