From 6710669286adc16045c8f41259786240612d9df7 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 11 Jan 2018 23:54:44 +0000 Subject: [PATCH 1/3] Add finite iterator specialisations for Repeat --- src/libcore/iter/sources.rs | 34 ++++++++++++++++++++++++++++++++++ src/libcore/tests/iter.rs | 14 ++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index b405f35d5e4db..6258919b7c298 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -11,6 +11,7 @@ use fmt; use marker; use usize; +use cmp::Ordering; use super::{FusedIterator, TrustedLen}; @@ -31,8 +32,41 @@ impl Iterator for Repeat { #[inline] fn next(&mut self) -> Option { Some(self.element.clone()) } + #[inline] fn size_hint(&self) -> (usize, Option) { (usize::MAX, None) } + + #[inline] + fn nth(&mut self, _: usize) -> Option { self.next() } + + #[inline] + fn all(&mut self, f: F) -> bool where F: FnMut(A) -> bool { self.any(f) } + + #[inline] + fn max(mut self) -> Option { self.next() } + + #[inline] + fn min(mut self) -> Option { self.next() } + + #[inline] + fn max_by_key(mut self, _: F) -> Option where F: FnMut(&A) -> B { + self.next() + } + + #[inline] + fn max_by(mut self, _: F) -> Option where F: FnMut(&A, &A) -> Ordering { + self.next() + } + + #[inline] + fn min_by_key(mut self, _: F) -> Option where F: FnMut(&A) -> B { + self.next() + } + + #[inline] + fn min_by(mut self, _: F) -> Option where F: FnMut(&A, &A) -> Ordering { + self.next() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 8997cf9c6bff9..e34580aa8c66a 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -11,6 +11,7 @@ use core::iter::*; use core::{i8, i16, isize}; use core::usize; +use std::cmp::Ordering; #[test] fn test_lt() { @@ -1405,6 +1406,19 @@ fn test_repeat() { assert_eq!(it.next(), Some(42)); } +#[test] +fn test_repeat_iterator() { + let mut it = repeat(42); + assert_eq!(it.nth(usize::MAX), Some(42)); + assert_eq!(it.all(|x| x == 42), true); + assert_eq!(repeat(42).max(), Some(42)); + assert_eq!(repeat(42).min(), Some(42)); + assert_eq!(repeat(42).max_by_key(|_| 0), Some(42)); + assert_eq!(repeat(42).max_by_key(|_| Ordering::Greater), Some(42)); + assert_eq!(repeat(42).min_by_key(|_| 0), Some(42)); + assert_eq!(repeat(42).min_by_key(|_| Ordering::Greater), Some(42)); +} + #[test] fn test_fuse() { let mut it = 0..3; From d6e28676329cef9b39af86f5511d253982b4870c Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 12 Jan 2018 01:21:39 +0000 Subject: [PATCH 2/3] Add finite iterator specialisations for Cycle --- src/libcore/iter/mod.rs | 37 ++++++++++++++++++++++++++++++++++++- src/libcore/tests/iter.rs | 18 ++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 06c29b47bf921..5ec53139180ec 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -302,7 +302,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use cmp; +use cmp::{self, Ordering}; use fmt; use iter_private::TrustedRandomAccess; use ops::Try; @@ -643,6 +643,41 @@ impl Iterator for Cycle where I: Clone + Iterator { _ => (usize::MAX, None) } } + + #[inline] + fn all(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool { self.orig.clone().all(f) } + + #[inline] + fn max(self) -> Option where Self::Item: cmp::Ord { self.orig.clone().max() } + + #[inline] + fn min(self) -> Option where Self::Item: cmp::Ord { + cmp::min(self.iter.min(), self.orig.clone().min()) + } + + #[inline] + fn max_by_key(self, f: F) -> Option + where F: FnMut(&Self::Item) -> B { + self.orig.clone().max_by_key(f) + } + + #[inline] + fn max_by(self, f: F) -> Option + where F: FnMut(&Self::Item, &Self::Item) -> Ordering { + self.orig.clone().max_by(f) + } + + #[inline] + fn min_by_key(self, f: F) -> Option + where F: FnMut(&Self::Item) -> B { + self.iter.chain(self.orig.clone()).min_by_key(f) + } + + #[inline] + fn min_by(self, f: F) -> Option + where F: FnMut(&Self::Item, &Self::Item) -> Ordering { + self.iter.chain(self.orig.clone()).min_by(f) + } } #[unstable(feature = "fused", issue = "35602")] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index e34580aa8c66a..56dc5825dcbd2 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -867,6 +867,20 @@ fn test_cycle() { assert_eq!(it.next(), None); } +#[test] +fn test_cycle_iterator() { + let a = 1; + let b = 5; + let mut it = (a..b).cycle(); + assert_eq!(it.all(|x| x <= b), true); + assert_eq!((a..b).cycle().max(), Some(b - 1)); + assert_eq!((a..b).cycle().min(), Some(a)); + assert_eq!((a..b).cycle().max_by_key(|x| -x), Some(a)); + assert_eq!((a..b).cycle().max_by(|x, y| y.cmp(x)), Some(a)); + assert_eq!((a..b).cycle().min_by_key(|x| -x), Some(b - 1)); + assert_eq!((a..b).cycle().min_by(|x, y| y.cmp(x)), Some(b - 1)); +} + #[test] fn test_iterator_nth() { let v: &[_] = &[0, 1, 2, 3, 4]; @@ -1414,9 +1428,9 @@ fn test_repeat_iterator() { assert_eq!(repeat(42).max(), Some(42)); assert_eq!(repeat(42).min(), Some(42)); assert_eq!(repeat(42).max_by_key(|_| 0), Some(42)); - assert_eq!(repeat(42).max_by_key(|_| Ordering::Greater), Some(42)); + assert_eq!(repeat(42).max_by(|_, _| Ordering::Equal), Some(42)); assert_eq!(repeat(42).min_by_key(|_| 0), Some(42)); - assert_eq!(repeat(42).min_by_key(|_| Ordering::Greater), Some(42)); + assert_eq!(repeat(42).min_by(|_, _| Ordering::Equal), Some(42)); } #[test] From 71322b1eff3348b8767d72892f6636244992310e Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 12 Jan 2018 11:49:11 +0000 Subject: [PATCH 3/3] Fix issues with `all` --- src/libcore/iter/mod.rs | 4 +++- src/libcore/iter/sources.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 5ec53139180ec..7592284f9b135 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -645,7 +645,9 @@ impl Iterator for Cycle where I: Clone + Iterator { } #[inline] - fn all(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool { self.orig.clone().all(f) } + fn all(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool { + self.iter.clone().chain(self.orig.clone()).all(f) + } #[inline] fn max(self) -> Option where Self::Item: cmp::Ord { self.orig.clone().max() } diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 6258919b7c298..cb41e65790765 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -40,7 +40,7 @@ impl Iterator for Repeat { fn nth(&mut self, _: usize) -> Option { self.next() } #[inline] - fn all(&mut self, f: F) -> bool where F: FnMut(A) -> bool { self.any(f) } + fn all(&mut self, mut f: F) -> bool where F: FnMut(A) -> bool { f(self.element.clone()) } #[inline] fn max(mut self) -> Option { self.next() }