]>
Commit | Line | Data |
---|---|---|
2c00a5a8 | 1 | use rayon::iter::plumbing::*; |
532ac7d7 | 2 | use rayon::prelude::*; |
2c00a5a8 XL |
3 | |
4 | /// Stress-test indexes for `Producer::split_at`. | |
5 | fn check<F, I>(expected: &[I::Item], mut f: F) | |
532ac7d7 XL |
6 | where |
7 | F: FnMut() -> I, | |
8 | I: IntoParallelIterator, | |
9 | I::Iter: IndexedParallelIterator, | |
10 | I::Item: PartialEq + std::fmt::Debug, | |
2c00a5a8 | 11 | { |
532ac7d7 | 12 | map_triples(expected.len() + 1, |i, j, k| { |
2c00a5a8 XL |
13 | Split::forward(f(), i, j, k, expected); |
14 | Split::reverse(f(), i, j, k, expected); | |
532ac7d7 | 15 | }); |
2c00a5a8 XL |
16 | } |
17 | ||
532ac7d7 XL |
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 | } | |
2c00a5a8 XL |
29 | } |
30 | ||
31 | #[derive(Debug)] | |
32 | struct Split { | |
33 | i: usize, | |
34 | j: usize, | |
35 | k: usize, | |
532ac7d7 | 36 | reverse: bool, |
2c00a5a8 XL |
37 | } |
38 | ||
39 | impl Split { | |
40 | fn forward<I>(iter: I, i: usize, j: usize, k: usize, expected: &[I::Item]) | |
532ac7d7 XL |
41 | where |
42 | I: IntoParallelIterator, | |
43 | I::Iter: IndexedParallelIterator, | |
44 | I::Item: PartialEq + std::fmt::Debug, | |
2c00a5a8 | 45 | { |
532ac7d7 XL |
46 | let result = iter.into_par_iter().with_producer(Split { |
47 | i, | |
48 | j, | |
49 | k, | |
50 | reverse: false, | |
51 | }); | |
2c00a5a8 XL |
52 | assert_eq!(result, expected); |
53 | } | |
54 | ||
55 | fn reverse<I>(iter: I, i: usize, j: usize, k: usize, expected: &[I::Item]) | |
532ac7d7 XL |
56 | where |
57 | I: IntoParallelIterator, | |
58 | I::Iter: IndexedParallelIterator, | |
59 | I::Item: PartialEq + std::fmt::Debug, | |
2c00a5a8 | 60 | { |
532ac7d7 XL |
61 | let result = iter.into_par_iter().with_producer(Split { |
62 | i, | |
63 | j, | |
64 | k, | |
65 | reverse: true, | |
66 | }); | |
2c00a5a8 XL |
67 | assert!(result.iter().eq(expected.iter().rev())); |
68 | } | |
69 | } | |
70 | ||
71 | impl<T> ProducerCallback<T> for Split { | |
72 | type Output = Vec<T>; | |
73 | ||
74 | fn callback<P>(self, producer: P) -> Self::Output | |
532ac7d7 XL |
75 | where |
76 | P: Producer<Item = T>, | |
2c00a5a8 XL |
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 | ||
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 | ||
2c00a5a8 XL |
109 | // **** Base Producers **** |
110 | ||
923072b8 FG |
111 | #[test] |
112 | fn array() { | |
113 | let a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; | |
114 | check(&a, || a); | |
115 | } | |
116 | ||
2c00a5a8 XL |
117 | #[test] |
118 | fn empty() { | |
119 | let v = vec![42]; | |
e74abb32 | 120 | check(&v[..0], rayon::iter::empty); |
2c00a5a8 XL |
121 | } |
122 | ||
123 | #[test] | |
124 | fn once() { | |
125 | let v = vec![42]; | |
126 | check(&v, || rayon::iter::once(42)); | |
127 | } | |
128 | ||
129 | #[test] | |
130 | fn option() { | |
131 | let v = vec![42]; | |
132 | check(&v, || Some(42)); | |
133 | } | |
134 | ||
135 | #[test] | |
136 | fn range() { | |
137 | let v: Vec<_> = (0..10).collect(); | |
138 | check(&v, || 0..10); | |
139 | } | |
140 | ||
e74abb32 XL |
141 | #[test] |
142 | fn range_inclusive() { | |
143 | let v: Vec<_> = (0u16..=10).collect(); | |
144 | check(&v, || 0u16..=10); | |
145 | } | |
146 | ||
2c00a5a8 XL |
147 | #[test] |
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] | |
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] | |
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 | ||
532ac7d7 | 166 | map_triples(expected.len() + 1, |i, j, k| { |
2c00a5a8 XL |
167 | Split::forward(s.par_iter_mut(), i, j, k, &expected); |
168 | Split::reverse(s.par_iter_mut(), i, j, k, &expected); | |
532ac7d7 | 169 | }); |
2c00a5a8 XL |
170 | } |
171 | ||
172 | #[test] | |
173 | fn slice_chunks() { | |
174 | let s: Vec<_> = (0..10).collect(); | |
532ac7d7 XL |
175 | for len in 1..s.len() + 2 { |
176 | let v: Vec<_> = s.chunks(len).collect(); | |
177 | check(&v, || s.par_chunks(len)); | |
178 | } | |
2c00a5a8 XL |
179 | } |
180 | ||
923072b8 FG |
181 | #[test] |
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 | ||
2c00a5a8 XL |
190 | #[test] |
191 | fn slice_chunks_mut() { | |
192 | let mut s: Vec<_> = (0..10).collect(); | |
193 | let mut v: Vec<_> = s.clone(); | |
532ac7d7 XL |
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 | }); | |
2c00a5a8 XL |
200 | } |
201 | } | |
202 | ||
923072b8 FG |
203 | #[test] |
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] | |
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] | |
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] | |
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] | |
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 | ||
2c00a5a8 XL |
260 | #[test] |
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] | |
268 | fn vec() { | |
269 | let v: Vec<_> = (0..10).collect(); | |
270 | check(&v, || v.clone()); | |
271 | } | |
272 | ||
2c00a5a8 XL |
273 | // **** Adaptors **** |
274 | ||
275 | #[test] | |
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] | |
282 | fn cloned() { | |
283 | let v: Vec<_> = (0..10).collect(); | |
284 | check(&v, || v.par_iter().cloned()); | |
285 | } | |
286 | ||
e74abb32 XL |
287 | #[test] |
288 | fn copied() { | |
289 | let v: Vec<_> = (0..10).collect(); | |
290 | check(&v, || v.par_iter().copied()); | |
291 | } | |
292 | ||
2c00a5a8 XL |
293 | #[test] |
294 | fn enumerate() { | |
295 | let v: Vec<_> = (0..10).enumerate().collect(); | |
296 | check(&v, || (0..10).into_par_iter().enumerate()); | |
297 | } | |
298 | ||
923072b8 FG |
299 | #[test] |
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] | |
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 | ||
2c00a5a8 XL |
311 | #[test] |
312 | fn inspect() { | |
313 | let v: Vec<_> = (0..10).collect(); | |
314 | check(&v, || (0..10).into_par_iter().inspect(|_| ())); | |
315 | } | |
316 | ||
317 | #[test] | |
318 | fn update() { | |
319 | let v: Vec<_> = (0..10).collect(); | |
320 | check(&v, || (0..10).into_par_iter().update(|_| ())); | |
321 | } | |
322 | ||
323 | #[test] | |
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] | |
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] | |
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] | |
347 | fn map() { | |
348 | let v: Vec<_> = (0..10).collect(); | |
349 | check(&v, || v.par_iter().map(Clone::clone)); | |
350 | } | |
351 | ||
352 | #[test] | |
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 | ||
532ac7d7 XL |
358 | #[test] |
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 | ||
e74abb32 XL |
364 | #[test] |
365 | fn panic_fuse() { | |
366 | let v: Vec<_> = (0..10).collect(); | |
367 | check(&v, || (0..10).into_par_iter().panic_fuse()); | |
368 | } | |
369 | ||
2c00a5a8 XL |
370 | #[test] |
371 | fn rev() { | |
372 | let v: Vec<_> = (0..10).rev().collect(); | |
373 | check(&v, || (0..10).into_par_iter().rev()); | |
374 | } | |
375 | ||
376 | #[test] | |
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] | |
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] | |
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 | } |