1 use itertools::Itertools;
2 use std::fmt::Debug;
3 use quickcheck::quickcheck;
4
5 struct Unspecialized<I>(I);
6 impl<I> Iterator for Unspecialized<I>
7 where
8 I: Iterator,
9 {
10 type Item = I::Item;
11
12 #[inline(always)]
next(&mut self) -> Option<Self::Item>13 fn next(&mut self) -> Option<Self::Item> {
14 self.0.next()
15 }
16 }
17
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,18 fn check_specialized<'a, V, IterItem, Iter, F>(iterator: &Iter, mapper: F)
19 where
20 V: Eq + Debug,
21 Iter: Iterator<Item = IterItem> + Clone + 'a,
22 F: Fn(Box<dyn Iterator<Item = IterItem> + 'a>) -> V,
23 {
24 assert_eq!(
25 mapper(Box::new(Unspecialized(iterator.clone()))),
26 mapper(Box::new(iterator.clone()))
27 )
28 }
29
test_specializations<IterItem, Iter>( it: &Iter, ) where IterItem: Eq + Debug + Clone, Iter: Iterator<Item = IterItem> + Clone,30 fn test_specializations<IterItem, Iter>(
31 it: &Iter,
32 ) where
33 IterItem: Eq + Debug + Clone,
34 Iter: Iterator<Item = IterItem> + Clone,
35 {
36 check_specialized(it, |i| i.count());
37 check_specialized(it, |i| i.last());
38 check_specialized(it, |i| i.collect::<Vec<_>>());
39 check_specialized(it, |i| {
40 let mut parameters_from_fold = vec![];
41 let fold_result = i.fold(vec![], |mut acc, v: IterItem| {
42 parameters_from_fold.push((acc.clone(), v.clone()));
43 acc.push(v);
44 acc
45 });
46 (parameters_from_fold, fold_result)
47 });
48 check_specialized(it, |mut i| {
49 let mut parameters_from_all = vec![];
50 let first = i.next();
51 let all_result = i.all(|x| {
52 parameters_from_all.push(x.clone());
53 Some(x)==first
54 });
55 (parameters_from_all, all_result)
56 });
57 let size = it.clone().count();
58 for n in 0..size + 2 {
59 check_specialized(it, |mut i| i.nth(n));
60 }
61 // size_hint is a bit harder to check
62 let mut it_sh = it.clone();
63 for n in 0..size + 2 {
64 let len = it_sh.clone().count();
65 let (min, max) = it_sh.size_hint();
66 assert_eq!(size - n.min(size), len);
67 assert!(min <= len);
68 if let Some(max) = max {
69 assert!(len <= max);
70 }
71 it_sh.next();
72 }
73 }
74
75 quickcheck! {
76 fn put_back_qc(test_vec: Vec<i32>) -> () {
77 test_specializations(&itertools::put_back(test_vec.iter()));
78 let mut pb = itertools::put_back(test_vec.into_iter());
79 pb.put_back(1);
80 test_specializations(&pb);
81 }
82 }
83
84 quickcheck! {
85 fn merge_join_by_qc(i1: Vec<usize>, i2: Vec<usize>) -> () {
86 test_specializations(&i1.into_iter().merge_join_by(i2.into_iter(), std::cmp::Ord::cmp));
87 }
88 }
89
90 quickcheck! {
91 fn map_into(v: Vec<u8>) -> () {
92 test_specializations(&v.into_iter().map_into::<u32>());
93 }
94 }
95
96 quickcheck! {
97 fn map_ok(v: Vec<Result<u8, char>>) -> () {
98 test_specializations(&v.into_iter().map_ok(|u| u.checked_add(1)));
99 }
100 }
101