@@ -471,3 +471,79 @@ impl<St: fmt::Debug, F> fmt::Debug for Unfold<St, F> {
471471 . finish ( )
472472 }
473473}
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