|
5 | 5 | use crate::cmp::{self, Ordering};
|
6 | 6 | use crate::ops::{ControlFlow, Try};
|
7 | 7 |
|
8 |
| -use super::super::TrustedRandomAccess; |
9 | 8 | use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
|
10 | 9 | use super::super::{FlatMap, Flatten};
|
11 | 10 | use super::super::{FromIterator, Intersperse, IntersperseWith, Product, Sum, Zip};
|
12 | 11 | use super::super::{
|
13 | 12 | Inspect, Map, MapWhile, Peekable, Rev, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile,
|
14 | 13 | };
|
| 14 | +use super::super::{TrustedLen, TrustedRandomAccess}; |
15 | 15 |
|
16 | 16 | fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
17 | 17 |
|
@@ -2125,16 +2125,12 @@ pub trait Iterator {
|
2125 | 2125 | #[doc(alias = "inject")]
|
2126 | 2126 | #[inline]
|
2127 | 2127 | #[stable(feature = "rust1", since = "1.0.0")]
|
2128 |
| - fn fold<B, F>(mut self, init: B, mut f: F) -> B |
| 2128 | + fn fold<B, F>(self, init: B, f: F) -> B |
2129 | 2129 | where
|
2130 | 2130 | Self: Sized,
|
2131 | 2131 | F: FnMut(B, Self::Item) -> B,
|
2132 | 2132 | {
|
2133 |
| - let mut accum = init; |
2134 |
| - while let Some(x) = self.next() { |
2135 |
| - accum = f(accum, x); |
2136 |
| - } |
2137 |
| - accum |
| 2133 | + self.fold_spec(init, f) |
2138 | 2134 | }
|
2139 | 2135 |
|
2140 | 2136 | /// Reduces the elements to a single one, by repeatedly applying a reducing
|
@@ -3420,3 +3416,71 @@ impl<I: Iterator + ?Sized> Iterator for &mut I {
|
3420 | 3416 | (**self).nth(n)
|
3421 | 3417 | }
|
3422 | 3418 | }
|
| 3419 | + |
| 3420 | +trait SpecIteratorDefaultImpls: Iterator { |
| 3421 | + fn fold_spec<B, F>(self, init: B, f: F) -> B |
| 3422 | + where |
| 3423 | + Self: Sized, |
| 3424 | + F: FnMut(B, Self::Item) -> B; |
| 3425 | +} |
| 3426 | + |
| 3427 | +impl<T> SpecIteratorDefaultImpls for T |
| 3428 | +where |
| 3429 | + T: Iterator, |
| 3430 | +{ |
| 3431 | + #[inline] |
| 3432 | + default fn fold_spec<B, F>(mut self, init: B, mut f: F) -> B |
| 3433 | + where |
| 3434 | + Self: Sized, |
| 3435 | + F: FnMut(B, Self::Item) -> B, |
| 3436 | + { |
| 3437 | + let mut accum = init; |
| 3438 | + while let Some(x) = self.next() { |
| 3439 | + accum = f(accum, x); |
| 3440 | + } |
| 3441 | + accum |
| 3442 | + } |
| 3443 | +} |
| 3444 | + |
| 3445 | +impl<T> SpecIteratorDefaultImpls for T |
| 3446 | +where |
| 3447 | + T: Iterator + Sized + TrustedLen, |
| 3448 | +{ |
| 3449 | + #[inline] |
| 3450 | + default fn fold_spec<B, F>(mut self, init: B, mut f: F) -> B |
| 3451 | + where |
| 3452 | + Self: Sized, |
| 3453 | + F: FnMut(B, Self::Item) -> B, |
| 3454 | + { |
| 3455 | + let mut accum = init; |
| 3456 | + while self.size_hint().1.is_none() { |
| 3457 | + accum = f(accum, self.next().unwrap()); |
| 3458 | + } |
| 3459 | + for _ in 0..self.size_hint().1.unwrap() { |
| 3460 | + accum = f(accum, self.next().unwrap()) |
| 3461 | + } |
| 3462 | + accum |
| 3463 | + } |
| 3464 | +} |
| 3465 | + |
| 3466 | +impl<T> SpecIteratorDefaultImpls for T |
| 3467 | +where |
| 3468 | + T: Iterator + Sized + TrustedLen + TrustedRandomAccess, |
| 3469 | +{ |
| 3470 | + #[inline] |
| 3471 | + fn fold_spec<B, F>(mut self, init: B, mut f: F) -> B |
| 3472 | + where |
| 3473 | + Self: Sized, |
| 3474 | + F: FnMut(B, Self::Item) -> B, |
| 3475 | + { |
| 3476 | + let mut accum = init; |
| 3477 | + // SAFETY: every element is only read once, as required by the |
| 3478 | + // TrustedRandomAccess contract |
| 3479 | + unsafe { |
| 3480 | + for i in 0..self.size() { |
| 3481 | + accum = f(accum, self.__iterator_get_unchecked(i)) |
| 3482 | + } |
| 3483 | + } |
| 3484 | + accum |
| 3485 | + } |
| 3486 | +} |
0 commit comments