about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-01 19:07:11 +0000
committerbors <bors@rust-lang.org>2015-02-01 19:07:11 +0000
commitc2bda2a5bb55e2ed54fecd2a03b133bb108e66e7 (patch)
tree7ea0304042dc35d8bd08991b4d9a509b06c3f3be /src/libcore
parent76ce1ea42158b5be3f3896df708602918d202947 (diff)
parentb9c055cc70816585ccd715f24b5fc965fe286174 (diff)
downloadrust-c2bda2a5bb55e2ed54fecd2a03b133bb108e66e7.tar.gz
rust-c2bda2a5bb55e2ed54fecd2a03b133bb108e66e7.zip
Auto merge of #21806 - edwardw:new-range-impl, r=alexcrichton
The new `::ops::Range` has separated implementations for each of the
numeric types, while the old `::iter::Range` has one for type `Int`.
However, we do not take output bindings into account when selecting
traits. So it confuses `typeck` and makes the new range does not work as
good as the old one when it comes to type inference.

This patch implements `Iterator` for the new range for one type `Int`.
This limitation could be lifted, however, if we ever reconsider the
output types' role in type inference.

Closes #21595
Closes #21649
Closes #21672
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/iter.rs116
1 files changed, 47 insertions, 69 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 751b5959d8b..c782452d4cf 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2797,93 +2797,71 @@ impl<A: Int> Iterator for RangeStepInclusive<A> {
     }
 }
 
-macro_rules! range_impl {
+macro_rules! range_exact_iter_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl Iterator for ::ops::Range<$t> {
-            type Item = $t;
-
+        impl ExactSizeIterator for ::ops::Range<$t> {
             #[inline]
-            fn next(&mut self) -> Option<$t> {
-                if self.start < self.end {
-                    let result = self.start;
-                    self.start += 1;
-                    return Some(result);
-                }
-
-                return None;
-            }
-
-            #[inline]
-            fn size_hint(&self) -> (usize, Option<usize>) {
+            fn len(&self) -> usize {
                 debug_assert!(self.end >= self.start);
-                let hint = (self.end - self.start) as usize;
-                (hint, Some(hint))
+                (self.end - self.start) as usize
             }
         }
-
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl ExactSizeIterator for ::ops::Range<$t> {}
     )*)
 }
 
-macro_rules! range_impl_no_hint {
-    ($($t:ty)*) => ($(
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl Iterator for ::ops::Range<$t> {
-            type Item = $t;
-
-            #[inline]
-            fn next(&mut self) -> Option<$t> {
-                if self.start < self.end {
-                    let result = self.start;
-                    self.start += 1;
-                    return Some(result);
-                }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Int> Iterator for ::ops::Range<A> {
+    type Item = A;
 
-                return None;
-            }
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        if self.start < self.end {
+            let result = self.start;
+            self.start = self.start + Int::one();
+            Some(result)
+        } else {
+            None
         }
-    )*)
-}
-
-macro_rules! range_other_impls {
-    ($($t:ty)*) => ($(
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl DoubleEndedIterator for ::ops::Range<$t> {
-            #[inline]
-            fn next_back(&mut self) -> Option<$t> {
-                if self.start < self.end {
-                    self.end -= 1;
-                    return Some(self.end);
-                }
+    }
 
-                return None;
-            }
-        }
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        debug_assert!(self.end >= self.start);
+        let hint = (self.end - self.start).to_uint();
+        (hint.unwrap_or(0), hint)
+    }
+}
 
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl Iterator for ::ops::RangeFrom<$t> {
-            type Item = $t;
+range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
+#[cfg(target_pointer_width = "64")]
+range_exact_iter_impl!(u64 i64);
 
-            #[inline]
-            fn next(&mut self) -> Option<$t> {
-                let result = self.start;
-                self.start += 1;
-                debug_assert!(result < self.start);
-                return Some(result);
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Int> DoubleEndedIterator for ::ops::Range<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        if self.start < self.end {
+            self.end = self.end - Int::one();
+            Some(self.end)
+        } else {
+            None
         }
-    )*)
+    }
 }
 
-range_impl!(usize u8 u16 u32 isize i8 i16 i32);
-#[cfg(target_pointer_width = "64")]
-range_impl!(u64 i64);
-#[cfg(target_pointer_width = "32")]
-range_impl_no_hint!(u64 i64);
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Int> Iterator for ::ops::RangeFrom<A> {
+    type Item = A;
 
-range_other_impls!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        let result = self.start;
+        self.start = self.start + Int::one();
+        debug_assert!(result < self.start);
+        Some(result)
+    }
+}
 
 /// An iterator that repeats an element endlessly
 #[derive(Clone)]