From cc2689a2539a28d54d0f0ec029c487aadad724f0 Mon Sep 17 00:00:00 2001 From: Adrian Friedli Date: Tue, 16 Apr 2019 20:41:23 +0200 Subject: [PATCH 1/3] implement nth_back for Bytes --- src/libcore/str/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 8d28be621d647..24c008460447e 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -795,6 +795,11 @@ impl DoubleEndedIterator for Bytes<'_> { self.0.next_back() } + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + self.0.nth_back(n) + } + #[inline] fn rfind

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool From fae2a68ba21d5cdd3557cd01ca18b792b0bcbd67 Mon Sep 17 00:00:00 2001 From: Adrian Friedli Date: Tue, 16 Apr 2019 21:40:50 +0200 Subject: [PATCH 2/3] implement nth_back for Fuse --- src/libcore/iter/adapters/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index cccd51b577930..f08f2a5ec7519 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1789,6 +1789,17 @@ impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator { } } + #[inline] + default fn nth_back(&mut self, n: usize) -> Option<::Item> { + if self.done { + None + } else { + let nth = self.iter.nth_back(n); + self.done = nth.is_none(); + nth + } + } + #[inline] default fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try @@ -1877,6 +1888,11 @@ impl DoubleEndedIterator for Fuse self.iter.next_back() } + #[inline] + fn nth_back(&mut self, n: usize) -> Option<::Item> { + self.iter.nth_back(n) + } + #[inline] fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try From 2605537012022980d5ec69ad11653794db935cf6 Mon Sep 17 00:00:00 2001 From: Adrian Friedli Date: Tue, 16 Apr 2019 23:45:59 +0200 Subject: [PATCH 3/3] implement nth_back for Enumerate --- src/libcore/iter/adapters/mod.rs | 10 ++++++++++ src/libcore/tests/iter.rs | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index f08f2a5ec7519..9f9146a1523b3 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -980,6 +980,16 @@ impl DoubleEndedIterator for Enumerate where }) } + #[inline] + fn nth_back(&mut self, n: usize) -> Option<(usize, ::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(&mut self, init: Acc, mut fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index d5b581d336d2f..5247331fba24f 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -389,6 +389,24 @@ fn test_iterator_enumerate_nth() { assert_eq!(i, 3); } +#[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];