]> git.lizzy.rs Git - rust.git/commitdiff
iter: Implement .fold() for .chain()
authorUlrik Sverdrup <bluss@users.noreply.github.com>
Tue, 25 Oct 2016 13:21:49 +0000 (15:21 +0200)
committerUlrik Sverdrup <bluss@users.noreply.github.com>
Tue, 25 Oct 2016 20:06:39 +0000 (22:06 +0200)
Chain can do something interesting here where it passes on the fold
into its inner iterators.

The lets the underlying iterator's custom fold() be used, and skips the
regular chain logic in next.

src/libcore/iter/mod.rs
src/libcoretest/iter.rs

index 2c3b8864a115e4c7d877d0291f5b8eec5f9c5e32..df4f5e5c5764335d1cc53cde45caa840bb14ad27 100644 (file)
@@ -550,6 +550,25 @@ fn count(self) -> usize {
         }
     }
 
+    fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
+        where F: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut accum = init;
+        match self.state {
+            ChainState::Both | ChainState::Front => {
+                accum = self.a.fold(accum, &mut f);
+            }
+            _ => { }
+        }
+        match self.state {
+            ChainState::Both | ChainState::Back => {
+                accum = self.b.fold(accum, &mut f);
+            }
+            _ => { }
+        }
+        accum
+    }
+
     #[inline]
     fn nth(&mut self, mut n: usize) -> Option<A::Item> {
         match self.state {
index 27eb25537f31bde549db5cc266b55b4bacc2027c..58b6444ef88cd95f278d4c0b458516573b1cc5c4 100644 (file)
@@ -985,6 +985,18 @@ fn test_empty() {
     assert_eq!(it.next(), None);
 }
 
+#[test]
+fn test_chain_fold() {
+    let xs = [1, 2, 3];
+    let ys = [1, 2, 0];
+
+    let mut iter = xs.iter().chain(&ys);
+    iter.next();
+    let mut result = Vec::new();
+    iter.fold((), |(), &elt| result.push(elt));
+    assert_eq!(&[2, 3, 1, 2, 0], &result[..]);
+}
+
 #[bench]
 fn bench_rposition(b: &mut Bencher) {
     let it: Vec<usize> = (0..300).collect();