about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-09-09 16:33:43 +0000
committerbors <bors@rust-lang.org>2019-09-09 16:33:43 +0000
commit0b36e9dea3f2ff25b1d0df2669836c33cce89ae5 (patch)
treee5e45ef04b46bdba8f8959029e7da415a58b0983 /src/libcore
parent45859b7ca764cafb14efb8c63a83d5e48dc5d016 (diff)
parentf7ee13040b66c323359c8aea139ba4d91db84376 (diff)
downloadrust-0b36e9dea3f2ff25b1d0df2669836c33cce89ae5.tar.gz
rust-0b36e9dea3f2ff25b1d0df2669836c33cce89ae5.zip
Auto merge of #64313 - Centril:rollup-7w8b67g, r=Centril
Rollup of 5 pull requests

Successful merges:

 - #63468 (Resolve attributes in several places)
 - #64121 (Override `StepBy::{try_fold, try_rfold}`)
 - #64278 (check git in bootstrap.py)
 - #64306 (Fix typo in config.toml.example)
 - #64312 (Unify escape usage)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/iter/adapters/mod.rs44
-rw-r--r--src/libcore/tests/iter.rs35
2 files changed, 78 insertions, 1 deletions
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 8e1ac6082c8..3b8edc2ad61 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -5,7 +5,7 @@ use crate::usize;
 use crate::intrinsics;
 
 use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen};
-use super::LoopState;
+use super::{LoopState, from_fn};
 
 mod chain;
 mod flatten;
@@ -534,6 +534,26 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
             self.iter.nth(nth - 1);
         }
     }
+
+    fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
+    where
+        F: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+    {
+        #[inline]
+        fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
+            move || iter.nth(step)
+        }
+
+        if self.first_take {
+            self.first_take = false;
+            match self.iter.next() {
+                None => return Try::from_ok(acc),
+                Some(x) => acc = f(acc, x)?,
+            }
+        }
+        from_fn(nth(&mut self.iter, self.step)).try_fold(acc, f)
+    }
 }
 
 impl<I> StepBy<I> where I: ExactSizeIterator {
@@ -567,6 +587,28 @@ impl<I> DoubleEndedIterator for StepBy<I> where I: DoubleEndedIterator + ExactSi
             .saturating_add(self.next_back_index());
         self.iter.nth_back(n)
     }
+
+    fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R
+    where
+        F: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+    {
+        #[inline]
+        fn nth_back<I: DoubleEndedIterator>(
+            iter: &mut I,
+            step: usize,
+        ) -> impl FnMut() -> Option<I::Item> + '_ {
+            move || iter.nth_back(step)
+        }
+
+        match self.next_back() {
+            None => Try::from_ok(init),
+            Some(x) => {
+                let acc = f(init, x)?;
+                from_fn(nth_back(&mut self.iter, self.step)).try_fold(acc, f)
+            }
+        }
+    }
 }
 
 // StepBy can only make the iterator shorter, so the len will still fit.
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index d7088cf891f..c9096b713f2 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -386,6 +386,23 @@ fn test_iterator_step_by_nth_overflow() {
 }
 
 #[test]
+fn test_iterator_step_by_nth_try_fold() {
+    let mut it = (0..).step_by(10);
+    assert_eq!(it.try_fold(0, i8::checked_add), None);
+    assert_eq!(it.next(), Some(60));
+    assert_eq!(it.try_fold(0, i8::checked_add), None);
+    assert_eq!(it.next(), Some(90));
+
+    let mut it = (100..).step_by(10);
+    assert_eq!(it.try_fold(50, i8::checked_add), None);
+    assert_eq!(it.next(), Some(110));
+
+    let mut it = (100..=100).step_by(10);
+    assert_eq!(it.next(), Some(100));
+    assert_eq!(it.try_fold(0, i8::checked_add), Some(0));
+}
+
+#[test]
 fn test_iterator_step_by_nth_back() {
     let mut it = (0..16).step_by(5);
     assert_eq!(it.nth_back(0), Some(15));
@@ -411,6 +428,24 @@ fn test_iterator_step_by_nth_back() {
 }
 
 #[test]
+fn test_iterator_step_by_nth_try_rfold() {
+    let mut it = (0..100).step_by(10);
+    assert_eq!(it.try_rfold(0, i8::checked_add), None);
+    assert_eq!(it.next_back(), Some(70));
+    assert_eq!(it.next(), Some(0));
+    assert_eq!(it.try_rfold(0, i8::checked_add), None);
+    assert_eq!(it.next_back(), Some(30));
+
+    let mut it = (0..100).step_by(10);
+    assert_eq!(it.try_rfold(50, i8::checked_add), None);
+    assert_eq!(it.next_back(), Some(80));
+
+    let mut it = (100..=100).step_by(10);
+    assert_eq!(it.next_back(), Some(100));
+    assert_eq!(it.try_fold(0, i8::checked_add), Some(0));
+}
+
+#[test]
 #[should_panic]
 fn test_iterator_step_by_zero() {
     let mut it = (0..).step_by(0);