blob: 199cf562aae3b00e16edff68108bbbb0ff9580b8 [file] [log] [blame]
Joel Galenson6f798712021-04-01 17:03:06 -07001use itertools::Itertools;
Jakub Kotura425e552020-12-21 17:28:15 +01002use std::fmt::Debug;
Jakub Kotura425e552020-12-21 17:28:15 +01003use quickcheck::quickcheck;
4
5struct Unspecialized<I>(I);
6impl<I> Iterator for Unspecialized<I>
7where
8 I: Iterator,
9{
10 type Item = I::Item;
11
12 #[inline(always)]
Joel Galenson6f798712021-04-01 17:03:06 -070013 fn next(&mut self) -> Option<Self::Item> {
Jakub Kotura425e552020-12-21 17:28:15 +010014 self.0.next()
15 }
Jakub Kotura425e552020-12-21 17:28:15 +010016}
17
David LeGareb72e9052022-03-02 16:21:08 +000018macro_rules! check_specialized {
19 ($src:expr, |$it:pat| $closure:expr) => {
20 let $it = $src.clone();
21 let v1 = $closure;
22
23 let $it = Unspecialized($src.clone());
24 let v2 = $closure;
25
26 assert_eq!(v1, v2);
27 }
Jakub Kotura425e552020-12-21 17:28:15 +010028}
29
Joel Galenson6f798712021-04-01 17:03:06 -070030fn test_specializations<IterItem, Iter>(
Jakub Kotura425e552020-12-21 17:28:15 +010031 it: &Iter,
Jakub Kotura425e552020-12-21 17:28:15 +010032) where
Joel Galenson6f798712021-04-01 17:03:06 -070033 IterItem: Eq + Debug + Clone,
34 Iter: Iterator<Item = IterItem> + Clone,
Jakub Kotura425e552020-12-21 17:28:15 +010035{
David LeGareb72e9052022-03-02 16:21:08 +000036 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| {
Joel Galenson6f798712021-04-01 17:03:06 -070040 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 });
David LeGareb72e9052022-03-02 16:21:08 +000048 check_specialized!(it, |mut i| {
Joel Galenson6f798712021-04-01 17:03:06 -070049 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();
Jakub Kotura425e552020-12-21 17:28:15 +010058 for n in 0..size + 2 {
David LeGareb72e9052022-03-02 16:21:08 +000059 check_specialized!(it, |mut i| i.nth(n));
Jakub Kotura425e552020-12-21 17:28:15 +010060 }
Joel Galenson6f798712021-04-01 17:03:06 -070061 // size_hint is a bit harder to check
Jakub Kotura425e552020-12-21 17:28:15 +010062 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();
Joel Galenson6f798712021-04-01 17:03:06 -070066 assert_eq!(size - n.min(size), len);
Jakub Kotura425e552020-12-21 17:28:15 +010067 assert!(min <= len);
68 if let Some(max) = max {
69 assert!(len <= max);
70 }
71 it_sh.next();
72 }
73}
74
Jakub Kotura425e552020-12-21 17:28:15 +010075quickcheck! {
David LeGareb72e9052022-03-02 16:21:08 +000076 fn intersperse(v: Vec<u8>) -> () {
77 test_specializations(&v.into_iter().intersperse(0));
78 }
79}
80
81quickcheck! {
Jakub Kotura425e552020-12-21 17:28:15 +010082 fn put_back_qc(test_vec: Vec<i32>) -> () {
Joel Galenson6f798712021-04-01 17:03:06 -070083 test_specializations(&itertools::put_back(test_vec.iter()));
84 let mut pb = itertools::put_back(test_vec.into_iter());
85 pb.put_back(1);
86 test_specializations(&pb);
Jakub Kotura425e552020-12-21 17:28:15 +010087 }
88}
89
Jakub Kotura425e552020-12-21 17:28:15 +010090quickcheck! {
91 fn merge_join_by_qc(i1: Vec<usize>, i2: Vec<usize>) -> () {
Joel Galenson6f798712021-04-01 17:03:06 -070092 test_specializations(&i1.into_iter().merge_join_by(i2.into_iter(), std::cmp::Ord::cmp));
93 }
94}
95
96quickcheck! {
97 fn map_into(v: Vec<u8>) -> () {
98 test_specializations(&v.into_iter().map_into::<u32>());
99 }
100}
101
102quickcheck! {
103 fn map_ok(v: Vec<Result<u8, char>>) -> () {
104 test_specializations(&v.into_iter().map_ok(|u| u.checked_add(1)));
Jakub Kotura425e552020-12-21 17:28:15 +0100105 }
106}
David LeGareb72e9052022-03-02 16:21:08 +0000107
108quickcheck! {
109 fn process_results(v: Vec<Result<u8, u8>>) -> () {
110 helper(v.iter().copied());
111 helper(v.iter().copied().filter(Result::is_ok));
112
113 fn helper(it: impl Iterator<Item = Result<u8, u8>> + Clone) {
114 macro_rules! check_results_specialized {
115 ($src:expr, |$it:pat| $closure:expr) => {
116 assert_eq!(
117 itertools::process_results($src.clone(), |$it| $closure),
118 itertools::process_results($src.clone(), |i| {
119 let $it = Unspecialized(i);
120 $closure
121 }),
122 )
123 }
124 }
125
126 check_results_specialized!(it, |i| i.count());
127 check_results_specialized!(it, |i| i.last());
128 check_results_specialized!(it, |i| i.collect::<Vec<_>>());
129 check_results_specialized!(it, |i| {
130 let mut parameters_from_fold = vec![];
131 let fold_result = i.fold(vec![], |mut acc, v| {
132 parameters_from_fold.push((acc.clone(), v.clone()));
133 acc.push(v);
134 acc
135 });
136 (parameters_from_fold, fold_result)
137 });
138 check_results_specialized!(it, |mut i| {
139 let mut parameters_from_all = vec![];
140 let first = i.next();
141 let all_result = i.all(|x| {
142 parameters_from_all.push(x.clone());
143 Some(x)==first
144 });
145 (parameters_from_all, all_result)
146 });
147 let size = it.clone().count();
148 for n in 0..size + 2 {
149 check_results_specialized!(it, |mut i| i.nth(n));
150 }
151 }
152 }
153}