Skip to content

Commit 2c2a695

Browse files
committed
add SymmetricalModuloLifetimes specialization for double-ended chains
1 parent bff32ed commit 2c2a695

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

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

+34-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ where
179179
{
180180
#[inline]
181181
fn next_back(&mut self) -> Option<A::Item> {
182-
and_then_or_clear(&mut self.b, |b| b.next_back()).or_else(|| self.a.as_mut()?.next_back())
182+
SpecChainBack::next_back(self)
183183
}
184184

185185
#[inline]
@@ -337,6 +337,10 @@ trait SpecChain: Iterator {
337337
fn next(&mut self) -> Option<Self::Item>;
338338
}
339339

340+
trait SpecChainBack: DoubleEndedIterator {
341+
fn next_back(&mut self) -> Option<Self::Item>;
342+
}
343+
340344
impl<A, B> SpecChain for Chain<A, B>
341345
where
342346
A: Iterator,
@@ -348,6 +352,17 @@ where
348352
}
349353
}
350354

355+
impl<A, B> SpecChainBack for Chain<A, B>
356+
where
357+
A: DoubleEndedIterator,
358+
B: DoubleEndedIterator<Item = A::Item>,
359+
{
360+
#[inline]
361+
default fn next_back(&mut self) -> Option<Self::Item> {
362+
and_then_or_clear(&mut self.b, |b| b.next_back()).or_else(|| self.a.as_mut()?.next_back())
363+
}
364+
}
365+
351366
impl<A, B> SpecChain for Chain<A, B>
352367
where
353368
A: Iterator,
@@ -365,3 +380,21 @@ where
365380
result
366381
}
367382
}
383+
384+
impl<A, B> SpecChainBack for Chain<A, B>
385+
where
386+
A: DoubleEndedIterator,
387+
B: DoubleEndedIterator<Item = A::Item>,
388+
Self: SymmetricalModuloLifetimes,
389+
{
390+
#[inline]
391+
fn next_back(&mut self) -> Option<Self::Item> {
392+
let mut result = and_then_or_clear(&mut self.b, DoubleEndedIterator::next_back);
393+
if result.is_none() {
394+
// SAFETY: SymmetricalModuloLifetimes guarantees that A and B are safe to swap
395+
unsafe { mem::swap(&mut self.a, &mut *(&mut self.b as *mut _ as *mut Option<A>)) };
396+
result = and_then_or_clear(&mut self.b, DoubleEndedIterator::next_back);
397+
}
398+
result
399+
}
400+
}

0 commit comments

Comments
 (0)