]> git.lizzy.rs Git - rust.git/commitdiff
Add max and sum specialisations for Range
authorvarkor <github@varkor.com>
Thu, 4 Jan 2018 01:51:18 +0000 (01:51 +0000)
committervarkor <github@varkor.com>
Thu, 4 Jan 2018 01:51:18 +0000 (01:51 +0000)
src/libcore/iter/range.rs

index 280f0eafcf026e2f26ba2019bd538c965d4d7dcb..ecc288d07fcef6e116057b3ac0d62f678a5dd3db 100644 (file)
@@ -13,7 +13,7 @@
 use ops::{self, Add, Sub};
 use usize;
 
-use super::{FusedIterator, TrustedLen};
+use super::{FusedIterator, TrustedLen, Sum};
 
 /// Objects that can be stepped over in both directions.
 ///
@@ -177,6 +177,20 @@ fn add_usize(&self, n: usize) -> Option<Self> {
 step_impl_no_between!(u64 i64);
 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 {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -251,8 +265,18 @@ fn nth(&mut self, n: usize) -> Option<A> {
         self.start = self.end.clone();
         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.
 // Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded
 // because they cannot guarantee having a length <= usize::MAX, which is