diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-03-21 19:33:27 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-03-23 16:55:43 -0400 |
| commit | b4d4daf007753dfb04d87b1ffe1c2ad2d8811d5a (patch) | |
| tree | c35d3d74c271c4ec72678d9d866bcad331a9e706 /src/libcore | |
| parent | bc1dde468c1613743c919cb9f33923cc9916c5b4 (diff) | |
| download | rust-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.rs | 6 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 201 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 78 |
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 + } } } |
