diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 0bf311e4d3f6e..b05b5e276e867 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -818,25 +818,31 @@ impl<'a> Add<&'a str> for String { } } -impl ops::Slice for String { +impl ops::Index, str> for String { #[inline] - fn as_slice_<'a>(&'a self) -> &'a str { - unsafe { mem::transmute(self.vec.as_slice()) } + fn index(&self, &index: &ops::Range) -> &str { + self[][*index] } +} +impl ops::Index, str> for String { #[inline] - fn slice_from_or_fail<'a>(&'a self, from: &uint) -> &'a str { - self[][*from..] + fn index(&self, &index: &ops::RangeTo) -> &str { + self[][*index] } +} +impl ops::Index, str> for String { #[inline] - fn slice_to_or_fail<'a>(&'a self, to: &uint) -> &'a str { - self[][..*to] + fn index(&self, &index: &ops::RangeFrom) -> &str { + self[][*index] } +} +impl ops::Index, str> for String { #[inline] - fn slice_or_fail<'a>(&'a self, from: &uint, to: &uint) -> &'a str { - self[][*from..*to] + fn index(&self, &index: &ops::FullRange) -> &str { + unsafe { mem::transmute(self.vec.as_slice()) } } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 99231e7253c3c..c057939df2b42 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1211,43 +1211,64 @@ impl IndexMut for Vec { impl ops::Slice for Vec { #[inline] - fn as_slice_<'a>(&'a self) -> &'a [T] { - self.as_slice() + fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T { + &mut self.as_mut_slice()[*index] } +} +impl ops::Index, [T]> for Vec { #[inline] - fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { - self.as_slice().slice_from_or_fail(start) + fn index(&self, &index: &ops::Range) -> &[T] { + self.as_slice().index(index) } +} +impl ops::Index, [T]> for Vec { #[inline] - fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { - self.as_slice().slice_to_or_fail(end) + fn index(&self, &index: &ops::RangeTo) -> &[T] { + self.as_slice().index(index) } +} + +impl ops::Index, [T]> for Vec { #[inline] - fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { - self.as_slice().slice_or_fail(start, end) + fn index(&self, &index: &ops::RangeFrom) -> &[T] { + self.as_slice().index(index) } } -impl ops::SliceMut for Vec { +impl ops::Index, [T]> for Vec { #[inline] - fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { - self.as_mut_slice() + fn index(&self, &index: &ops::FullRange) -> &[T] { + self.as_slice() } +} +impl ops::IndexMut, [T]> for Vec { #[inline] - fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { - self.as_mut_slice().slice_from_or_fail_mut(start) + fn index_mut(&mut self, &index: &ops::Range) -> &mut [T] { + self.as_mut_slice().index_mut(index) } +} +impl ops::IndexMut, [T]> for Vec { #[inline] - fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { - self.as_mut_slice().slice_to_or_fail_mut(end) + fn index_mut(&mut self, &index: &ops::RangeTo) -> &mut [T] { + self.as_mut_slice().index_mut(index) } +} + +impl ops::IndexMut, [T]> for Vec { #[inline] - fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { - self.as_mut_slice().slice_or_fail_mut(start, end) + fn index_mut(&mut self, &index: &ops::RangeFrom) -> &mut [T] { + self.as_mut_slice().index_mut(index) + } +} + +impl ops::IndexMut, [T]> for Vec { + #[inline] + fn index_mut(&mut self, &index: &ops::FullRange) -> &mut [T] { + self.as_mut_slice() } } diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 97d94e73bb33a..2a7e6eb47955d 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -846,105 +846,6 @@ pub trait IndexMut { fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output; } -/// The `Slice` trait is used to specify the functionality of slicing operations -/// like `arr[from..to]` when used in an immutable context. -/// -/// # Example -/// -/// A trivial implementation of `Slice`. When `Foo[..Foo]` happens, it ends up -/// calling `slice_to`, and therefore, `main` prints `Slicing!`. -/// -/// ```ignore -/// use std::ops::Slice; -/// -/// #[derive(Copy)] -/// struct Foo; -/// -/// impl Slice for Foo { -/// fn as_slice_<'a>(&'a self) -> &'a Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_from_or_fail<'a>(&'a self, _from: &Foo) -> &'a Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_to_or_fail<'a>(&'a self, _to: &Foo) -> &'a Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_or_fail<'a>(&'a self, _from: &Foo, _to: &Foo) -> &'a Foo { -/// println!("Slicing!"); -/// self -/// } -/// } -/// -/// fn main() { -/// Foo[..Foo]; -/// } -/// ``` -#[lang="slice"] -pub trait Slice { - /// The method for the slicing operation foo[] - fn as_slice_<'a>(&'a self) -> &'a Result; - /// The method for the slicing operation foo[from..] - fn slice_from_or_fail<'a>(&'a self, from: &Idx) -> &'a Result; - /// The method for the slicing operation foo[..to] - fn slice_to_or_fail<'a>(&'a self, to: &Idx) -> &'a Result; - /// The method for the slicing operation foo[from..to] - fn slice_or_fail<'a>(&'a self, from: &Idx, to: &Idx) -> &'a Result; -} - -/// The `SliceMut` trait is used to specify the functionality of slicing -/// operations like `arr[from..to]`, when used in a mutable context. -/// -/// # Example -/// -/// A trivial implementation of `SliceMut`. When `Foo[Foo..]` happens, it ends up -/// calling `slice_from_mut`, and therefore, `main` prints `Slicing!`. -/// -/// ```ignore -/// use std::ops::SliceMut; -/// -/// #[derive(Copy)] -/// struct Foo; -/// -/// impl SliceMut for Foo { -/// fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_from_or_fail_mut<'a>(&'a mut self, _from: &Foo) -> &'a mut Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_to_or_fail_mut<'a>(&'a mut self, _to: &Foo) -> &'a mut Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_or_fail_mut<'a>(&'a mut self, _from: &Foo, _to: &Foo) -> &'a mut Foo { -/// println!("Slicing!"); -/// self -/// } -/// } -/// -/// pub fn main() { -/// Foo[mut Foo..]; -/// } -/// ``` -#[lang="slice_mut"] -pub trait SliceMut { - /// The method for the slicing operation foo[] - fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Result; - /// The method for the slicing operation foo[from..] - fn slice_from_or_fail_mut<'a>(&'a mut self, from: &Idx) -> &'a mut Result; - /// The method for the slicing operation foo[..to] - fn slice_to_or_fail_mut<'a>(&'a mut self, to: &Idx) -> &'a mut Result; - /// The method for the slicing operation foo[from..to] - fn slice_or_fail_mut<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result; -} - - /// An unbounded range. #[derive(Copy)] #[lang="full_range"] @@ -962,8 +863,6 @@ pub struct Range { pub end: Idx, } -// FIXME(#19391) needs a snapshot -//impl> Iterator for Range { #[unstable = "API still in development"] impl Iterator for Range { type Item = Idx; diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index e88cb73c8a9b7..a560b68db01fa 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -30,7 +30,7 @@ // Reexported core operators pub use kinds::{Copy, Send, Sized, Sync}; -pub use ops::{Drop, Fn, FnMut, FnOnce}; +pub use ops::{Drop, Fn, FnMut, FnOnce, FullRange}; // Reexported functions pub use iter::range; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 093ed0b242f5f..369652b215f24 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -292,17 +292,17 @@ impl SliceExt for [T] { fn as_mut_slice(&mut self) -> &mut [T] { self } fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] { - ops::SliceMut::slice_or_fail_mut(self, &start, &end) + ops::IndexMut::index_mut(self, &ops::Range { start: start, end: end } ) } #[inline] fn slice_from_mut(&mut self, start: uint) -> &mut [T] { - ops::SliceMut::slice_from_or_fail_mut(self, &start) + ops::IndexMut::index_mut(self, &ops::RangeFrom { start: start } ) } #[inline] fn slice_to_mut(&mut self, end: uint) -> &mut [T] { - ops::SliceMut::slice_to_or_fail_mut(self, &end) + ops::IndexMut::index_mut(self, &ops::RangeTo { end: end } ) } #[inline] @@ -310,8 +310,8 @@ impl SliceExt for [T] { unsafe { let self2: &mut [T] = mem::transmute_copy(&self); - (ops::SliceMut::slice_to_or_fail_mut(self, &mid), - ops::SliceMut::slice_from_or_fail_mut(self2, &mid)) + (ops::IndexMut::index_mut(self, &ops::RangeTo { end: mid } ), + ops::IndexMut::index_mut(self2, &ops::RangeFrom { start: mid } )) } } @@ -551,63 +551,78 @@ impl ops::IndexMut for [T] { } } -impl ops::Slice for [T] { +impl ops::Index, [T]> for [T] { #[inline] - fn as_slice_<'a>(&'a self) -> &'a [T] { - self + fn index(&self, &index: &ops::Range) -> &[T] { + assert!(index.start <= index.end); + assert!(index.end <= self.len()); + unsafe { + transmute(RawSlice { + data: self.as_ptr().offset(index.start as int), + len: index.end - index.start + }) + } + } +} + +impl ops::Index, [T]> for [T] { + #[inline] + fn index(&self, &index: &ops::RangeTo) -> &[T] { + self.index(&ops::Range{ start: 0, end: index.end }) } +} +impl ops::Index, [T]> for [T] { #[inline] - fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { - self.slice_or_fail(start, &self.len()) + fn index(&self, &index: &ops::RangeFrom) -> &[T] { + self.index(&ops::Range{ start: index.start, end: self.len() }) } +} +impl ops::Index for [T] { #[inline] - fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { - self.slice_or_fail(&0, end) + fn index(&self, &index: &ops::FullRange) -> &[T] { + self } +} + +impl ops::IndexMut, [T]> for [T] { #[inline] - fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { - assert!(*start <= *end); - assert!(*end <= self.len()); + fn index_mut(&mut self, &index: &ops::Range) -> &mut [T] { + assert!(index.start <= index.end); + assert!(index.end <= self.len()); unsafe { transmute(RawSlice { - data: self.as_ptr().offset(*start as int), - len: (*end - *start) + data: self.as_ptr().offset(index.start as int), + len: index.end - index.start }) } } } -impl ops::SliceMut for [T] { +impl ops::IndexMut, [T]> for [T] { #[inline] - fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { - self + fn index_mut(&mut self, &index: &ops::RangeTo) -> &mut [T] { + self.index_mut(&ops::Range{ start: 0, end: index.end }) } +} +impl ops::IndexMut, [T]> for [T] { #[inline] - fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { - let len = &self.len(); - self.slice_or_fail_mut(start, len) + fn index_mut(&mut self, &index: &ops::RangeFrom) -> &mut [T] { + let len = self.len(); + self.index_mut(&ops::Range{ start: index.start, end: len }) } +} +impl ops::IndexMut for [T] { #[inline] - fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { - self.slice_or_fail_mut(&0, end) - } - #[inline] - fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { - assert!(*start <= *end); - assert!(*end <= self.len()); - unsafe { - transmute(RawSlice { - data: self.as_ptr().offset(*start as int), - len: (*end - *start) - }) - } + fn index_mut(&mut self, &index: &ops::FullRange) -> &mut [T] { + self } } + //////////////////////////////////////////////////////////////////////////////// // Common traits //////////////////////////////////////////////////////////////////////////////// @@ -738,24 +753,38 @@ pub struct Iter<'a, T: 'a> { } #[experimental] -impl<'a, T> ops::Slice for Iter<'a, T> { - fn as_slice_(&self) -> &[T] { - self.as_slice() +impl<'a, T> ops::Index, [T]> for Iter<'a, T> { + #[inline] + fn index(&self, index: &ops::Range) -> &[T] { + self.as_slice().index(index) } - fn slice_from_or_fail<'b>(&'b self, from: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice().slice_from_or_fail(from) +} + +#[experimental] +impl<'a, T> ops::Index, [T]> for Iter<'a, T> { + #[inline] + fn index(&self, index: &ops::RangeTo) -> &[T] { + self.as_slice().index(index) } - fn slice_to_or_fail<'b>(&'b self, to: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice().slice_to_or_fail(to) +} + +#[experimental] +impl<'a, T> ops::Index, [T]> for Iter<'a, T> { + #[inline] + fn index(&self, index: &ops::RangeFrom) -> &[T] { + self.as_slice().index(index) } - fn slice_or_fail<'b>(&'b self, from: &uint, to: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice().slice_or_fail(from, to) +} + +#[experimental] +impl<'a, T> ops::Index for Iter<'a, T> { + #[inline] + fn index(&self, index: &ops::FullRange) -> &[T] { + self.as_slice() } } + impl<'a, T> Iter<'a, T> { /// View the underlying data as a subslice of the original data. /// @@ -813,43 +842,70 @@ pub struct IterMut<'a, T: 'a> { } #[experimental] -impl<'a, T> ops::Slice for IterMut<'a, T> { - fn as_slice_<'b>(&'b self) -> &'b [T] { - make_slice!(T -> &'b [T]: self.ptr, self.end) +impl<'a, T> ops::Index, [T]> for IterMut<'a, T> { + #[inline] + fn index(&self, index: &ops::Range) -> &[T] { + self.index(&ops::FullRange).index(index) } - fn slice_from_or_fail<'b>(&'b self, from: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice_().slice_from_or_fail(from) +} + +#[experimental] +impl<'a, T> ops::Index, [T]> for IterMut<'a, T> { + #[inline] + fn index(&self, index: &ops::RangeTo) -> &[T] { + self.index(&ops::FullRange).index(index) } - fn slice_to_or_fail<'b>(&'b self, to: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice_().slice_to_or_fail(to) +} + +#[experimental] +impl<'a, T> ops::Index, [T]> for IterMut<'a, T> { + #[inline] + fn index(&self, index: &ops::RangeFrom) -> &[T] { + self.index(&ops::FullRange).index(index) } - fn slice_or_fail<'b>(&'b self, from: &uint, to: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice_().slice_or_fail(from, to) +} + +#[experimental] +impl<'a, T> ops::Index for IterMut<'a, T> { + #[inline] + fn index(&self, index: &ops::FullRange) -> &[T] { + make_slice!(T -> &[T]: self.ptr, self.end) } } #[experimental] -impl<'a, T> ops::SliceMut for IterMut<'a, T> { - fn as_mut_slice_<'b>(&'b mut self) -> &'b mut [T] { - make_slice!(T -> &'b mut [T]: self.ptr, self.end) +impl<'a, T> ops::IndexMut, [T]> for IterMut<'a, T> { + #[inline] + fn index_mut(&mut self, index: &ops::Range) -> &mut [T] { + self.index_mut(&ops::FullRange).index_mut(index) } - fn slice_from_or_fail_mut<'b>(&'b mut self, from: &uint) -> &'b mut [T] { - use ops::SliceMut; - self.as_mut_slice_().slice_from_or_fail_mut(from) +} + +#[experimental] +impl<'a, T> ops::IndexMut, [T]> for IterMut<'a, T> { + #[inline] + fn index_mut(&mut self, index: &ops::RangeTo) -> &mut [T] { + self.index_mut(&ops::FullRange).index_mut(index) } - fn slice_to_or_fail_mut<'b>(&'b mut self, to: &uint) -> &'b mut [T] { - use ops::SliceMut; - self.as_mut_slice_().slice_to_or_fail_mut(to) +} + +#[experimental] +impl<'a, T> ops::IndexMut, [T]> for IterMut<'a, T> { + #[inline] + fn index_mut(&mut self, index: &ops::RangeFrom) -> &mut [T] { + self.index_mut(&ops::FullRange).index_mut(index) } - fn slice_or_fail_mut<'b>(&'b mut self, from: &uint, to: &uint) -> &'b mut [T] { - use ops::SliceMut; - self.as_mut_slice_().slice_or_fail_mut(from, to) +} + +#[experimental] +impl<'a, T> ops::IndexMut for IterMut<'a, T> { + #[inline] + fn index_mut(&mut self, index: &ops::FullRange) -> &mut [T] { + make_slice!(T -> &mut [T]: self.ptr, self.end) } } + impl<'a, T> IterMut<'a, T> { /// View the underlying data as a subslice of the original data. /// diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index a39787b8207b5..a28e56144177e 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1119,25 +1119,31 @@ mod traits { } } - impl ops::Slice for str { + impl ops::Index, str> for str { #[inline] - fn as_slice_<'a>(&'a self) -> &'a str { - self + fn index(&self, &index: &ops::Range) -> &str { + self.slice(index.start, index.end) } + } + impl ops::Index, str> for str { #[inline] - fn slice_from_or_fail<'a>(&'a self, from: &uint) -> &'a str { - self.slice_from(*from) + fn index(&self, &index: &ops::RangeTo) -> &str { + self.slice_to(index.end) } + } + impl ops::Index, str> for str { #[inline] - fn slice_to_or_fail<'a>(&'a self, to: &uint) -> &'a str { - self.slice_to(*to) + fn index(&self, &index: &ops::RangeFrom) -> &str { + self.slice_from(index.start) } + } + impl ops::Index for str { #[inline] - fn slice_or_fail<'a>(&'a self, from: &uint, to: &uint) -> &'a str { - self.slice(*from, *to) + fn index(&self, &index: &ops::FullRange) -> &str { + self } } }