summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-03-21 19:33:27 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-03-23 16:55:43 -0400
commitb4d4daf007753dfb04d87b1ffe1c2ad2d8811d5a (patch)
treec35d3d74c271c4ec72678d9d866bcad331a9e706 /src/libcore
parentbc1dde468c1613743c919cb9f33923cc9916c5b4 (diff)
downloadrust-b4d4daf007753dfb04d87b1ffe1c2ad2d8811d5a.tar.gz
rust-b4d4daf007753dfb04d87b1ffe1c2ad2d8811d5a.zip
Adjust Index/IndexMut impls. For generic collections, we take
references. For collections whose keys are integers, we take both
references and by-value.
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/ops.rs6
-rw-r--r--src/libcore/slice.rs201
-rw-r--r--src/libcore/str/mod.rs78
3 files changed, 282 insertions, 3 deletions
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index e1e352b5b64..6e6f97a7af7 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -898,7 +898,7 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
 ///         println!("Indexing!");
 ///         self
 ///     }
@@ -945,13 +945,13 @@ pub trait Index<Idx: ?Sized> {
 /// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
 ///         self
 ///     }
 /// }
 ///
 /// impl IndexMut<Bar> for Foo {
-///     fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo {
+///     fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
 ///         println!("Indexing!");
 ///         self
 ///     }
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 907b2eba80c..04b425416f3 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -263,6 +263,7 @@ impl<T> SliceExt for [T] {
     #[inline]
     fn as_mut_slice(&mut self) -> &mut [T] { self }
 
+    #[cfg(stage0)]
     #[inline]
     fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
         unsafe {
@@ -273,6 +274,17 @@ impl<T> SliceExt for [T] {
         }
     }
 
+    #[cfg(not(stage0))]
+    #[inline]
+    fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+        unsafe {
+            let self2: &mut [T] = mem::transmute_copy(&self);
+
+            (ops::IndexMut::index_mut(self, ops::RangeTo { end: mid } ),
+             ops::IndexMut::index_mut(self2, ops::RangeFrom { start: mid } ))
+        }
+    }
+
     #[inline]
     fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
         unsafe {
@@ -495,25 +507,45 @@ impl<T> SliceExt for [T] {
 impl<T> ops::Index<usize> for [T] {
     type Output = T;
 
+    #[cfg(stage0)]
     fn index(&self, &index: &usize) -> &T {
         assert!(index < self.len());
 
         unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
     }
+
+    #[cfg(not(stage0))]
+    fn index(&self, index: usize) -> &T {
+        assert!(index < self.len());
+
+        unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<usize> for [T] {
+    #[cfg(stage0)]
+    #[inline]
     fn index_mut(&mut self, &index: &usize) -> &mut T {
         assert!(index < self.len());
 
         unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: usize) -> &mut T {
+        assert!(index < self.len());
+
+        unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::Range<usize>> for [T] {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::Range<usize>) -> &[T] {
         assert!(index.start <= index.end);
@@ -525,34 +557,72 @@ impl<T> ops::Index<ops::Range<usize>> for [T] {
             )
         }
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
+        assert!(index.start <= index.end);
+        assert!(index.end <= self.len());
+        unsafe {
+            from_raw_parts (
+                self.as_ptr().offset(index.start as isize),
+                index.end - index.start
+            )
+        }
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeTo<usize>> for [T] {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
         self.index(&ops::Range{ start: 0, end: index.end })
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
+        self.index(ops::Range{ start: 0, end: index.end })
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeFrom<usize>> for [T] {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
         self.index(&ops::Range{ start: index.start, end: self.len() })
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
+        self.index(ops::Range{ start: index.start, end: self.len() })
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<RangeFull> for [T] {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, _index: &RangeFull) -> &[T] {
         self
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, _index: RangeFull) -> &[T] {
+        self
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
         assert!(index.start <= index.end);
@@ -564,28 +634,64 @@ impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
             )
         }
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
+        assert!(index.start <= index.end);
+        assert!(index.end <= self.len());
+        unsafe {
+            from_raw_parts_mut(
+                self.as_mut_ptr().offset(index.start as isize),
+                index.end - index.start
+            )
+        }
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] {
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
         self.index_mut(&ops::Range{ start: 0, end: index.end })
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
+        self.index_mut(ops::Range{ start: 0, end: index.end })
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] {
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
         let len = self.len();
         self.index_mut(&ops::Range{ start: index.start, end: len })
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
+        let len = self.len();
+        self.index_mut(ops::Range{ start: index.start, end: len })
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<RangeFull> for [T] {
+
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
         self
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
+        self
+    }
 }
 
 
@@ -763,37 +869,69 @@ unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::Range<usize>> for Iter<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::Range<usize>) -> &[T] {
         self.as_slice().index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
+        self.as_slice().index(index)
+    }
 }
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeTo<usize>> for Iter<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
         self.as_slice().index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
+        self.as_slice().index(index)
+    }
 }
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeFrom<usize>> for Iter<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
         self.as_slice().index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
+        self.as_slice().index(index)
+    }
 }
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<RangeFull> for Iter<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, _index: &RangeFull) -> &[T] {
         self.as_slice()
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, _index: RangeFull) -> &[T] {
+        self.as_slice()
+    }
 }
 
 impl<'a, T> Iter<'a, T> {
@@ -856,63 +994,126 @@ unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::Range<usize>> for IterMut<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::Range<usize>) -> &[T] {
         self.index(&RangeFull).index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeTo<usize>> for IterMut<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
         self.index(&RangeFull).index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeFrom<usize>> for IterMut<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
         self.index(&RangeFull).index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, _index: &RangeFull) -> &[T] {
         make_slice!(T => &[T]: self.ptr, self.end)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, _index: RangeFull) -> &[T] {
+        make_slice!(T => &[T]: self.ptr, self.end)
+    }
 }
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::Range<usize>> for IterMut<'a, T> {
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
         self.index_mut(&RangeFull).index_mut(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::RangeTo<usize>> for IterMut<'a, T> {
+
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
         self.index_mut(&RangeFull).index_mut(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::RangeFrom<usize>> for IterMut<'a, T> {
+
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
         self.index_mut(&RangeFull).index_mut(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
+
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
         make_mut_slice!(T => &mut [T]: self.ptr, self.end)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
+        make_mut_slice!(T => &mut [T]: self.ptr, self.end)
+    }
 }
 
 
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index e8181395b5c..b9a655c6d4e 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1203,6 +1203,7 @@ mod traits {
     /// // byte 100 is outside the string
     /// // &s[3 .. 100];
     /// ```
+    #[cfg(stage0)]
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::Range<usize>> for str {
         type Output = str;
@@ -1219,6 +1220,49 @@ mod traits {
         }
     }
 
+    /// Returns a slice of the given string from the byte range
+    /// [`begin`..`end`).
+    ///
+    /// This operation is `O(1)`.
+    ///
+    /// Panics when `begin` and `end` do not point to valid characters
+    /// or point beyond the last character of the string.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    /// assert_eq!(&s[0 .. 1], "L");
+    ///
+    /// assert_eq!(&s[1 .. 9], "öwe 老");
+    ///
+    /// // these will panic:
+    /// // byte 2 lies within `ö`:
+    /// // &s[2 ..3];
+    ///
+    /// // byte 8 lies within `老`
+    /// // &s[1 .. 8];
+    ///
+    /// // byte 100 is outside the string
+    /// // &s[3 .. 100];
+    /// ```
+    #[cfg(not(stage0))]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl ops::Index<ops::Range<usize>> for str {
+        type Output = str;
+        #[inline]
+        fn index(&self, index: ops::Range<usize>) -> &str {
+            // is_char_boundary checks that the index is in [0, .len()]
+            if index.start <= index.end &&
+               self.is_char_boundary(index.start) &&
+               self.is_char_boundary(index.end) {
+                unsafe { self.slice_unchecked(index.start, index.end) }
+            } else {
+                super::slice_error_fail(self, index.start, index.end)
+            }
+        }
+    }
+
     /// Returns a slice of the string from the beginning to byte
     /// `end`.
     ///
@@ -1229,6 +1273,8 @@ mod traits {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeTo<usize>> for str {
         type Output = str;
+
+        #[cfg(stage0)]
         #[inline]
         fn index(&self, index: &ops::RangeTo<usize>) -> &str {
             // is_char_boundary checks that the index is in [0, .len()]
@@ -1238,6 +1284,17 @@ mod traits {
                 super::slice_error_fail(self, 0, index.end)
             }
         }
+
+        #[cfg(not(stage0))]
+        #[inline]
+        fn index(&self, index: ops::RangeTo<usize>) -> &str {
+            // is_char_boundary checks that the index is in [0, .len()]
+            if self.is_char_boundary(index.end) {
+                unsafe { self.slice_unchecked(0, index.end) }
+            } else {
+                super::slice_error_fail(self, 0, index.end)
+            }
+        }
     }
 
     /// Returns a slice of the string from `begin` to its end.
@@ -1249,6 +1306,8 @@ mod traits {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeFrom<usize>> for str {
         type Output = str;
+
+        #[cfg(stage0)]
         #[inline]
         fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
             // is_char_boundary checks that the index is in [0, .len()]
@@ -1258,15 +1317,34 @@ mod traits {
                 super::slice_error_fail(self, index.start, self.len())
             }
         }
+
+        #[cfg(not(stage0))]
+        #[inline]
+        fn index(&self, index: ops::RangeFrom<usize>) -> &str {
+            // is_char_boundary checks that the index is in [0, .len()]
+            if self.is_char_boundary(index.start) {
+                unsafe { self.slice_unchecked(index.start, self.len()) }
+            } else {
+                super::slice_error_fail(self, index.start, self.len())
+            }
+        }
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeFull> for str {
         type Output = str;
+
+        #[cfg(stage0)]
         #[inline]
         fn index(&self, _index: &ops::RangeFull) -> &str {
             self
         }
+
+        #[cfg(not(stage0))]
+        #[inline]
+        fn index(&self, _index: ops::RangeFull) -> &str {
+            self
+        }
     }
 }