Update itertools to 0.10.3

Test: cd external/rust/crates && atest --host -c
Change-Id: Ic4635782fb45eaa4b94696aa8a7b3c5dc1910fc3
diff --git a/tests/fold_specialization.rs b/tests/fold_specialization.rs
deleted file mode 100644
index a984b40..0000000
--- a/tests/fold_specialization.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use itertools::Itertools;
-
-#[test]
-fn specialization_intersperse() {
-    let mut iter = (1..2).intersperse(0);
-    iter.clone().for_each(|x| assert_eq!(Some(x), iter.next()));
-
-    let mut iter = (1..3).intersperse(0);
-    iter.clone().for_each(|x| assert_eq!(Some(x), iter.next()));
-
-    let mut iter = (1..4).intersperse(0);
-    iter.clone().for_each(|x| assert_eq!(Some(x), iter.next()));
-}
diff --git a/tests/specializations.rs b/tests/specializations.rs
index bc337c2..199cf56 100644
--- a/tests/specializations.rs
+++ b/tests/specializations.rs
@@ -15,16 +15,16 @@
     }
 }
 
-fn check_specialized<'a, V, IterItem, Iter, F>(iterator: &Iter, mapper: F)
-where
-    V: Eq + Debug,
-    Iter: Iterator<Item = IterItem> + Clone + 'a,
-    F: Fn(Box<dyn Iterator<Item = IterItem> + 'a>) -> V,
-{
-    assert_eq!(
-        mapper(Box::new(Unspecialized(iterator.clone()))),
-        mapper(Box::new(iterator.clone()))
-    )
+macro_rules! check_specialized {
+    ($src:expr, |$it:pat| $closure:expr) => {
+        let $it = $src.clone();
+        let v1 = $closure;
+
+        let $it = Unspecialized($src.clone());
+        let v2 = $closure;
+
+        assert_eq!(v1, v2);
+    }
 }
 
 fn test_specializations<IterItem, Iter>(
@@ -33,10 +33,10 @@
     IterItem: Eq + Debug + Clone,
     Iter: Iterator<Item = IterItem> + Clone,
 {
-    check_specialized(it, |i| i.count());
-    check_specialized(it, |i| i.last());
-    check_specialized(it, |i| i.collect::<Vec<_>>());
-    check_specialized(it, |i| {
+    check_specialized!(it, |i| i.count());
+    check_specialized!(it, |i| i.last());
+    check_specialized!(it, |i| i.collect::<Vec<_>>());
+    check_specialized!(it, |i| {
         let mut parameters_from_fold = vec![];
         let fold_result = i.fold(vec![], |mut acc, v: IterItem| {
             parameters_from_fold.push((acc.clone(), v.clone()));
@@ -45,7 +45,7 @@
         });
         (parameters_from_fold, fold_result)
     });
-    check_specialized(it, |mut i| {
+    check_specialized!(it, |mut i| {
         let mut parameters_from_all = vec![];
         let first = i.next();
         let all_result = i.all(|x| {
@@ -56,7 +56,7 @@
     });
     let size = it.clone().count();
     for n in 0..size + 2 {
-        check_specialized(it, |mut i| i.nth(n));
+        check_specialized!(it, |mut i| i.nth(n));
     }
     // size_hint is a bit harder to check
     let mut it_sh = it.clone();
@@ -73,6 +73,12 @@
 }
 
 quickcheck! {
+    fn intersperse(v: Vec<u8>) -> () {
+        test_specializations(&v.into_iter().intersperse(0));
+    }
+}
+
+quickcheck! {
     fn put_back_qc(test_vec: Vec<i32>) -> () {
         test_specializations(&itertools::put_back(test_vec.iter()));
         let mut pb = itertools::put_back(test_vec.into_iter());
@@ -98,3 +104,50 @@
         test_specializations(&v.into_iter().map_ok(|u| u.checked_add(1)));
     }
 }
+
+quickcheck! {
+    fn process_results(v: Vec<Result<u8, u8>>) -> () {
+        helper(v.iter().copied());
+        helper(v.iter().copied().filter(Result::is_ok));
+
+        fn helper(it: impl Iterator<Item = Result<u8, u8>> + Clone) {
+            macro_rules! check_results_specialized {
+                ($src:expr, |$it:pat| $closure:expr) => {
+                    assert_eq!(
+                        itertools::process_results($src.clone(), |$it| $closure),
+                        itertools::process_results($src.clone(), |i| {
+                            let $it = Unspecialized(i);
+                            $closure
+                        }),
+                    )
+                }
+            }
+
+            check_results_specialized!(it, |i| i.count());
+            check_results_specialized!(it, |i| i.last());
+            check_results_specialized!(it, |i| i.collect::<Vec<_>>());
+            check_results_specialized!(it, |i| {
+                let mut parameters_from_fold = vec![];
+                let fold_result = i.fold(vec![], |mut acc, v| {
+                    parameters_from_fold.push((acc.clone(), v.clone()));
+                    acc.push(v);
+                    acc
+                });
+                (parameters_from_fold, fold_result)
+            });
+            check_results_specialized!(it, |mut i| {
+                let mut parameters_from_all = vec![];
+                let first = i.next();
+                let all_result = i.all(|x| {
+                    parameters_from_all.push(x.clone());
+                    Some(x)==first
+                });
+                (parameters_from_all, all_result)
+            });
+            let size = it.clone().count();
+            for n in 0..size + 2 {
+                check_results_specialized!(it, |mut i| i.nth(n));
+            }
+        }
+    }
+}
diff --git a/tests/test_core.rs b/tests/test_core.rs
index bcdca0e..a7b7449 100644
--- a/tests/test_core.rs
+++ b/tests/test_core.rs
@@ -9,6 +9,8 @@
 use itertools as it;
 use crate::it::Itertools;
 use crate::it::interleave;
+use crate::it::intersperse;
+use crate::it::intersperse_with;
 use crate::it::multizip;
 use crate::it::free::put_back;
 use crate::it::iproduct;
@@ -136,6 +138,23 @@
     it::assert_equal(it, rs.iter());
 }
 
+#[test]
+fn test_intersperse() {
+    let xs = [1u8, 2, 3];
+    let ys = [1u8, 0, 2, 0, 3];
+    let it = intersperse(&xs, &0);
+    it::assert_equal(it, ys.iter());
+}
+
+#[test]
+fn test_intersperse_with() {
+    let xs = [1u8, 2, 3];
+    let ys = [1u8, 10, 2, 10, 3];
+    let i = 10;
+    let it = intersperse_with(&xs, || &i);
+    it::assert_equal(it, ys.iter());
+}
+
 #[allow(deprecated)]
 #[test]
 fn foreach() {
diff --git a/tests/test_std.rs b/tests/test_std.rs
index 7cda9b5..2049d15 100644
--- a/tests/test_std.rs
+++ b/tests/test_std.rs
@@ -84,6 +84,13 @@
     it::assert_equal(ys.iter(), xs.iter().rev().duplicates().rev());
     let ys_rev = [1, 0];
     it::assert_equal(ys_rev.iter(), xs.iter().duplicates().rev());
+
+    let xs = vec![0, 1, 2, 1, 2];
+    let ys = vec![1, 2];
+    assert_eq!(ys, xs.iter().duplicates().cloned().collect_vec());
+    assert_eq!(ys, xs.iter().rev().duplicates().rev().cloned().collect_vec());
+    let ys_rev = vec![2, 1];
+    assert_eq!(ys_rev, xs.iter().duplicates().rev().cloned().collect_vec());
 }
 
 #[test]
@@ -504,6 +511,30 @@
 }
 
 #[test]
+fn sorted_by_cached_key() {
+    // Track calls to key function
+    let mut ncalls = 0;
+
+    let sorted = [3, 4, 1, 2].iter().cloned().sorted_by_cached_key(|&x| {
+        ncalls += 1;
+        x.to_string()
+    });
+    it::assert_equal(sorted, vec![1, 2, 3, 4]);
+    // Check key function called once per element
+    assert_eq!(ncalls, 4);
+
+    let mut ncalls = 0;
+
+    let sorted = (0..5).sorted_by_cached_key(|&x| {
+        ncalls += 1;
+        -x
+    });
+    it::assert_equal(sorted, vec![4, 3, 2, 1, 0]);
+    // Check key function called once per element
+    assert_eq!(ncalls, 5);
+}
+
+#[test]
 fn test_multipeek() {
     let nums = vec![1u8,2,3,4,5];
 
@@ -1080,3 +1111,12 @@
     [].iter().exactly_one()?;
     Ok(())
 }
+
+#[test]
+fn multiunzip() {
+    let (a, b, c): (Vec<_>, Vec<_>, Vec<_>) = [(0, 1, 2), (3, 4, 5), (6, 7, 8)].iter().cloned().multiunzip();    
+    assert_eq!((a, b, c), (vec![0, 3, 6], vec![1, 4, 7], vec![2, 5, 8]));
+    let (): () = [(), (), ()].iter().cloned().multiunzip();
+    let t: (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)].iter().cloned().multiunzip();    
+    assert_eq!(t, (vec![0], vec![1], vec![2], vec![3], vec![4], vec![5], vec![6], vec![7], vec![8], vec![9], vec![10], vec![11]));
+}
\ No newline at end of file