Skip to content

Commit beb9614

Browse files
committed
add SymmetricalModuloLifetimes specialization for double-ended chains
1 parent 8d14986 commit beb9614

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
@@ -183,7 +183,7 @@ where
183183
{
184184
#[inline]
185185
fn next_back(&mut self) -> Option<A::Item> {
186-
and_then_or_clear(&mut self.b, |b| b.next_back()).or_else(|| self.a.as_mut()?.next_back())
186+
SpecChainBack::next_back(self)
187187
}
188188

189189
#[inline]
@@ -324,6 +324,10 @@ trait SpecChain: Iterator {
324324
fn next(&mut self) -> Option<Self::Item>;
325325
}
326326

327+
trait SpecChainBack: DoubleEndedIterator {
328+
fn next_back(&mut self) -> Option<Self::Item>;
329+
}
330+
327331
impl<A, B> SpecChain for Chain<A, B>
328332
where
329333
A: Iterator,
@@ -335,6 +339,17 @@ where
335339
}
336340
}
337341

342+
impl<A, B> SpecChainBack for Chain<A, B>
343+
where
344+
A: DoubleEndedIterator,
345+
B: DoubleEndedIterator<Item = A::Item>,
346+
{
347+
#[inline]
348+
default fn next_back(&mut self) -> Option<Self::Item> {
349+
and_then_or_clear(&mut self.b, |b| b.next_back()).or_else(|| self.a.as_mut()?.next_back())
350+
}
351+
}
352+
338353
impl<A, B> SpecChain for Chain<A, B>
339354
where
340355
A: Iterator,
@@ -352,3 +367,21 @@ where
352367
result
353368
}
354369
}
370+
371+
impl<A, B> SpecChainBack for Chain<A, B>
372+
where
373+
A: DoubleEndedIterator,
374+
B: DoubleEndedIterator<Item = A::Item>,
375+
Self: SymmetricalModuloLifetimes,
376+
{
377+
#[inline]
378+
fn next_back(&mut self) -> Option<Self::Item> {
379+
let mut result = and_then_or_clear(&mut self.b, DoubleEndedIterator::next_back);
380+
if result.is_none() {
381+
// SAFETY: SymmetricalModuloLifetimes guarantees that A and B are safe to swap
382+
unsafe { mem::swap(&mut self.a, &mut *(&mut self.b as *mut _ as *mut Option<A>)) };
383+
result = and_then_or_clear(&mut self.b, DoubleEndedIterator::next_back);
384+
}
385+
result
386+
}
387+
}

0 commit comments

Comments
 (0)