Add max and sum specialisations for Range

This commit is contained in:
varkor
2018-01-04 01:51:18 +00:00
parent 3d9c36fbf5
commit 29e6b1034b

View File

@@ -13,7 +13,7 @@ use mem;
use ops::{self, Add, Sub}; use ops::{self, Add, Sub};
use usize; use usize;
use super::{FusedIterator, TrustedLen}; use super::{FusedIterator, TrustedLen, Sum};
/// Objects that can be stepped over in both directions. /// Objects that can be stepped over in both directions.
/// ///
@@ -177,6 +177,20 @@ step_impl_signed!([i64: u64]);
step_impl_no_between!(u64 i64); step_impl_no_between!(u64 i64);
step_impl_no_between!(u128 i128); step_impl_no_between!(u128 i128);
macro_rules! range_inc_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for ops::RangeInclusive<$t> {
#[inline]
fn sum<S>(self) -> S where S: Sum<$t> {
let a = self.start;
let b = self.end;
S::sum(super::once((a + b) * (1 + b - a) / 2))
}
}
)*)
}
macro_rules! range_exact_iter_impl { macro_rules! range_exact_iter_impl {
($($t:ty)*) => ($( ($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@@ -251,7 +265,17 @@ impl<A: Step> Iterator for ops::Range<A> {
self.start = self.end.clone(); self.start = self.end.clone();
None None
} }
#[inline]
fn max(self) -> Option<A> {
if self.start != self.end {
Some(self.end.sub_one())
} else { None }
} }
}
// These macros generate specialisations for `Iterator` methods for efficiency purposes.
range_inc_iter_impl!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
// These macros generate `ExactSizeIterator` impls for various range types. // These macros generate `ExactSizeIterator` impls for various range types.
// Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded // Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded