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 check(&[], rayon::iter::empty::<i32>);
120 }
121
122 #[test]
once()123 fn once() {
124 check(&[42], || rayon::iter::once(42));
125 }
126
127 #[test]
option()128 fn option() {
129 check(&[42], || Some(42));
130 }
131
132 #[test]
range()133 fn range() {
134 let v: Vec<_> = (0..10).collect();
135 check(&v, || 0..10);
136 }
137
138 #[test]
range_inclusive()139 fn range_inclusive() {
140 let v: Vec<_> = (0u16..=10).collect();
141 check(&v, || 0u16..=10);
142 }
143
144 #[test]
repeatn()145 fn repeatn() {
146 let v: Vec<_> = std::iter::repeat(1).take(5).collect();
147 check(&v, || rayon::iter::repeatn(1, 5));
148 }
149
150 #[test]
slice_iter()151 fn slice_iter() {
152 let s: Vec<_> = (0..10).collect();
153 let v: Vec<_> = s.iter().collect();
154 check(&v, || &s);
155 }
156
157 #[test]
slice_iter_mut()158 fn slice_iter_mut() {
159 let mut s: Vec<_> = (0..10).collect();
160 let mut v: Vec<_> = s.clone();
161 let expected: Vec<_> = v.iter_mut().collect();
162
163 map_triples(expected.len() + 1, |i, j, k| {
164 Split::forward(s.par_iter_mut(), i, j, k, &expected);
165 Split::reverse(s.par_iter_mut(), i, j, k, &expected);
166 });
167 }
168
169 #[test]
slice_chunks()170 fn slice_chunks() {
171 let s: Vec<_> = (0..10).collect();
172 for len in 1..s.len() + 2 {
173 let v: Vec<_> = s.chunks(len).collect();
174 check(&v, || s.par_chunks(len));
175 }
176 }
177
178 #[test]
slice_chunks_exact()179 fn slice_chunks_exact() {
180 let s: Vec<_> = (0..10).collect();
181 for len in 1..s.len() + 2 {
182 let v: Vec<_> = s.chunks_exact(len).collect();
183 check(&v, || s.par_chunks_exact(len));
184 }
185 }
186
187 #[test]
slice_chunks_mut()188 fn slice_chunks_mut() {
189 let mut s: Vec<_> = (0..10).collect();
190 let mut v: Vec<_> = s.clone();
191 for len in 1..s.len() + 2 {
192 let expected: Vec<_> = v.chunks_mut(len).collect();
193 map_triples(expected.len() + 1, |i, j, k| {
194 Split::forward(s.par_chunks_mut(len), i, j, k, &expected);
195 Split::reverse(s.par_chunks_mut(len), i, j, k, &expected);
196 });
197 }
198 }
199
200 #[test]
slice_chunks_exact_mut()201 fn slice_chunks_exact_mut() {
202 let mut s: Vec<_> = (0..10).collect();
203 let mut v: Vec<_> = s.clone();
204 for len in 1..s.len() + 2 {
205 let expected: Vec<_> = v.chunks_exact_mut(len).collect();
206 map_triples(expected.len() + 1, |i, j, k| {
207 Split::forward(s.par_chunks_exact_mut(len), i, j, k, &expected);
208 Split::reverse(s.par_chunks_exact_mut(len), i, j, k, &expected);
209 });
210 }
211 }
212
213 #[test]
slice_rchunks()214 fn slice_rchunks() {
215 let s: Vec<_> = (0..10).collect();
216 for len in 1..s.len() + 2 {
217 let v: Vec<_> = s.rchunks(len).collect();
218 check(&v, || s.par_rchunks(len));
219 }
220 }
221
222 #[test]
slice_rchunks_exact()223 fn slice_rchunks_exact() {
224 let s: Vec<_> = (0..10).collect();
225 for len in 1..s.len() + 2 {
226 let v: Vec<_> = s.rchunks_exact(len).collect();
227 check(&v, || s.par_rchunks_exact(len));
228 }
229 }
230
231 #[test]
slice_rchunks_mut()232 fn slice_rchunks_mut() {
233 let mut s: Vec<_> = (0..10).collect();
234 let mut v: Vec<_> = s.clone();
235 for len in 1..s.len() + 2 {
236 let expected: Vec<_> = v.rchunks_mut(len).collect();
237 map_triples(expected.len() + 1, |i, j, k| {
238 Split::forward(s.par_rchunks_mut(len), i, j, k, &expected);
239 Split::reverse(s.par_rchunks_mut(len), i, j, k, &expected);
240 });
241 }
242 }
243
244 #[test]
slice_rchunks_exact_mut()245 fn slice_rchunks_exact_mut() {
246 let mut s: Vec<_> = (0..10).collect();
247 let mut v: Vec<_> = s.clone();
248 for len in 1..s.len() + 2 {
249 let expected: Vec<_> = v.rchunks_exact_mut(len).collect();
250 map_triples(expected.len() + 1, |i, j, k| {
251 Split::forward(s.par_rchunks_exact_mut(len), i, j, k, &expected);
252 Split::reverse(s.par_rchunks_exact_mut(len), i, j, k, &expected);
253 });
254 }
255 }
256
257 #[test]
slice_windows()258 fn slice_windows() {
259 let s: Vec<_> = (0..10).collect();
260 let v: Vec<_> = s.windows(2).collect();
261 check(&v, || s.par_windows(2));
262 }
263
264 #[test]
vec()265 fn vec() {
266 let v: Vec<_> = (0..10).collect();
267 check(&v, || v.clone());
268 }
269
270 // **** Adaptors ****
271
272 #[test]
chain()273 fn chain() {
274 let v: Vec<_> = (0..10).collect();
275 check(&v, || (0..5).into_par_iter().chain(5..10));
276 }
277
278 #[test]
cloned()279 fn cloned() {
280 let v: Vec<_> = (0..10).collect();
281 check(&v, || v.par_iter().cloned());
282 }
283
284 #[test]
copied()285 fn copied() {
286 let v: Vec<_> = (0..10).collect();
287 check(&v, || v.par_iter().copied());
288 }
289
290 #[test]
enumerate()291 fn enumerate() {
292 let v: Vec<_> = (0..10).enumerate().collect();
293 check(&v, || (0..10).into_par_iter().enumerate());
294 }
295
296 #[test]
step_by()297 fn step_by() {
298 let v: Vec<_> = (0..10).step_by(2).collect();
299 check(&v, || (0..10).into_par_iter().step_by(2))
300 }
301
302 #[test]
step_by_unaligned()303 fn step_by_unaligned() {
304 let v: Vec<_> = (0..10).step_by(3).collect();
305 check(&v, || (0..10).into_par_iter().step_by(3))
306 }
307
308 #[test]
inspect()309 fn inspect() {
310 let v: Vec<_> = (0..10).collect();
311 check(&v, || (0..10).into_par_iter().inspect(|_| ()));
312 }
313
314 #[test]
update()315 fn update() {
316 let v: Vec<_> = (0..10).collect();
317 check(&v, || (0..10).into_par_iter().update(|_| ()));
318 }
319
320 #[test]
interleave()321 fn interleave() {
322 let v = [0, 10, 1, 11, 2, 12, 3, 4];
323 check(&v, || (0..5).into_par_iter().interleave(10..13));
324 check(&v[..6], || (0..3).into_par_iter().interleave(10..13));
325
326 let v = [0, 10, 1, 11, 2, 12, 13, 14];
327 check(&v, || (0..3).into_par_iter().interleave(10..15));
328 }
329
330 #[test]
intersperse()331 fn intersperse() {
332 let v = [0, -1, 1, -1, 2, -1, 3, -1, 4];
333 check(&v, || (0..5).into_par_iter().intersperse(-1));
334 }
335
336 #[test]
chunks()337 fn chunks() {
338 let s: Vec<_> = (0..10).collect();
339 let v: Vec<_> = s.chunks(2).map(|c| c.to_vec()).collect();
340 check(&v, || s.par_iter().cloned().chunks(2));
341 }
342
343 #[test]
map()344 fn map() {
345 let v: Vec<_> = (0..10).collect();
346 check(&v, || v.par_iter().map(Clone::clone));
347 }
348
349 #[test]
map_with()350 fn map_with() {
351 let v: Vec<_> = (0..10).collect();
352 check(&v, || v.par_iter().map_with(vec![0], |_, &x| x));
353 }
354
355 #[test]
map_init()356 fn map_init() {
357 let v: Vec<_> = (0..10).collect();
358 check(&v, || v.par_iter().map_init(|| vec![0], |_, &x| x));
359 }
360
361 #[test]
panic_fuse()362 fn panic_fuse() {
363 let v: Vec<_> = (0..10).collect();
364 check(&v, || (0..10).into_par_iter().panic_fuse());
365 }
366
367 #[test]
rev()368 fn rev() {
369 let v: Vec<_> = (0..10).rev().collect();
370 check(&v, || (0..10).into_par_iter().rev());
371 }
372
373 #[test]
with_max_len()374 fn with_max_len() {
375 let v: Vec<_> = (0..10).collect();
376 check(&v, || (0..10).into_par_iter().with_max_len(1));
377 }
378
379 #[test]
with_min_len()380 fn with_min_len() {
381 let v: Vec<_> = (0..10).collect();
382 check(&v, || (0..10).into_par_iter().with_min_len(1));
383 }
384
385 #[test]
zip()386 fn zip() {
387 let v: Vec<_> = (0..10).zip(10..20).collect();
388 check(&v, || (0..10).into_par_iter().zip(10..20));
389 check(&v[..5], || (0..5).into_par_iter().zip(10..20));
390 check(&v[..5], || (0..10).into_par_iter().zip(10..15));
391 }
392