@@ -227,6 +227,13 @@ cfg_if! {
227227 resume( panic) ;
228228 }
229229
230+ pub fn balance_par_for_each<T : IntoIterator >(
231+ t: T ,
232+ for_each: impl FnMut ( <<T as IntoIterator >:: IntoIter as Iterator >:: Item ) ,
233+ ) {
234+ par_for_each( t, for_each)
235+ }
236+
230237 pub fn par_map<T : IntoIterator , R , C : FromIterator <R >>(
231238 t: T ,
232239 mut map: impl FnMut ( <<T as IntoIterator >:: IntoIter as Iterator >:: Item ) -> R ,
@@ -405,7 +412,9 @@ cfg_if! {
405412
406413 pub use rayon_core:: WorkerLocal ;
407414
408- use rayon:: iter:: { ParallelIterator , FromParallelIterator , IntoParallelIterator } ;
415+ use rayon:: iter:: {
416+ ParallelIterator , IndexedParallelIterator , FromParallelIterator , IntoParallelIterator
417+ } ;
409418
410419 pub fn par_for_each<T : IntoParallelIterator >(
411420 t: T ,
@@ -421,6 +430,25 @@ cfg_if! {
421430 resume( panic) ;
422431 }
423432
433+ /// This does the same as `par_for_each`,
434+ /// but each loop iteration is stealable by other threads.
435+ pub fn balance_par_for_each<T : IntoParallelIterator >(
436+ t: T ,
437+ for_each: impl Fn (
438+ <<T as IntoParallelIterator >:: Iter as ParallelIterator >:: Item
439+ ) + Sync + Send
440+ )
441+ where
442+ <T as IntoParallelIterator >:: Iter : IndexedParallelIterator
443+ {
444+ // We catch panics here ensuring that all the loop iterations execute.
445+ let panic = Lock :: new( None ) ;
446+ t. into_par_iter( ) . with_max_len( 1 ) . for_each( |i| {
447+ catch( & panic, || for_each( i) ) ;
448+ } ) ;
449+ resume( panic) ;
450+ }
451+
424452 pub fn par_map<
425453 T : IntoParallelIterator ,
426454 R : Send ,
0 commit comments