1 use rayon::iter::plumbing::*;
2 use rayon::prelude::*;
3 
4 /// Stress-test indexes for `Producer::split_at`.
check<F, I>(expected: &[I::Item], mut f: F) where F: FnMut() -> I, I: IntoParallelIterator, I::Iter: IndexedParallelIterator, I::Item: PartialEq + std::fmt::Debug,5 fn check<F, I>(expected: &[I::Item], mut f: F)
6 where
7     F: FnMut() -> I,
8     I: IntoParallelIterator,
9     I::Iter: IndexedParallelIterator,
10     I::Item: PartialEq + std::fmt::Debug,
11 {
12     map_triples(expected.len() + 1, |i, j, k| {
13         Split::forward(f(), i, j, k, expected);
14         Split::reverse(f(), i, j, k, expected);
15     });
16 }
17 
map_triples<F>(end: usize, mut f: F) where F: FnMut(usize, usize, usize),18 fn map_triples<F>(end: usize, mut f: F)
19 where
20     F: FnMut(usize, usize, usize),
21 {
22     for i in 0..end {
23         for j in i..end {
24             for k in j..end {
25                 f(i, j, k);
26             }
27         }
28     }
29 }
30 
31 #[derive(Debug)]
32 struct Split {
33     i: usize,
34     j: usize,
35     k: usize,
36     reverse: bool,
37 }
38 
39 impl Split {
forward<I>(iter: I, i: usize, j: usize, k: usize, expected: &[I::Item]) where I: IntoParallelIterator, I::Iter: IndexedParallelIterator, I::Item: PartialEq + std::fmt::Debug,40     fn forward<I>(iter: I, i: usize, j: usize, k: usize, expected: &[I::Item])
41     where
42         I: IntoParallelIterator,
43         I::Iter: IndexedParallelIterator,
44         I::Item: PartialEq + std::fmt::Debug,
45     {
46         let result = iter.into_par_iter().with_producer(Split {
47             i,
48             j,
49             k,
50             reverse: false,
51         });
52         assert_eq!(result, expected);
53     }
54 
reverse<I>(iter: I, i: usize, j: usize, k: usize, expected: &[I::Item]) where I: IntoParallelIterator, I::Iter: IndexedParallelIterator, I::Item: PartialEq + std::fmt::Debug,55     fn reverse<I>(iter: I, i: usize, j: usize, k: usize, expected: &[I::Item])
56     where
57         I: IntoParallelIterator,
58         I::Iter: IndexedParallelIterator,
59         I::Item: PartialEq + std::fmt::Debug,
60     {
61         let result = iter.into_par_iter().with_producer(Split {
62             i,
63             j,
64             k,
65             reverse: true,
66         });
67         assert!(result.iter().eq(expected.iter().rev()));
68     }
69 }
70 
71 impl<T> ProducerCallback<T> for Split {
72     type Output = Vec<T>;
73 
callback<P>(self, producer: P) -> Self::Output where P: Producer<Item = T>,74     fn callback<P>(self, producer: P) -> Self::Output
75     where
76         P: Producer<Item = T>,
77     {
78         println!("{:?}", self);
79 
80         // Splitting the outer indexes first gets us an arbitrary mid section,
81         // which we then split further to get full test coverage.
82         let (left, d) = producer.split_at(self.k);
83         let (a, mid) = left.split_at(self.i);
84         let (b, c) = mid.split_at(self.j - self.i);
85 
86         let a = a.into_iter();
87         let b = b.into_iter();
88         let c = c.into_iter();
89         let d = d.into_iter();
90 
91         check_len(&a, self.i);
92         check_len(&b, self.j - self.i);
93         check_len(&c, self.k - self.j);
94 
95         let chain = a.chain(b).chain(c).chain(d);
96         if self.reverse {
97             chain.rev().collect()
98         } else {
99             chain.collect()
100         }
101     }
102 }
103 
check_len<I: ExactSizeIterator>(iter: &I, len: usize)104 fn check_len<I: ExactSizeIterator>(iter: &I, len: usize) {
105     assert_eq!(iter.size_hint(), (len, Some(len)));
106     assert_eq!(iter.len(), len);
107 }
108 
109 // **** Base Producers ****
110 
111 #[test]
array()112 fn array() {
113     let a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
114     check(&a, || a);
115 }
116 
117 #[test]
empty()118 fn empty() {
119     let v = vec![42];
120     check(&v[..0], rayon::iter::empty);
121 }
122 
123 #[test]
once()124 fn once() {
125     let v = vec![42];
126     check(&v, || rayon::iter::once(42));
127 }
128 
129 #[test]
option()130 fn option() {
131     let v = vec![42];
132     check(&v, || Some(42));
133 }
134 
135 #[test]
range()136 fn range() {
137     let v: Vec<_> = (0..10).collect();
138     check(&v, || 0..10);
139 }
140 
141 #[test]
range_inclusive()142 fn range_inclusive() {
143     let v: Vec<_> = (0u16..=10).collect();
144     check(&v, || 0u16..=10);
145 }
146 
147 #[test]
repeatn()148 fn repeatn() {
149     let v: Vec<_> = std::iter::repeat(1).take(5).collect();
150     check(&v, || rayon::iter::repeatn(1, 5));
151 }
152 
153 #[test]
slice_iter()154 fn slice_iter() {
155     let s: Vec<_> = (0..10).collect();
156     let v: Vec<_> = s.iter().collect();
157     check(&v, || &s);
158 }
159 
160 #[test]
slice_iter_mut()161 fn slice_iter_mut() {
162     let mut s: Vec<_> = (0..10).collect();
163     let mut v: Vec<_> = s.clone();
164     let expected: Vec<_> = v.iter_mut().collect();
165 
166     map_triples(expected.len() + 1, |i, j, k| {
167         Split::forward(s.par_iter_mut(), i, j, k, &expected);
168         Split::reverse(s.par_iter_mut(), i, j, k, &expected);
169     });
170 }
171 
172 #[test]
slice_chunks()173 fn slice_chunks() {
174     let s: Vec<_> = (0..10).collect();
175     for len in 1..s.len() + 2 {
176         let v: Vec<_> = s.chunks(len).collect();
177         check(&v, || s.par_chunks(len));
178     }
179 }
180 
181 #[test]
slice_chunks_exact()182 fn slice_chunks_exact() {
183     let s: Vec<_> = (0..10).collect();
184     for len in 1..s.len() + 2 {
185         let v: Vec<_> = s.chunks_exact(len).collect();
186         check(&v, || s.par_chunks_exact(len));
187     }
188 }
189 
190 #[test]
slice_chunks_mut()191 fn slice_chunks_mut() {
192     let mut s: Vec<_> = (0..10).collect();
193     let mut v: Vec<_> = s.clone();
194     for len in 1..s.len() + 2 {
195         let expected: Vec<_> = v.chunks_mut(len).collect();
196         map_triples(expected.len() + 1, |i, j, k| {
197             Split::forward(s.par_chunks_mut(len), i, j, k, &expected);
198             Split::reverse(s.par_chunks_mut(len), i, j, k, &expected);
199         });
200     }
201 }
202 
203 #[test]
slice_chunks_exact_mut()204 fn slice_chunks_exact_mut() {
205     let mut s: Vec<_> = (0..10).collect();
206     let mut v: Vec<_> = s.clone();
207     for len in 1..s.len() + 2 {
208         let expected: Vec<_> = v.chunks_exact_mut(len).collect();
209         map_triples(expected.len() + 1, |i, j, k| {
210             Split::forward(s.par_chunks_exact_mut(len), i, j, k, &expected);
211             Split::reverse(s.par_chunks_exact_mut(len), i, j, k, &expected);
212         });
213     }
214 }
215 
216 #[test]
slice_rchunks()217 fn slice_rchunks() {
218     let s: Vec<_> = (0..10).collect();
219     for len in 1..s.len() + 2 {
220         let v: Vec<_> = s.rchunks(len).collect();
221         check(&v, || s.par_rchunks(len));
222     }
223 }
224 
225 #[test]
slice_rchunks_exact()226 fn slice_rchunks_exact() {
227     let s: Vec<_> = (0..10).collect();
228     for len in 1..s.len() + 2 {
229         let v: Vec<_> = s.rchunks_exact(len).collect();
230         check(&v, || s.par_rchunks_exact(len));
231     }
232 }
233 
234 #[test]
slice_rchunks_mut()235 fn slice_rchunks_mut() {
236     let mut s: Vec<_> = (0..10).collect();
237     let mut v: Vec<_> = s.clone();
238     for len in 1..s.len() + 2 {
239         let expected: Vec<_> = v.rchunks_mut(len).collect();
240         map_triples(expected.len() + 1, |i, j, k| {
241             Split::forward(s.par_rchunks_mut(len), i, j, k, &expected);
242             Split::reverse(s.par_rchunks_mut(len), i, j, k, &expected);
243         });
244     }
245 }
246 
247 #[test]
slice_rchunks_exact_mut()248 fn slice_rchunks_exact_mut() {
249     let mut s: Vec<_> = (0..10).collect();
250     let mut v: Vec<_> = s.clone();
251     for len in 1..s.len() + 2 {
252         let expected: Vec<_> = v.rchunks_exact_mut(len).collect();
253         map_triples(expected.len() + 1, |i, j, k| {
254             Split::forward(s.par_rchunks_exact_mut(len), i, j, k, &expected);
255             Split::reverse(s.par_rchunks_exact_mut(len), i, j, k, &expected);
256         });
257     }
258 }
259 
260 #[test]
slice_windows()261 fn slice_windows() {
262     let s: Vec<_> = (0..10).collect();
263     let v: Vec<_> = s.windows(2).collect();
264     check(&v, || s.par_windows(2));
265 }
266 
267 #[test]
vec()268 fn vec() {
269     let v: Vec<_> = (0..10).collect();
270     check(&v, || v.clone());
271 }
272 
273 // **** Adaptors ****
274 
275 #[test]
chain()276 fn chain() {
277     let v: Vec<_> = (0..10).collect();
278     check(&v, || (0..5).into_par_iter().chain(5..10));
279 }
280 
281 #[test]
cloned()282 fn cloned() {
283     let v: Vec<_> = (0..10).collect();
284     check(&v, || v.par_iter().cloned());
285 }
286 
287 #[test]
copied()288 fn copied() {
289     let v: Vec<_> = (0..10).collect();
290     check(&v, || v.par_iter().copied());
291 }
292 
293 #[test]
enumerate()294 fn enumerate() {
295     let v: Vec<_> = (0..10).enumerate().collect();
296     check(&v, || (0..10).into_par_iter().enumerate());
297 }
298 
299 #[test]
step_by()300 fn step_by() {
301     let v: Vec<_> = (0..10).step_by(2).collect();
302     check(&v, || (0..10).into_par_iter().step_by(2))
303 }
304 
305 #[test]
step_by_unaligned()306 fn step_by_unaligned() {
307     let v: Vec<_> = (0..10).step_by(3).collect();
308     check(&v, || (0..10).into_par_iter().step_by(3))
309 }
310 
311 #[test]
inspect()312 fn inspect() {
313     let v: Vec<_> = (0..10).collect();
314     check(&v, || (0..10).into_par_iter().inspect(|_| ()));
315 }
316 
317 #[test]
update()318 fn update() {
319     let v: Vec<_> = (0..10).collect();
320     check(&v, || (0..10).into_par_iter().update(|_| ()));
321 }
322 
323 #[test]
interleave()324 fn interleave() {
325     let v = [0, 10, 1, 11, 2, 12, 3, 4];
326     check(&v, || (0..5).into_par_iter().interleave(10..13));
327     check(&v[..6], || (0..3).into_par_iter().interleave(10..13));
328 
329     let v = [0, 10, 1, 11, 2, 12, 13, 14];
330     check(&v, || (0..3).into_par_iter().interleave(10..15));
331 }
332 
333 #[test]
intersperse()334 fn intersperse() {
335     let v = [0, -1, 1, -1, 2, -1, 3, -1, 4];
336     check(&v, || (0..5).into_par_iter().intersperse(-1));
337 }
338 
339 #[test]
chunks()340 fn chunks() {
341     let s: Vec<_> = (0..10).collect();
342     let v: Vec<_> = s.chunks(2).map(|c| c.to_vec()).collect();
343     check(&v, || s.par_iter().cloned().chunks(2));
344 }
345 
346 #[test]
map()347 fn map() {
348     let v: Vec<_> = (0..10).collect();
349     check(&v, || v.par_iter().map(Clone::clone));
350 }
351 
352 #[test]
map_with()353 fn map_with() {
354     let v: Vec<_> = (0..10).collect();
355     check(&v, || v.par_iter().map_with(vec![0], |_, &x| x));
356 }
357 
358 #[test]
map_init()359 fn map_init() {
360     let v: Vec<_> = (0..10).collect();
361     check(&v, || v.par_iter().map_init(|| vec![0], |_, &x| x));
362 }
363 
364 #[test]
panic_fuse()365 fn panic_fuse() {
366     let v: Vec<_> = (0..10).collect();
367     check(&v, || (0..10).into_par_iter().panic_fuse());
368 }
369 
370 #[test]
rev()371 fn rev() {
372     let v: Vec<_> = (0..10).rev().collect();
373     check(&v, || (0..10).into_par_iter().rev());
374 }
375 
376 #[test]
with_max_len()377 fn with_max_len() {
378     let v: Vec<_> = (0..10).collect();
379     check(&v, || (0..10).into_par_iter().with_max_len(1));
380 }
381 
382 #[test]
with_min_len()383 fn with_min_len() {
384     let v: Vec<_> = (0..10).collect();
385     check(&v, || (0..10).into_par_iter().with_min_len(1));
386 }
387 
388 #[test]
zip()389 fn zip() {
390     let v: Vec<_> = (0..10).zip(10..20).collect();
391     check(&v, || (0..10).into_par_iter().zip(10..20));
392     check(&v[..5], || (0..5).into_par_iter().zip(10..20));
393     check(&v[..5], || (0..10).into_par_iter().zip(10..15));
394 }
395