@@ -386,3 +386,164 @@ impl<T> FusedIterator for Once<T> {}
386386pub fn once < T > ( value : T ) -> Once < T > {
387387 Once { inner : Some ( value) . into_iter ( ) }
388388}
389+
390+ /// Creates a new iterator where each iteration calls the provided closure
391+ /// `F: FnMut(&mut St) -> Option<T>`.
392+ ///
393+ /// This allows creating a custom iterator with any behavior
394+ /// without using the more verbose syntax of creating a dedicated type
395+ /// and implementing the `Iterator` trait for it.
396+ ///
397+ /// In addition to its captures and environment,
398+ /// the closure is given a mutable reference to some state
399+ /// that is preserved across iterations.
400+ /// That state starts as the given `initial_state` value.
401+ ///
402+ /// Note that the `Unfold` iterator doesn’t make assumptions about the behavior of the closure,
403+ /// and therefore conservatively does not implement [`FusedIterator`],
404+ /// or override [`Iterator::size_hint`] from its default `(0, None)`.
405+ ///
406+ /// [`FusedIterator`]: trait.FusedIterator.html
407+ /// [`Iterator::size_hint`]: trait.Iterator.html#method.size_hint
408+ ///
409+ /// # Examples
410+ ///
411+ /// Let’s re-implement the counter iterator from [module-level documentation]:
412+ ///
413+ /// [module-level documentation]: index.html
414+ ///
415+ /// ```
416+ /// #![feature(iter_unfold)]
417+ /// let counter = std::iter::unfold(0, |count| {
418+ /// // Increment our count. This is why we started at zero.
419+ /// *count += 1;
420+ ///
421+ /// // Check to see if we've finished counting or not.
422+ /// if *count < 6 {
423+ /// Some(*count)
424+ /// } else {
425+ /// None
426+ /// }
427+ /// });
428+ /// assert_eq!(counter.collect::<Vec<_>>(), &[1, 2, 3, 4, 5]);
429+ /// ```
430+ #[ inline]
431+ #[ unstable( feature = "iter_unfold" , issue = "55977" ) ]
432+ pub fn unfold < St , T , F > ( initial_state : St , f : F ) -> Unfold < St , F >
433+ where F : FnMut ( & mut St ) -> Option < T >
434+ {
435+ Unfold {
436+ state : initial_state,
437+ f,
438+ }
439+ }
440+
441+ /// An iterator where each iteration calls the provided closure `F: FnMut(&mut St) -> Option<T>`.
442+ ///
443+ /// This `struct` is created by the [`unfold`] function.
444+ /// See its documentation for more.
445+ ///
446+ /// [`unfold`]: fn.unfold.html
447+ #[ derive( Clone ) ]
448+ #[ unstable( feature = "iter_unfold" , issue = "55977" ) ]
449+ pub struct Unfold < St , F > {
450+ state : St ,
451+ f : F ,
452+ }
453+
454+ #[ unstable( feature = "iter_unfold" , issue = "55977" ) ]
455+ impl < St , T , F > Iterator for Unfold < St , F >
456+ where F : FnMut ( & mut St ) -> Option < T >
457+ {
458+ type Item = T ;
459+
460+ #[ inline]
461+ fn next ( & mut self ) -> Option < Self :: Item > {
462+ ( self . f ) ( & mut self . state )
463+ }
464+ }
465+
466+ #[ unstable( feature = "iter_unfold" , issue = "55977" ) ]
467+ impl < St : fmt:: Debug , F > fmt:: Debug for Unfold < St , F > {
468+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
469+ f. debug_struct ( "Unfold" )
470+ . field ( "state" , & self . state )
471+ . finish ( )
472+ }
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 = "55977" ) ]
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 = "55977" ) ]
508+ pub struct Successors < T , F > {
509+ next : Option < T > ,
510+ succ : F ,
511+ }
512+
513+ #[ unstable( feature = "iter_unfold" , issue = "55977" ) ]
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 = "55977" ) ]
538+ impl < T , F > FusedIterator for Successors < T , F >
539+ where F : FnMut ( & T ) -> Option < T >
540+ { }
541+
542+ #[ unstable( feature = "iter_unfold" , issue = "55977" ) ]
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