Optimize Iterator implementation for &mut impl Iterator + Sized
This commit is contained in:
parent
6f8c0557e0
commit
922cd417ea
3 changed files with 130 additions and 0 deletions
|
|
@ -361,6 +361,12 @@ macro_rules! impl_fold_via_try_fold {
|
|||
(rfold -> try_rfold) => {
|
||||
impl_fold_via_try_fold! { @internal rfold -> try_rfold }
|
||||
};
|
||||
(spec_fold -> spec_try_fold) => {
|
||||
impl_fold_via_try_fold! { @internal spec_fold -> spec_try_fold }
|
||||
};
|
||||
(spec_rfold -> spec_try_rfold) => {
|
||||
impl_fold_via_try_fold! { @internal spec_rfold -> spec_try_rfold }
|
||||
};
|
||||
(@internal $fold:ident -> $try_fold:ident) => {
|
||||
#[inline]
|
||||
fn $fold<AAA, FFF>(mut self, init: AAA, fold: FFF) -> AAA
|
||||
|
|
|
|||
|
|
@ -379,4 +379,66 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
|
|||
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
|
||||
(**self).nth_back(n)
|
||||
}
|
||||
fn rfold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
self.spec_rfold(init, f)
|
||||
}
|
||||
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Output = B>,
|
||||
{
|
||||
self.spec_try_rfold(init, f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait to specialize `rfold` and `rtry_fold` for `&mut I where I: Sized`
|
||||
trait DoubleEndedIteratorRefSpec: DoubleEndedIterator {
|
||||
fn spec_rfold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B;
|
||||
|
||||
fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Output = B>;
|
||||
}
|
||||
|
||||
impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIteratorRefSpec for &mut I {
|
||||
default fn spec_rfold<B, F>(self, init: B, mut f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
let mut accum = init;
|
||||
while let Some(x) = self.next_back() {
|
||||
accum = f(accum, x);
|
||||
}
|
||||
accum
|
||||
}
|
||||
|
||||
default fn spec_try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Output = B>,
|
||||
{
|
||||
let mut accum = init;
|
||||
while let Some(x) = self.next_back() {
|
||||
accum = f(accum, x)?;
|
||||
}
|
||||
try { accum }
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: DoubleEndedIterator> DoubleEndedIteratorRefSpec for &mut I {
|
||||
impl_fold_via_try_fold! { spec_rfold -> spec_try_rfold }
|
||||
|
||||
fn spec_try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Output = B>,
|
||||
{
|
||||
(**self).try_rfold(init, f)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4018,4 +4018,66 @@ impl<I: Iterator + ?Sized> Iterator for &mut I {
|
|||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
(**self).nth(n)
|
||||
}
|
||||
fn fold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
self.spec_fold(init, f)
|
||||
}
|
||||
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Output = B>,
|
||||
{
|
||||
self.spec_try_fold(init, f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait to specialize `fold` and `try_fold` for `&mut I where I: Sized`
|
||||
trait IteratorRefSpec: Iterator {
|
||||
fn spec_fold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B;
|
||||
|
||||
fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Output = B>;
|
||||
}
|
||||
|
||||
impl<I: Iterator + ?Sized> IteratorRefSpec for &mut I {
|
||||
default fn spec_fold<B, F>(self, init: B, mut f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
let mut accum = init;
|
||||
while let Some(x) = self.next() {
|
||||
accum = f(accum, x);
|
||||
}
|
||||
accum
|
||||
}
|
||||
|
||||
default fn spec_try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Output = B>,
|
||||
{
|
||||
let mut accum = init;
|
||||
while let Some(x) = self.next() {
|
||||
accum = f(accum, x)?;
|
||||
}
|
||||
try { accum }
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Iterator> IteratorRefSpec for &mut I {
|
||||
impl_fold_via_try_fold! { spec_fold -> spec_try_fold }
|
||||
|
||||
fn spec_try_fold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Output = B>,
|
||||
{
|
||||
(**self).try_fold(init, f)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue