@@ -232,6 +232,159 @@ fn test_zip_trusted_random_access_composition() {
232232 assert_eq ! ( z2. next( ) . unwrap( ) , ( ( 1 , 1 ) , 1 ) ) ;
233233}
234234
235+ #[ test]
236+ fn test_zip_trusted_random_access_fold_rfold ( ) {
237+ let a = [ 0 , 1 , 2 , 3 , 4 ] ;
238+ let b = [ 5 , 6 , 7 , 8 , 9 , 10 ] ;
239+
240+ let sum = a. iter ( ) . copied ( ) . sum :: < i32 > ( ) + b. iter ( ) . copied ( ) . take ( a. len ( ) ) . sum :: < i32 > ( ) ;
241+ let zip = || a. iter ( ) . copied ( ) . zip ( b. iter ( ) . copied ( ) ) ;
242+ let fwd_sum = zip ( ) . fold ( 0 , |a, ( b, c) | a + b + c) ;
243+ let bwd_sum = zip ( ) . rfold ( 0 , |a, ( b, c) | a + b + c) ;
244+
245+ assert_eq ! ( fwd_sum, sum) ;
246+ assert_eq ! ( bwd_sum, sum) ;
247+ }
248+
249+ #[ test]
250+ fn test_zip_trusted_random_access_try_fold_try_rfold ( ) {
251+ let a = [ 0 , 1 , 2 , 3 , 4 ] ;
252+ let b = [ 5 , 6 , 7 , 8 , 9 , 10 ] ;
253+
254+ let sum = a. iter ( ) . copied ( ) . sum :: < i32 > ( ) + b. iter ( ) . copied ( ) . take ( a. len ( ) ) . sum :: < i32 > ( ) ;
255+ let zip = || a. iter ( ) . copied ( ) . zip ( b. iter ( ) . copied ( ) ) ;
256+ let mut zip_fwd = zip ( ) ;
257+ let mut zip_bwd = zip ( ) ;
258+
259+ let fwd_sum: Result < i32 , ( ) > = zip_fwd. try_fold ( 0 , |a, ( b, c) | Ok ( a + b + c) ) ;
260+ let bwd_sum: Result < i32 , ( ) > = zip_bwd. try_rfold ( 0 , |a, ( b, c) | Ok ( a + b + c) ) ;
261+
262+ assert_eq ! ( fwd_sum, Ok ( sum) ) ;
263+ assert_eq ! ( bwd_sum, Ok ( sum) ) ;
264+ assert_eq ! ( zip_fwd. next( ) , None ) ;
265+ assert_eq ! ( zip_fwd. next_back( ) , None ) ;
266+ assert_eq ! ( zip_bwd. next( ) , None ) ;
267+ assert_eq ! ( zip_bwd. next_back( ) , None ) ;
268+ }
269+
270+ #[ test]
271+ fn test_zip_trusted_random_access_try_fold_try_rfold_resumable ( ) {
272+ let a = [ 0 , 1 , 2 , 3 , 4 ] ;
273+ let b = [ 5 , 6 , 7 , 8 , 9 , 10 ] ;
274+
275+ fn sum_countdown ( mut count : usize ) -> impl FnMut ( i32 , ( i32 , i32 ) ) -> Result < i32 , i32 > {
276+ move |a : i32 , ( b, c) : ( i32 , i32 ) | {
277+ if count == 0 {
278+ Err ( a)
279+ } else {
280+ count -= 1 ;
281+ Ok ( a + b + c)
282+ }
283+ }
284+ }
285+
286+ let zip = || a. iter ( ) . copied ( ) . zip ( b. iter ( ) . copied ( ) ) ;
287+ let mut zip_fwd = zip ( ) ;
288+ let mut zip_bwd = zip ( ) ;
289+
290+ let fwd_sum = zip_fwd. try_fold ( 0 , sum_countdown ( 2 ) ) ;
291+ let bwd_sum = zip_bwd. try_rfold ( 0 , sum_countdown ( 2 ) ) ;
292+
293+ assert_eq ! ( fwd_sum, Err ( 0 + 1 + 5 + 6 ) ) ;
294+ assert_eq ! ( bwd_sum, Err ( 4 + 3 + 9 + 8 ) ) ;
295+ {
296+ let mut zip_fwd = zip_fwd. clone ( ) ;
297+ let mut zip_bwd = zip_bwd. clone ( ) ;
298+ assert_eq ! ( zip_fwd. next( ) , Some ( ( 3 , 8 ) ) ) ;
299+ assert_eq ! ( zip_fwd. next( ) , Some ( ( 4 , 9 ) ) ) ;
300+ assert_eq ! ( zip_fwd. next( ) , None ) ;
301+
302+ assert_eq ! ( zip_bwd. next( ) , Some ( ( 0 , 5 ) ) ) ;
303+ assert_eq ! ( zip_bwd. next( ) , Some ( ( 1 , 6 ) ) ) ;
304+ assert_eq ! ( zip_bwd. next( ) , None ) ;
305+ }
306+
307+ assert_eq ! ( zip_fwd. next_back( ) , Some ( ( 4 , 9 ) ) ) ;
308+ assert_eq ! ( zip_fwd. next_back( ) , Some ( ( 3 , 8 ) ) ) ;
309+ assert_eq ! ( zip_fwd. next_back( ) , None ) ;
310+
311+ assert_eq ! ( zip_bwd. next_back( ) , Some ( ( 1 , 6 ) ) ) ;
312+ assert_eq ! ( zip_bwd. next_back( ) , Some ( ( 0 , 5 ) ) ) ;
313+ assert_eq ! ( zip_bwd. next_back( ) , None ) ;
314+ }
315+
316+ #[ test]
317+ #[ cfg( panic = "unwind" ) ]
318+ fn test_zip_trusted_random_access_try_fold_try_rfold_panic ( ) {
319+ use std:: panic:: catch_unwind;
320+ use std:: panic:: AssertUnwindSafe ;
321+
322+ let a = [ 0 , 1 , 2 ] ;
323+ let b = [ 3 , 4 , 5 , 6 ] ;
324+
325+ fn sum_countdown ( mut count : usize ) -> impl FnMut ( i32 , ( i32 , i32 ) ) -> Result < i32 , i32 > {
326+ move |a : i32 , ( b, c) : ( i32 , i32 ) | {
327+ if count == 0 {
328+ panic ! ( "bomb" )
329+ } else {
330+ count -= 1 ;
331+ Ok ( a + b + c)
332+ }
333+ }
334+ }
335+
336+ let zip = || a. iter ( ) . copied ( ) . zip ( b. iter ( ) . copied ( ) ) ;
337+ let mut zip_fwd = zip ( ) ;
338+ let mut zip_bwd = zip ( ) ;
339+
340+ let _ = catch_unwind ( AssertUnwindSafe ( || {
341+ let _ = zip_fwd. try_fold ( 0 , sum_countdown ( 1 ) ) ;
342+ } ) ) ;
343+ let _ = catch_unwind ( AssertUnwindSafe ( || {
344+ let _ = zip_bwd. try_rfold ( 0 , sum_countdown ( 1 ) ) ;
345+ } ) ) ;
346+
347+ {
348+ let mut zip_fwd = zip_fwd. clone ( ) ;
349+ let mut zip_bwd = zip_bwd. clone ( ) ;
350+ match zip_fwd. next ( ) {
351+ Some ( ( a, b) ) => {
352+ assert ! ( a > 1 ) ;
353+ assert ! ( b > 4 ) ;
354+ assert_eq ! ( b - a, 3 ) ;
355+ }
356+ None => ( ) ,
357+ } ;
358+
359+ match zip_bwd. next_back ( ) {
360+ Some ( ( a, b) ) => {
361+ assert ! ( a < 1 ) ;
362+ assert ! ( b < 4 ) ;
363+ assert_eq ! ( b - a, 3 ) ;
364+ }
365+ None => ( ) ,
366+ } ;
367+ }
368+
369+ match zip_fwd. next_back ( ) {
370+ Some ( ( a, b) ) => {
371+ assert ! ( a > 1 ) ;
372+ assert ! ( b > 4 ) ;
373+ assert_eq ! ( b - a, 3 ) ;
374+ }
375+ None => ( ) ,
376+ } ;
377+
378+ match zip_bwd. next ( ) {
379+ Some ( ( a, b) ) => {
380+ assert ! ( a < 1 ) ;
381+ assert ! ( b < 4 ) ;
382+ assert_eq ! ( b - a, 3 ) ;
383+ }
384+ None => ( ) ,
385+ } ;
386+ }
387+
235388#[ test]
236389#[ cfg( panic = "unwind" ) ]
237390fn test_zip_trusted_random_access_next_back_drop ( ) {
0 commit comments