diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index a3e9cfa94931..e7efd9728b94 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -1,6 +1,6 @@
use convert::TryFrom;
use mem;
-use ops::{self, Add, Sub};
+use ops::{self, Add, Sub, Try};
use usize;
use super::{FusedIterator, TrustedLen};
@@ -368,11 +368,11 @@ fn nth(&mut self, n: usize) -> Option {
Some(Less) => {
self.is_empty = Some(false);
self.start = plus_n.add_one();
- return Some(plus_n)
+ return Some(plus_n);
}
Some(Equal) => {
self.is_empty = Some(true);
- return Some(plus_n)
+ return Some(plus_n);
}
_ => {}
}
@@ -382,6 +382,34 @@ fn nth(&mut self, n: usize) -> Option {
None
}
+ #[inline]
+ fn try_fold(&mut self, init: B, mut f: F) -> R
+ where
+ Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try
+ {
+ self.compute_is_empty();
+
+ if self.is_empty() {
+ return Try::from_ok(init);
+ }
+
+ let mut accum = init;
+
+ while self.start < self.end {
+ let n = self.start.add_one();
+ let n = mem::replace(&mut self.start, n);
+ accum = f(accum, n)?;
+ }
+
+ self.is_empty = Some(true);
+
+ if self.start == self.end {
+ accum = f(accum, self.start.clone())?;
+ }
+
+ Try::from_ok(accum)
+ }
+
#[inline]
fn last(mut self) -> Option {
self.next_back()
@@ -415,6 +443,33 @@ fn next_back(&mut self) -> Option {
self.end.clone()
})
}
+
+ #[inline]
+ fn try_rfold(&mut self, init: B, mut f: F) -> R where
+ Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try
+ {
+ self.compute_is_empty();
+
+ if self.is_empty() {
+ return Try::from_ok(init);
+ }
+
+ let mut accum = init;
+
+ while self.start < self.end {
+ let n = self.end.sub_one();
+ let n = mem::replace(&mut self.end, n);
+ accum = f(accum, n)?;
+ }
+
+ self.is_empty = Some(true);
+
+ if self.start == self.end {
+ accum = f(accum, self.start.clone())?;
+ }
+
+ Try::from_ok(accum)
+ }
}
#[stable(feature = "fused", since = "1.26.0")]
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index b3dd5d20299c..998b597d5e11 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -334,12 +334,14 @@ pub struct RangeInclusive {
trait RangeInclusiveEquality: Sized {
fn canonicalized_is_empty(range: &RangeInclusive) -> bool;
}
+
impl RangeInclusiveEquality for T {
#[inline]
default fn canonicalized_is_empty(range: &RangeInclusive) -> bool {
range.is_empty.unwrap_or_default()
}
}
+
impl RangeInclusiveEquality for T {
#[inline]
fn canonicalized_is_empty(range: &RangeInclusive) -> bool {
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 9b76a4af9882..d880abb181c2 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1741,19 +1741,37 @@ fn test_range_inclusive_folds() {
assert_eq!((1..=10).sum::(), 55);
assert_eq!((1..=10).rev().sum::(), 55);
- let mut it = 40..=50;
+ let mut it = 44..=50;
assert_eq!(it.try_fold(0, i8::checked_add), None);
- assert_eq!(it, 44..=50);
+ assert_eq!(it, 47..=50);
+ assert_eq!(it.try_fold(0, i8::checked_add), None);
+ assert_eq!(it, 50..=50);
+ assert_eq!(it.try_fold(0, i8::checked_add), Some(50));
+ assert!(it.is_empty());
+ assert_eq!(it.try_fold(0, i8::checked_add), Some(0));
+ assert!(it.is_empty());
+
+ let mut it = 40..=47;
assert_eq!(it.try_rfold(0, i8::checked_add), None);
- assert_eq!(it, 44..=47);
+ assert_eq!(it, 40..=44);
+ assert_eq!(it.try_rfold(0, i8::checked_add), None);
+ assert_eq!(it, 40..=41);
+ assert_eq!(it.try_rfold(0, i8::checked_add), Some(81));
+ assert!(it.is_empty());
+ assert_eq!(it.try_rfold(0, i8::checked_add), Some(0));
+ assert!(it.is_empty());
let mut it = 10..=20;
assert_eq!(it.try_fold(0, |a,b| Some(a+b)), Some(165));
assert!(it.is_empty());
+ assert_eq!(it.try_fold(0, |a,b| Some(a+b)), Some(0));
+ assert!(it.is_empty());
let mut it = 10..=20;
assert_eq!(it.try_rfold(0, |a,b| Some(a+b)), Some(165));
assert!(it.is_empty());
+ assert_eq!(it.try_rfold(0, |a,b| Some(a+b)), Some(0));
+ assert!(it.is_empty());
}
#[test]