Skip to content

Commit 5f1cedf

Browse files
authored
Rollup merge of rust-lang#60023 - koalatux:nth-back, r=scottmcm
implement specialized nth_back() for Bytes, Fuse and Enumerate Hi, After my first PR has been successfully merged, here is my second pull request :-) Also this PR contains some specializations for the problem discussed in rust-lang#54054.
2 parents 0a23147 + 2605537 commit 5f1cedf

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

src/libcore/iter/adapters/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,16 @@ impl<I> DoubleEndedIterator for Enumerate<I> where
980980
})
981981
}
982982

983+
#[inline]
984+
fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
985+
self.iter.nth_back(n).map(|a| {
986+
let len = self.iter.len();
987+
// Can safely add, `ExactSizeIterator` promises that the number of
988+
// elements fits into a `usize`.
989+
(self.count + len, a)
990+
})
991+
}
992+
983993
#[inline]
984994
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
985995
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
@@ -1789,6 +1799,17 @@ impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
17891799
}
17901800
}
17911801

1802+
#[inline]
1803+
default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
1804+
if self.done {
1805+
None
1806+
} else {
1807+
let nth = self.iter.nth_back(n);
1808+
self.done = nth.is_none();
1809+
nth
1810+
}
1811+
}
1812+
17921813
#[inline]
17931814
default fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
17941815
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
@@ -1877,6 +1898,11 @@ impl<I> DoubleEndedIterator for Fuse<I>
18771898
self.iter.next_back()
18781899
}
18791900

1901+
#[inline]
1902+
fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
1903+
self.iter.nth_back(n)
1904+
}
1905+
18801906
#[inline]
18811907
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
18821908
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>

src/libcore/str/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,11 @@ impl DoubleEndedIterator for Bytes<'_> {
795795
self.0.next_back()
796796
}
797797

798+
#[inline]
799+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
800+
self.0.nth_back(n)
801+
}
802+
798803
#[inline]
799804
fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
800805
P: FnMut(&Self::Item) -> bool

src/libcore/tests/iter.rs

+18
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,24 @@ fn test_iterator_enumerate_nth() {
389389
assert_eq!(i, 3);
390390
}
391391

392+
#[test]
393+
fn test_iterator_enumerate_nth_back() {
394+
let xs = [0, 1, 2, 3, 4, 5];
395+
let mut it = xs.iter().enumerate();
396+
while let Some((i, &x)) = it.nth_back(0) {
397+
assert_eq!(i, x);
398+
}
399+
400+
let mut it = xs.iter().enumerate();
401+
while let Some((i, &x)) = it.nth_back(1) {
402+
assert_eq!(i, x);
403+
}
404+
405+
let (i, &x) = xs.iter().enumerate().nth_back(3).unwrap();
406+
assert_eq!(i, x);
407+
assert_eq!(i, 2);
408+
}
409+
392410
#[test]
393411
fn test_iterator_enumerate_count() {
394412
let xs = [0, 1, 2, 3, 4, 5];

0 commit comments

Comments
 (0)