From 5a909a6a62fedb897c152d90a339c0a58b3685da Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Mon, 5 Feb 2018 23:11:15 +0100 Subject: [PATCH 1/2] optimize Range[Inclusive].count() --- src/libcore/iter/range.rs | 49 +++++++++++++++++++++++++++++++++++++++ src/libcore/tests/iter.rs | 7 ++++++ 2 files changed, 56 insertions(+) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 3b034efcce14c..2b052db21e2fa 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -268,6 +268,31 @@ impl Iterator for ops::Range { } } +macro_rules! impl_range_count { + ($t:ty) => { + #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] + impl Iterator for ops::Range<$t> { + #[inline] + fn count(self) -> usize { + self.end.wrapping_sub(self.start) as usize + } + } + }; +} + +impl_range_count!(u8); +impl_range_count!(u16); +impl_range_count!(u32); +impl_range_count!(u64); +impl_range_count!(usize); + +impl_range_count!(i8); +impl_range_count!(i16); +impl_range_count!(i32); +impl_range_count!(i64); +impl_range_count!(isize); + + // These macros generate `ExactSizeIterator` impls for various range types. // Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded // because they cannot guarantee having a length <= usize::MAX, which is @@ -421,6 +446,30 @@ impl Iterator for ops::RangeInclusive { } } +macro_rules! impl_inclusive_range_count { + ($t:ty) => { + #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] + impl Iterator for ops::RangeInclusive<$t> { + #[inline] + fn count(self) -> usize { + (self.end.wrapping_sub(self.start) as usize).wrapping_add(1) + } + } + }; +} + +impl_inclusive_range_count!(u8); +impl_inclusive_range_count!(u16); +impl_inclusive_range_count!(u32); +impl_inclusive_range_count!(u64); +impl_inclusive_range_count!(usize); + +impl_inclusive_range_count!(i8); +impl_inclusive_range_count!(i16); +impl_inclusive_range_count!(i32); +impl_inclusive_range_count!(i64); +impl_inclusive_range_count!(isize); + #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] impl DoubleEndedIterator for ops::RangeInclusive { #[inline] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index dc866d180bfa0..8e9140595dce8 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1391,6 +1391,13 @@ fn test_range_inclusive_nth() { assert_eq!(r, 1..=0); // We may not want to document/promise this detail } +#[test] +fn test_range_inclusive_count() { + assert_eq!((1..=1).count(), 1); + assert_eq!((0..=10).count(), 11); + assert_eq!((5..=7).count(), 3); +} + #[test] fn test_range_step() { #![allow(deprecated)] From 9ac41601a4631a333390534ef5767e612ad0d88d Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 6 Feb 2018 21:34:11 +0100 Subject: [PATCH 2/2] remove Range specialization, simplify RangeInclusive code --- src/libcore/iter/range.rs | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 2b052db21e2fa..0248c782910db 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -444,32 +444,14 @@ impl Iterator for ops::RangeInclusive { } Try::from_ok(accum) } -} -macro_rules! impl_inclusive_range_count { - ($t:ty) => { - #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] - impl Iterator for ops::RangeInclusive<$t> { - #[inline] - fn count(self) -> usize { - (self.end.wrapping_sub(self.start) as usize).wrapping_add(1) - } - } - }; + #[inline] + fn count(self) -> usize { + ::steps_between(&self.start, &self.end) + .expect("Overflow on `RangeInclusive::count()`") + 1 + } } -impl_inclusive_range_count!(u8); -impl_inclusive_range_count!(u16); -impl_inclusive_range_count!(u32); -impl_inclusive_range_count!(u64); -impl_inclusive_range_count!(usize); - -impl_inclusive_range_count!(i8); -impl_inclusive_range_count!(i16); -impl_inclusive_range_count!(i32); -impl_inclusive_range_count!(i64); -impl_inclusive_range_count!(isize); - #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] impl DoubleEndedIterator for ops::RangeInclusive { #[inline]