Skip to content

Commit c5d6a0d

Browse files
committed
Implement iter::Chain::{advance_by, advance_back_by}
1 parent 9cba260 commit c5d6a0d

File tree

1 file changed

+64
-12
lines changed

1 file changed

+64
-12
lines changed

library/core/src/iter/adapters/chain.rs

+64-12
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,42 @@ where
115115
}
116116

117117
#[inline]
118-
fn nth(&mut self, mut n: usize) -> Option<A::Item> {
118+
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
119+
let mut rem = n;
120+
119121
if let Some(ref mut a) = self.a {
120-
while let Some(x) = a.next() {
121-
if n == 0 {
122-
return Some(x);
123-
}
124-
n -= 1;
122+
match a.advance_by(rem) {
123+
Ok(()) => return Ok(()),
124+
Err(k) => rem -= k,
125125
}
126126
self.a = None;
127127
}
128+
129+
if let Some(ref mut b) = self.b {
130+
match b.advance_by(rem) {
131+
Ok(()) => return Ok(()),
132+
Err(k) => rem -= k,
133+
}
134+
// we don't fuse the second iterator
135+
}
136+
137+
if rem == 0 { Ok(()) } else { Err(n - rem) }
138+
}
139+
140+
#[inline]
141+
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
142+
if let Some(ref mut a) = self.a {
143+
match a.advance_by(n) {
144+
Ok(()) => match a.next() {
145+
None => n = 0,
146+
x => return x,
147+
},
148+
Err(k) => n -= k,
149+
}
150+
151+
self.a = None;
152+
}
153+
128154
maybe!(self.b.nth(n))
129155
}
130156

@@ -191,16 +217,42 @@ where
191217
}
192218

193219
#[inline]
194-
fn nth_back(&mut self, mut n: usize) -> Option<A::Item> {
220+
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
221+
let mut rem = n;
222+
195223
if let Some(ref mut b) = self.b {
196-
while let Some(x) = b.next_back() {
197-
if n == 0 {
198-
return Some(x);
199-
}
200-
n -= 1;
224+
match b.advance_back_by(rem) {
225+
Ok(()) => return Ok(()),
226+
Err(k) => rem -= k,
201227
}
202228
self.b = None;
203229
}
230+
231+
if let Some(ref mut a) = self.a {
232+
match a.advance_back_by(rem) {
233+
Ok(()) => return Ok(()),
234+
Err(k) => rem -= k,
235+
}
236+
// we don't fuse the second iterator
237+
}
238+
239+
if rem == 0 { Ok(()) } else { Err(n - rem) }
240+
}
241+
242+
#[inline]
243+
fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
244+
if let Some(ref mut b) = self.b {
245+
match b.advance_back_by(n) {
246+
Ok(()) => match b.next_back() {
247+
None => n = 0,
248+
x => return x,
249+
},
250+
Err(k) => n -= k,
251+
}
252+
253+
self.b = None;
254+
}
255+
204256
maybe!(self.a.nth_back(n))
205257
}
206258

0 commit comments

Comments
 (0)