Skip to content

Commit b1dc19c

Browse files
committed
Proxy nth in by ref iterators.
When treating a reference to an iterator as an iterator, proxy calls to nth to the underlying implementation instead of calling the default nth defined in the trait. This allows us to take advantage of optimized nth implementations in by-ref iterators. We can't proxy the other methods due to their sized constraints and the fact that we can't specialize.
1 parent 04483c8 commit b1dc19c

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

src/libcore/iter.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1125,8 +1125,18 @@ fn select_fold1<I,B, FProj, FCmp>(mut it: I,
11251125
#[stable(feature = "rust1", since = "1.0.0")]
11261126
impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
11271127
type Item = I::Item;
1128-
fn next(&mut self) -> Option<I::Item> { (**self).next() }
1129-
fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
1128+
1129+
fn next(&mut self) -> Option<I::Item> {
1130+
(**self).next()
1131+
}
1132+
1133+
fn size_hint(&self) -> (usize, Option<usize>) {
1134+
(**self).size_hint()
1135+
}
1136+
1137+
fn nth(&mut self, n: usize) -> Option<I::Item> {
1138+
(**self).nth(n)
1139+
}
11301140
}
11311141

11321142
/// Conversion from an `Iterator`

src/libcoretest/iter.rs

+14
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,20 @@ fn test_by_ref() {
651651
assert_eq!(xs.next(), Some(5));
652652
}
653653

654+
#[test]
655+
fn test_by_ref_nth() {
656+
let mut xs = 0..10;
657+
let mut ys = 0..10;
658+
let mut ysr = ys.by_ref();
659+
loop {
660+
match (xs.nth(2), ysr.nth(2)) {
661+
(Some(x), Some(y)) => assert_eq!(x, y),
662+
(None, None) => break,
663+
_ => panic!("Both iterators should have finished at the same time."),
664+
}
665+
}
666+
}
667+
654668
#[test]
655669
fn test_rev() {
656670
let xs = [2, 4, 6, 8, 10, 12, 14, 16];

0 commit comments

Comments
 (0)