Skip to content

Commit e632daf

Browse files
authored
Rollup merge of rust-lang#60492 - acrrd:issues/54054_chain, r=SimonSapin
Add custom nth_back for Chain Implementation of nth_back for Chain. Part of rust-lang#54054
2 parents 9dd5c19 + 7b6ad60 commit e632daf

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/libcore/iter/adapters/chain.rs

+23
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,29 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
207207
}
208208
}
209209

210+
#[inline]
211+
fn nth_back(&mut self, mut n: usize) -> Option<A::Item> {
212+
match self.state {
213+
ChainState::Both | ChainState::Back => {
214+
for x in self.b.by_ref().rev() {
215+
if n == 0 {
216+
return Some(x)
217+
}
218+
n -= 1;
219+
}
220+
if let ChainState::Both = self.state {
221+
self.state = ChainState::Front;
222+
}
223+
}
224+
ChainState::Front => {}
225+
}
226+
if let ChainState::Front = self.state {
227+
self.a.nth_back(n)
228+
} else {
229+
None
230+
}
231+
}
232+
210233
fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
211234
Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
212235
{

src/libcore/tests/iter.rs

+16
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,22 @@ fn test_iterator_chain_nth() {
103103
assert_eq!(it.next(), None);
104104
}
105105

106+
#[test]
107+
fn test_iterator_chain_nth_back() {
108+
let xs = [0, 1, 2, 3, 4, 5];
109+
let ys = [30, 40, 50, 60];
110+
let zs = [];
111+
let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
112+
for (i, x) in expected.iter().rev().enumerate() {
113+
assert_eq!(Some(x), xs.iter().chain(&ys).nth_back(i));
114+
}
115+
assert_eq!(zs.iter().chain(&xs).nth_back(0), Some(&5));
116+
117+
let mut it = xs.iter().chain(&zs);
118+
assert_eq!(it.nth_back(5), Some(&0));
119+
assert_eq!(it.next(), None);
120+
}
121+
106122
#[test]
107123
fn test_iterator_chain_last() {
108124
let xs = [0, 1, 2, 3, 4, 5];

0 commit comments

Comments
 (0)