@@ -471,3 +471,79 @@ impl<St: fmt::Debug, F> fmt::Debug for Unfold<St, F> {
471
471
. finish ( )
472
472
}
473
473
}
474
+
475
+ /// Creates a new iterator where each successive item is computed based on the preceding one.
476
+ ///
477
+ /// The iterator starts with the given first item (if any)
478
+ /// and calls the given `FnMut(&T) -> Option<T>` closure to compute each item’s successor.
479
+ ///
480
+ /// ```
481
+ /// #![feature(iter_unfold)]
482
+ /// use std::iter::successors;
483
+ ///
484
+ /// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
485
+ /// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
486
+ /// ```
487
+ #[ unstable( feature = "iter_unfold" , issue = /* FIXME */ "0" ) ]
488
+ pub fn successors < T , F > ( first : Option < T > , succ : F ) -> Successors < T , F >
489
+ where F : FnMut ( & T ) -> Option < T >
490
+ {
491
+ // If this function returned `impl Iterator<Item=T>`
492
+ // it could be based on `unfold` and not need a dedicated type.
493
+ // However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
494
+ Successors {
495
+ next : first,
496
+ succ,
497
+ }
498
+ }
499
+
500
+ /// An new iterator where each successive item is computed based on the preceding one.
501
+ ///
502
+ /// This `struct` is created by the [`successors`] function.
503
+ /// See its documentation for more.
504
+ ///
505
+ /// [`successors`]: fn.successors.html
506
+ #[ derive( Clone ) ]
507
+ #[ unstable( feature = "iter_unfold" , issue = /* FIXME */ "0" ) ]
508
+ pub struct Successors < T , F > {
509
+ next : Option < T > ,
510
+ succ : F ,
511
+ }
512
+
513
+ #[ unstable( feature = "iter_unfold" , issue = /* FIXME */ "0" ) ]
514
+ impl < T , F > Iterator for Successors < T , F >
515
+ where F : FnMut ( & T ) -> Option < T >
516
+ {
517
+ type Item = T ;
518
+
519
+ #[ inline]
520
+ fn next ( & mut self ) -> Option < Self :: Item > {
521
+ self . next . take ( ) . map ( |item| {
522
+ self . next = ( self . succ ) ( & item) ;
523
+ item
524
+ } )
525
+ }
526
+
527
+ #[ inline]
528
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
529
+ if self . next . is_some ( ) {
530
+ ( 1 , None )
531
+ } else {
532
+ ( 0 , Some ( 0 ) )
533
+ }
534
+ }
535
+ }
536
+
537
+ #[ unstable( feature = "iter_unfold" , issue = /* FIXME */ "0" ) ]
538
+ impl < T , F > FusedIterator for Successors < T , F >
539
+ where F : FnMut ( & T ) -> Option < T >
540
+ { }
541
+
542
+ #[ unstable( feature = "iter_unfold" , issue = /* FIXME */ "0" ) ]
543
+ impl < T : fmt:: Debug , F > fmt:: Debug for Successors < T , F > {
544
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
545
+ f. debug_struct ( "Successors" )
546
+ . field ( "next" , & self . next )
547
+ . finish ( )
548
+ }
549
+ }
0 commit comments