diff options
| author | Tim Vermeulen <tvermeulen@me.com> | 2019-09-14 21:24:50 +0200 |
|---|---|---|
| committer | Tim Vermeulen <tvermeulen@me.com> | 2019-09-14 21:52:08 +0200 |
| commit | 72175915d6ae5abbc45cf2860a90508d2b4a38ea (patch) | |
| tree | b411ca7c07f87b52c4679409e24e18f2554e087c /src/libcore | |
| parent | 6e5ada43bf84b15a8dd4d55f5bee3ba1a9939bfe (diff) | |
| download | rust-72175915d6ae5abbc45cf2860a90508d2b4a38ea.tar.gz rust-72175915d6ae5abbc45cf2860a90508d2b4a38ea.zip | |
Simplify Iterator::{min_by, max_by} using cmp::{min_by, max_by}
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/iter/traits/iterator.rs | 48 |
1 files changed, 17 insertions, 31 deletions
diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index c09df3f7f22..da49223dfb2 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1,4 +1,4 @@ -use crate::cmp::Ordering; +use crate::cmp::{self, Ordering}; use crate::ops::{Add, Try}; use super::super::LoopState; @@ -2223,13 +2223,12 @@ pub trait Iterator { move |x| (f(&x), x) } - // switch to y even if it is only equal, to preserve stability. #[inline] - fn select<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool { - x_p <= y_p + fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering { + x_p.cmp(y_p) } - let (_, x) = select_fold1(self.map(key(f)), select)?; + let (_, x) = self.map(key(f)).max_by(compare)?; Some(x) } @@ -2252,13 +2251,12 @@ pub trait Iterator { fn max_by<F>(self, compare: F) -> Option<Self::Item> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, { - // switch to y even if it is only equal, to preserve stability. #[inline] - fn select<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool { - move |x, y| compare(x, y) != Ordering::Greater + fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T { + move |x, y| cmp::max_by(x, y, &mut compare) } - select_fold1(self, select(compare)) + fold1(self, fold(compare)) } /// Returns the element that gives the minimum value from the @@ -2285,13 +2283,12 @@ pub trait Iterator { move |x| (f(&x), x) } - // only switch to y if it is strictly smaller, to preserve stability. #[inline] - fn select<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool { - x_p > y_p + fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering { + x_p.cmp(y_p) } - let (_, x) = select_fold1(self.map(key(f)), select)?; + let (_, x) = self.map(key(f)).min_by(compare)?; Some(x) } @@ -2314,13 +2311,12 @@ pub trait Iterator { fn min_by<F>(self, compare: F) -> Option<Self::Item> where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, { - // only switch to y if it is strictly smaller, to preserve stability. #[inline] - fn select<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool { - move |x, y| compare(x, y) == Ordering::Greater + fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T { + move |x, y| cmp::min_by(x, y, &mut compare) } - select_fold1(self, select(compare)) + fold1(self, fold(compare)) } @@ -2958,28 +2954,18 @@ pub trait Iterator { } } -/// Select an element from an iterator based on the given "comparison" -/// function. -/// -/// This is an idiosyncratic helper to try to factor out the -/// commonalities of {max,min}{,_by}. In particular, this avoids -/// having to implement optimizations several times. +/// Fold an iterator without having to provide an initial value. #[inline] -fn select_fold1<I, F>(mut it: I, f: F) -> Option<I::Item> +fn fold1<I, F>(mut it: I, f: F) -> Option<I::Item> where I: Iterator, - F: FnMut(&I::Item, &I::Item) -> bool, + F: FnMut(I::Item, I::Item) -> I::Item, { - #[inline] - fn select<T>(mut f: impl FnMut(&T, &T) -> bool) -> impl FnMut(T, T) -> T { - move |sel, x| if f(&sel, &x) { x } else { sel } - } - // start with the first element as our selection. This avoids // having to use `Option`s inside the loop, translating to a // sizeable performance gain (6x in one case). let first = it.next()?; - Some(it.fold(first, select(f))) + Some(it.fold(first, f)) } #[stable(feature = "rust1", since = "1.0.0")] |
