@@ -24,7 +24,7 @@ trait UnzipOp<T>: Sync + Send {
24
24
}
25
25
}
26
26
27
- /// Run an unzip-like operation into `ParallelExtend` collections.
27
+ /// Run an unzip-like operation into default `ParallelExtend` collections.
28
28
fn execute < I , OP , FromA , FromB > ( pi : I , op : OP ) -> ( FromA , FromB )
29
29
where I : ParallelIterator ,
30
30
OP : UnzipOp < I :: Item > ,
@@ -33,21 +33,30 @@ fn execute<I, OP, FromA, FromB>(pi: I, op: OP) -> (FromA, FromB)
33
33
{
34
34
let mut a = FromA :: default ( ) ;
35
35
let mut b = FromB :: default ( ) ;
36
- {
37
- // We have no idea what the consumers will look like for these
38
- // collections' `par_extend`, but we can intercept them in our own
39
- // `drive_unindexed`. Start with the left side, type `A`:
40
- let iter = UnzipA {
41
- base : pi,
42
- op : op,
43
- b : & mut b,
44
- } ;
45
- a. par_extend ( iter) ;
46
- }
36
+ execute_into ( & mut a, & mut b, pi, op) ;
47
37
( a, b)
48
38
}
49
39
50
40
41
+ /// Run an unzip-like operation into `ParallelExtend` collections.
42
+ fn execute_into < I , OP , FromA , FromB > ( a : & mut FromA , b : & mut FromB , pi : I , op : OP )
43
+ where I : ParallelIterator ,
44
+ OP : UnzipOp < I :: Item > ,
45
+ FromA : Send + ParallelExtend < OP :: Left > ,
46
+ FromB : Send + ParallelExtend < OP :: Right >
47
+ {
48
+ // We have no idea what the consumers will look like for these
49
+ // collections' `par_extend`, but we can intercept them in our own
50
+ // `drive_unindexed`. Start with the left side, type `A`:
51
+ let iter = UnzipA {
52
+ base : pi,
53
+ op : op,
54
+ b : b,
55
+ } ;
56
+ a. par_extend ( iter) ;
57
+ }
58
+
59
+
51
60
/// Unzips the items of a parallel iterator into a pair of arbitrary
52
61
/// `ParallelExtend` containers.
53
62
///
@@ -188,7 +197,7 @@ struct UnzipA<'b, I, OP, FromB: 'b> {
188
197
impl < ' b , I , OP , FromB > ParallelIterator for UnzipA < ' b , I , OP , FromB >
189
198
where I : ParallelIterator ,
190
199
OP : UnzipOp < I :: Item > ,
191
- FromB : Default + Send + ParallelExtend < OP :: Right >
200
+ FromB : Send + ParallelExtend < OP :: Right >
192
201
{
193
202
type Item = OP :: Left ;
194
203
@@ -386,3 +395,57 @@ impl<A, B, RA, RB> Reducer<(A, B)> for UnzipReducer<RA, RB>
386
395
( self . left . reduce ( left. 0 , right. 0 ) , self . right . reduce ( left. 1 , right. 1 ) )
387
396
}
388
397
}
398
+
399
+
400
+ impl < A , B , FromA , FromB > ParallelExtend < ( A , B ) > for ( FromA , FromB )
401
+ where
402
+ A : Send ,
403
+ B : Send ,
404
+ FromA : Send + ParallelExtend < A > ,
405
+ FromB : Send + ParallelExtend < B > ,
406
+ {
407
+ fn par_extend < I > ( & mut self , pi : I )
408
+ where
409
+ I : IntoParallelIterator < Item = ( A , B ) > ,
410
+ {
411
+ execute_into ( & mut self . 0 , & mut self . 1 , pi. into_par_iter ( ) , Unzip ) ;
412
+ }
413
+ }
414
+
415
+ impl < L , R , A , B > ParallelExtend < Either < L , R > > for ( A , B )
416
+ where
417
+ L : Send ,
418
+ R : Send ,
419
+ A : Send + ParallelExtend < L > ,
420
+ B : Send + ParallelExtend < R > ,
421
+ {
422
+ fn par_extend < I > ( & mut self , pi : I )
423
+ where
424
+ I : IntoParallelIterator < Item = Either < L , R > > ,
425
+ {
426
+ execute_into ( & mut self . 0 , & mut self . 1 , pi. into_par_iter ( ) , UnEither ) ;
427
+ }
428
+ }
429
+
430
+ /// An `UnzipOp` that routes items depending on their `Either` variant.
431
+ struct UnEither ;
432
+
433
+ impl < L , R > UnzipOp < Either < L , R > > for UnEither
434
+ where
435
+ L : Send ,
436
+ R : Send ,
437
+ {
438
+ type Left = L ;
439
+ type Right = R ;
440
+
441
+ fn consume < FL , FR > ( & self , item : Either < L , R > , left : FL , right : FR ) -> ( FL , FR )
442
+ where
443
+ FL : Folder < L > ,
444
+ FR : Folder < R > ,
445
+ {
446
+ match item {
447
+ Either :: Left ( item) => ( left. consume ( item) , right) ,
448
+ Either :: Right ( item) => ( left, right. consume ( item) ) ,
449
+ }
450
+ }
451
+ }
0 commit comments