diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 6b01ccaceea2f..f530009585ece 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1664,6 +1664,32 @@ pub trait Iterator { .map(|(_, x)| x) } + /// Returns the element that gives the maximum value with respect to the + /// specified comparison function. + /// + /// Returns the rightmost element if the comparison determines two elements + /// to be equally maximum. + /// + /// # Examples + /// + /// ``` + /// #![feature(iter_max_by)] + /// let a = [-3_i32, 0, 1, 5, -10]; + /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5); + /// ``` + #[inline] + #[unstable(feature = "iter_max_by", issue="36105")] + fn max_by(self, mut compare: F) -> Option + where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, + { + select_fold1(self, + |_| (), + // switch to y even if it is only equal, to preserve + // stability. + |_, x, _, y| Ordering::Greater != compare(x, y)) + .map(|(_, x)| x) + } + /// Returns the element that gives the minimum value from the /// specified function. /// @@ -1688,6 +1714,33 @@ pub trait Iterator { .map(|(_, x)| x) } + /// Returns the element that gives the minimum value with respect to the + /// specified comparison function. + /// + /// Returns the latest element if the comparison determines two elements + /// to be equally minimum. + /// + /// # Examples + /// + /// ``` + /// #![feature(iter_min_by)] + /// let a = [-3_i32, 0, 1, 5, -10]; + /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10); + /// ``` + #[inline] + #[unstable(feature = "iter_min_by", issue="36105")] + fn min_by(self, mut compare: F) -> Option + where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, + { + select_fold1(self, + |_| (), + // switch to y even if it is strictly smaller, to + // preserve stability. + |_, x, _, y| Ordering::Greater == compare(x, y)) + .map(|(_, x)| x) + } + + /// Reverses an iterator's direction. /// /// Usually, iterators iterate from left to right. After using `rev()`, diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index a2848faa105e9..27eb25537f31b 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -664,12 +664,24 @@ fn test_max_by_key() { assert_eq!(*xs.iter().max_by_key(|x| x.abs()).unwrap(), -10); } +#[test] +fn test_max_by() { + let xs: &[isize] = &[-3, 0, 1, 5, -10]; + assert_eq!(*xs.iter().max_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), -10); +} + #[test] fn test_min_by_key() { let xs: &[isize] = &[-3, 0, 1, 5, -10]; assert_eq!(*xs.iter().min_by_key(|x| x.abs()).unwrap(), 0); } +#[test] +fn test_min_by() { + let xs: &[isize] = &[-3, 0, 1, 5, -10]; + assert_eq!(*xs.iter().min_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), 0); +} + #[test] fn test_by_ref() { let mut xs = 0..10; diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 9428b4096bfec..b4c94509477a3 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -33,6 +33,8 @@ #![feature(try_from)] #![feature(unicode)] #![feature(unique)] +#![feature(iter_max_by)] +#![feature(iter_min_by)] extern crate core; extern crate test;