From d2b877485c11bfe6913441a99e7cf1b557e0c141 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Fri, 13 Jul 2018 21:34:36 -0700 Subject: [PATCH 1/4] Added fold_self and try_fold_self --- src/libcore/iter/iterator.rs | 73 ++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 3063cb1a7df44..6cc4dd8395108 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1586,6 +1586,45 @@ pub trait Iterator { Try::from_ok(accum) } + /// The same as [`try_fold()`](#method.try_fold), but uses the first element + /// in the iterator as the initial value, folding every subsequent element + /// into it. If the iterator is empty, return None; otherwise, return the + /// result of the fold. + /// + /// # Examples + /// + /// Find the maximum value: + /// + /// ``` + /// use std::cmp::Ordering; + /// fn find_max(iter: I) -> Option + /// where I: Iterator, + /// I::Item: PartialCmp, + /// { + /// iter.try_fold_self(|a, b| { + /// a.partial_cmp(b).map(move |cmp| match cmp { + /// Ordering::Greater | Ordering::Equal => a, + /// Ordering::Less => b, + /// }) + /// }) + /// } + /// let a = [10, 20, 5, -23, 0]; + /// let b = [10, 20, -23, std::f64::NAN, 12, 2.5]; + /// let c = []; + /// + /// assert_eq!(find_max(a.iter()), Some(Some(20))); + /// assert_eq!(find_max(b.iter()), Some(None)); + /// assert_eq!(find_max(c.iter()), None); + /// ``` + #[inline] + fn try_fold_self(&mut self, mut f: F) -> Option + where Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try + { + self.next().map(move |first| self.try_fold(first, f)) + } + /// An iterator method that applies a fallible function to each item in the /// iterator, stopping at the first error and returning that error. /// @@ -1696,6 +1735,40 @@ pub trait Iterator { self.try_fold(init, move |acc, x| Ok::(f(acc, x))).unwrap() } + /// The same as [`fold()`](#method.fold), but uses the first element in the + /// iterator as the initial value, folding every subsequent element into it. + /// If the iterator is empty, return `None`; otherwise, return the result + /// of the fold. + /// + /// # Example + /// + /// Find the maximum value: + /// + /// ``` + /// fn find_max(iter: I) -> Option + /// where I: Iterator, + /// I::Item: Ord, + /// { + /// iter.fold_self(|a, b| { + /// a.partial_cmp(b).map(move |cmp| match cmp { + /// Ordering::Greater | Ordering::Equal => a, + /// Ordering::Less => b, + /// }) + /// }) + /// } + /// let a = [10, 20, 5, -23, 0]; + /// let b = []; + /// + /// assert_eq!(find_max(a.iter()), Some(20)); + /// assert_eq!(find_max(b.iter()), None)); + /// ``` + #[inline] + fn fold_self(mut self, mut f: F) -> Option + where Self: Sized, F: FnMut(Self::Item, Self::Item) -> Self::Item + { + self.next().map(move |first| self.fold(first, f)) + } + /// Tests if every element of the iterator matches a predicate. /// /// `all()` takes a closure that returns `true` or `false`. It applies From 5c5fd0c81776c921e24ada3afca8d96ee0a57407 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Thu, 18 Apr 2019 20:54:14 -0700 Subject: [PATCH 2/4] Added unstable attributes --- src/libcore/iter/iterator.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 6cc4dd8395108..ea473974d09ad 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1617,6 +1617,7 @@ pub trait Iterator { /// assert_eq!(find_max(c.iter()), None); /// ``` #[inline] + #[unstable(feature = "iterator_try_fold_self", issue = "0")] fn try_fold_self(&mut self, mut f: F) -> Option where Self: Sized, F: FnMut(Self::Item, Self::Item) -> R, @@ -1763,6 +1764,7 @@ pub trait Iterator { /// assert_eq!(find_max(b.iter()), None)); /// ``` #[inline] + #[unstable(feature = "iterator_try_fold_self", issue = "0")] fn fold_self(mut self, mut f: F) -> Option where Self: Sized, F: FnMut(Self::Item, Self::Item) -> Self::Item { From 39943b334cb438ecefdcf2ac69eaef38844ec250 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Thu, 18 Apr 2019 20:58:07 -0700 Subject: [PATCH 3/4] Updated unstable feature attribute --- src/libcore/iter/iterator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index ea473974d09ad..b300441cf2649 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1617,7 +1617,7 @@ pub trait Iterator { /// assert_eq!(find_max(c.iter()), None); /// ``` #[inline] - #[unstable(feature = "iterator_try_fold_self", issue = "0")] + #[unstable(feature = "iterator_fold_self", issue = "60103")] fn try_fold_self(&mut self, mut f: F) -> Option where Self: Sized, F: FnMut(Self::Item, Self::Item) -> R, @@ -1764,7 +1764,7 @@ pub trait Iterator { /// assert_eq!(find_max(b.iter()), None)); /// ``` #[inline] - #[unstable(feature = "iterator_try_fold_self", issue = "0")] + #[unstable(feature = "iterator_fold_self", issue = "60103")] fn fold_self(mut self, mut f: F) -> Option where Self: Sized, F: FnMut(Self::Item, Self::Item) -> Self::Item { From 0b99f1f163e05a0ef87107dad122835bcf436a23 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 22 Apr 2019 08:31:00 -0700 Subject: [PATCH 4/4] Formatting Co-Authored-By: Lucretiel --- src/libcore/iter/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index b300441cf2649..70aacfa5eb8bb 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1621,7 +1621,7 @@ pub trait Iterator { fn try_fold_self(&mut self, mut f: F) -> Option where Self: Sized, F: FnMut(Self::Item, Self::Item) -> R, - R: Try + R: Try { self.next().map(move |first| self.try_fold(first, f)) }