Rename iter::unfold to iter::from_fn and remove explicit state

This API is unstable.

CC https://github.com/rust-lang/rust/issues/55977#issuecomment-459657195
This commit is contained in:
Simon Sapin
2019-02-01 23:59:11 +01:00
parent 741a3d42cb
commit 61e92b586b
2 changed files with 25 additions and 32 deletions

View File

@@ -327,7 +327,7 @@ pub use self::sources::{Once, once};
#[unstable(feature = "iter_once_with", issue = "57581")] #[unstable(feature = "iter_once_with", issue = "57581")]
pub use self::sources::{OnceWith, once_with}; pub use self::sources::{OnceWith, once_with};
#[unstable(feature = "iter_unfold", issue = "55977")] #[unstable(feature = "iter_unfold", issue = "55977")]
pub use self::sources::{Unfold, unfold, Successors, successors}; pub use self::sources::{FromFn, from_fn, Successors, successors};
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend}; pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend};

View File

@@ -491,24 +491,24 @@ pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
} }
/// Creates a new iterator where each iteration calls the provided closure /// Creates a new iterator where each iteration calls the provided closure
/// `F: FnMut(&mut St) -> Option<T>`. /// `F: FnMut() -> Option<T>`.
/// ///
/// This allows creating a custom iterator with any behavior /// This allows creating a custom iterator with any behavior
/// without using the more verbose syntax of creating a dedicated type /// without using the more verbose syntax of creating a dedicated type
/// and implementing the `Iterator` trait for it. /// and implementing the `Iterator` trait for it.
/// ///
/// In addition to its captures and environment, /// Note that the `FromFn` iterator doesnt make assumptions about the behavior of the closure,
/// the closure is given a mutable reference to some state
/// that is preserved across iterations.
/// That state starts as the given `initial_state` value.
///
/// Note that the `Unfold` iterator doesnt make assumptions about the behavior of the closure,
/// and therefore conservatively does not implement [`FusedIterator`], /// and therefore conservatively does not implement [`FusedIterator`],
/// or override [`Iterator::size_hint`] from its default `(0, None)`. /// or override [`Iterator::size_hint`] from its default `(0, None)`.
/// ///
/// [`FusedIterator`]: trait.FusedIterator.html /// [`FusedIterator`]: trait.FusedIterator.html
/// [`Iterator::size_hint`]: trait.Iterator.html#method.size_hint /// [`Iterator::size_hint`]: trait.Iterator.html#method.size_hint
/// ///
/// The closure can use its its captures and environment
/// to track state across iterations.
/// Depending on how the iterator is used,
/// this may require specifying the `move` keyword on the closure.
///
/// # Examples /// # Examples
/// ///
/// Lets re-implement the counter iterator from [module-level documentation]: /// Lets re-implement the counter iterator from [module-level documentation]:
@@ -517,13 +517,14 @@ pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
/// ///
/// ``` /// ```
/// #![feature(iter_unfold)] /// #![feature(iter_unfold)]
/// let counter = std::iter::unfold(0, |count| { /// let mut count = 0;
/// let counter = std::iter::from_fn(move || {
/// // Increment our count. This is why we started at zero. /// // Increment our count. This is why we started at zero.
/// *count += 1; /// count += 1;
/// ///
/// // Check to see if we've finished counting or not. /// // Check to see if we've finished counting or not.
/// if *count < 6 { /// if count < 6 {
/// Some(*count) /// Some(count)
/// } else { /// } else {
/// None /// None
/// } /// }
@@ -532,46 +533,38 @@ pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
/// ``` /// ```
#[inline] #[inline]
#[unstable(feature = "iter_unfold", issue = "55977")] #[unstable(feature = "iter_unfold", issue = "55977")]
pub fn unfold<St, T, F>(initial_state: St, f: F) -> Unfold<St, F> pub fn from_fn<T, F>(f: F) -> FromFn<F>
where F: FnMut(&mut St) -> Option<T> where F: FnMut() -> Option<T>
{ {
Unfold { FromFn(f)
state: initial_state,
f,
}
} }
/// An iterator where each iteration calls the provided closure `F: FnMut(&mut St) -> Option<T>`. /// An iterator where each iteration calls the provided closure `F: FnMut() -> Option<T>`.
/// ///
/// This `struct` is created by the [`unfold`] function. /// This `struct` is created by the [`iter::from_fn`] function.
/// See its documentation for more. /// See its documentation for more.
/// ///
/// [`unfold`]: fn.unfold.html /// [`iter::from_fn`]: fn.from_fn.html
#[derive(Clone)] #[derive(Clone)]
#[unstable(feature = "iter_unfold", issue = "55977")] #[unstable(feature = "iter_unfold", issue = "55977")]
pub struct Unfold<St, F> { pub struct FromFn<F>(F);
state: St,
f: F,
}
#[unstable(feature = "iter_unfold", issue = "55977")] #[unstable(feature = "iter_unfold", issue = "55977")]
impl<St, T, F> Iterator for Unfold<St, F> impl<T, F> Iterator for FromFn<F>
where F: FnMut(&mut St) -> Option<T> where F: FnMut() -> Option<T>
{ {
type Item = T; type Item = T;
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
(self.f)(&mut self.state) (self.0)()
} }
} }
#[unstable(feature = "iter_unfold", issue = "55977")] #[unstable(feature = "iter_unfold", issue = "55977")]
impl<St: fmt::Debug, F> fmt::Debug for Unfold<St, F> { impl<F> fmt::Debug for FromFn<F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Unfold") f.debug_struct("FromFn").finish()
.field("state", &self.state)
.finish()
} }
} }