diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-04-19 06:03:12 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-04-19 06:03:12 +0200 |
| commit | 291e44b3815b95b02bba0bf873351a2b6dfd72b9 (patch) | |
| tree | e0e7a8c70f5cfdbf4e0861c44f5c91ad67cc9fd7 /src | |
| parent | 7f450bd3ca9edd39b876293650d49dc17d200256 (diff) | |
| parent | 2605537012022980d5ec69ad11653794db935cf6 (diff) | |
| download | rust-291e44b3815b95b02bba0bf873351a2b6dfd72b9.tar.gz rust-291e44b3815b95b02bba0bf873351a2b6dfd72b9.zip | |
Rollup merge of #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 #54054.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/iter/adapters/mod.rs | 26 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 5 | ||||
| -rw-r--r-- | src/libcore/tests/iter.rs | 18 |
3 files changed, 49 insertions, 0 deletions
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index ce18b4b97ad..d6c5c3a2b09 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -982,6 +982,16 @@ impl<I> DoubleEndedIterator for Enumerate<I> where } #[inline] + fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> { + self.iter.nth_back(n).map(|a| { + let len = self.iter.len(); + // Can safely add, `ExactSizeIterator` promises that the number of + // elements fits into a `usize`. + (self.count + len, a) + }) + } + + #[inline] fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc> { @@ -1791,6 +1801,17 @@ impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator { } #[inline] + default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> { + if self.done { + None + } else { + let nth = self.iter.nth_back(n); + self.done = nth.is_none(); + nth + } + } + + #[inline] default fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc> { @@ -1879,6 +1900,11 @@ impl<I> DoubleEndedIterator for Fuse<I> } #[inline] + fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> { + self.iter.nth_back(n) + } + + #[inline] fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc> { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f4bb887dd29..b7e2825dd9c 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -796,6 +796,11 @@ impl DoubleEndedIterator for Bytes<'_> { } #[inline] + fn nth_back(&mut self, n: usize) -> Option<Self::Item> { + self.0.nth_back(n) + } + + #[inline] fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where P: FnMut(&Self::Item) -> bool { diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index d5b581d336d..5247331fba2 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -390,6 +390,24 @@ fn test_iterator_enumerate_nth() { } #[test] +fn test_iterator_enumerate_nth_back() { + let xs = [0, 1, 2, 3, 4, 5]; + let mut it = xs.iter().enumerate(); + while let Some((i, &x)) = it.nth_back(0) { + assert_eq!(i, x); + } + + let mut it = xs.iter().enumerate(); + while let Some((i, &x)) = it.nth_back(1) { + assert_eq!(i, x); + } + + let (i, &x) = xs.iter().enumerate().nth_back(3).unwrap(); + assert_eq!(i, x); + assert_eq!(i, 2); +} + +#[test] fn test_iterator_enumerate_count() { let xs = [0, 1, 2, 3, 4, 5]; assert_eq!(xs.iter().enumerate().count(), 6); |
