auto merge of #18291 : japaric/rust/dstify, r=aturon

This PR changes the signature of several methods from `foo(self, ...)` to `foo(&self, ...)`/`foo(&mut self, ...)`, but there is no breakage of the usage of these methods due to the autoref nature of `method.call()`s. This PR also removes the lifetime parameter from some traits (`Trait<'a>` -> `Trait`). These changes break any use of the extension traits for generic programming, but those traits are not meant to be used for generic programming in the first place. In the whole rust distribution there was only one misuse of a extension trait as a bound, which got corrected (the bound was unnecessary and got removed) as part of this PR.

I've kept the commits as small and self-contained as possible for reviewing sake, but I can squash them when the review is over.

See this [table] to get an idea of what's left to be done. I've already DSTified [`Show`][show] and I'm working on `Hash`, but bootstrapping those changes seem to require a more recent snapshot (#18259 does the trick)

r? @aturon 
cc #16918 

[show]: https://github.com/japaric/rust/commits/show
[table]: https://docs.google.com/spreadsheets/d/1MZ_iSNuzsoqeS-mtLXnj9m0hBYaH5jI8k9G_Ud8FT5g/edit?usp=sharing
This commit is contained in:
bors 2014-10-28 19:56:56 +00:00
commit 98bbccf2c7
8 changed files with 235 additions and 230 deletions

View File

@ -89,6 +89,7 @@
use alloc::boxed::Box; use alloc::boxed::Box;
use core::cmp; use core::cmp;
use core::kinds::Sized;
use core::mem::size_of; use core::mem::size_of;
use core::mem; use core::mem;
use core::prelude::{Clone, Collection, Greater, Iterator, Less, None, Option}; use core::prelude::{Clone, Collection, Greater, Iterator, Less, None, Option};
@ -109,7 +110,7 @@ pub use core::slice::{Found, NotFound};
// Functional utilities // Functional utilities
#[allow(missing_doc)] #[allow(missing_doc)]
pub trait VectorVector<T> { pub trait VectorVector<T> for Sized? {
// FIXME #5898: calling these .concat and .connect conflicts with // FIXME #5898: calling these .concat and .connect conflicts with
// StrVector::con{cat,nect}, since they have generic contents. // StrVector::con{cat,nect}, since they have generic contents.
/// Flattens a vector of vectors of `T` into a single `Vec<T>`. /// Flattens a vector of vectors of `T` into a single `Vec<T>`.
@ -119,7 +120,7 @@ pub trait VectorVector<T> {
fn connect_vec(&self, sep: &T) -> Vec<T>; fn connect_vec(&self, sep: &T) -> Vec<T>;
} }
impl<'a, T: Clone, V: AsSlice<T>> VectorVector<T> for &'a [V] { impl<T: Clone, V: AsSlice<T>> VectorVector<T> for [V] {
fn concat_vec(&self) -> Vec<T> { fn concat_vec(&self) -> Vec<T> {
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len()); let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
let mut result = Vec::with_capacity(size); let mut result = Vec::with_capacity(size);
@ -267,17 +268,17 @@ impl<T: Clone> Iterator<Vec<T>> for Permutations<T> {
} }
/// Extension methods for vector slices with cloneable elements /// Extension methods for vector slices with cloneable elements
pub trait CloneableVector<T> { pub trait CloneableVector<T> for Sized? {
/// Copies `self` into a new `Vec`. /// Copies `self` into a new `Vec`.
fn to_vec(&self) -> Vec<T>; fn to_vec(&self) -> Vec<T>;
} }
impl<'a, T: Clone> CloneableVector<T> for &'a [T] { impl<T: Clone> CloneableVector<T> for [T] {
/// Returns a copy of `v`. /// Returns a copy of `v`.
#[inline] #[inline]
fn to_vec(&self) -> Vec<T> { fn to_vec(&self) -> Vec<T> {
let mut vector = Vec::with_capacity(self.len()); let mut vector = Vec::with_capacity(self.len());
vector.push_all(*self); vector.push_all(self);
vector vector
} }
} }
@ -300,7 +301,7 @@ impl<T> BoxedSlice<T> for Box<[T]> {
} }
/// Extension methods for vectors containing `Clone` elements. /// Extension methods for vectors containing `Clone` elements.
pub trait ImmutableCloneableVector<T> { pub trait ImmutableCloneableVector<T> for Sized? {
/// Partitions the vector into two vectors `(a, b)`, where all /// Partitions the vector into two vectors `(a, b)`, where all
/// elements of `a` satisfy `f` and all elements of `b` do not. /// elements of `a` satisfy `f` and all elements of `b` do not.
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>); fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
@ -329,10 +330,10 @@ pub trait ImmutableCloneableVector<T> {
/// assert_eq!(Some(vec![1i, 3, 2]), perms.next()); /// assert_eq!(Some(vec![1i, 3, 2]), perms.next());
/// assert_eq!(Some(vec![3i, 1, 2]), perms.next()); /// assert_eq!(Some(vec![3i, 1, 2]), perms.next());
/// ``` /// ```
fn permutations(self) -> Permutations<T>; fn permutations(&self) -> Permutations<T>;
} }
impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] { impl<T: Clone> ImmutableCloneableVector<T> for [T] {
#[inline] #[inline]
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) { fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
let mut lefts = Vec::new(); let mut lefts = Vec::new();
@ -350,7 +351,7 @@ impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
} }
/// Returns an iterator over all permutations of a vector. /// Returns an iterator over all permutations of a vector.
fn permutations(self) -> Permutations<T> { fn permutations(&self) -> Permutations<T> {
Permutations{ Permutations{
swaps: ElementSwaps::new(self.len()), swaps: ElementSwaps::new(self.len()),
v: self.to_vec(), v: self.to_vec(),
@ -564,7 +565,7 @@ fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
/// Extension methods for vectors such that their elements are /// Extension methods for vectors such that their elements are
/// mutable. /// mutable.
pub trait MutableSliceAllocating<'a, T> { pub trait MutableSliceAllocating<T> for Sized? {
/// Sorts the slice, in place, using `compare` to compare /// Sorts the slice, in place, using `compare` to compare
/// elements. /// elements.
/// ///
@ -582,7 +583,7 @@ pub trait MutableSliceAllocating<'a, T> {
/// v.sort_by(|a, b| b.cmp(a)); /// v.sort_by(|a, b| b.cmp(a));
/// assert!(v == [5, 4, 3, 2, 1]); /// assert!(v == [5, 4, 3, 2, 1]);
/// ``` /// ```
fn sort_by(self, compare: |&T, &T| -> Ordering); fn sort_by(&mut self, compare: |&T, &T| -> Ordering);
/// Consumes `src` and moves as many elements as it can into `self` /// Consumes `src` and moves as many elements as it can into `self`
/// from the range [start,end). /// from the range [start,end).
@ -605,17 +606,17 @@ pub trait MutableSliceAllocating<'a, T> {
/// assert_eq!(num_moved, 3); /// assert_eq!(num_moved, 3);
/// assert!(a == [6i, 7, 8, 4, 5]); /// assert!(a == [6i, 7, 8, 4, 5]);
/// ``` /// ```
fn move_from(self, src: Vec<T>, start: uint, end: uint) -> uint; fn move_from(&mut self, src: Vec<T>, start: uint, end: uint) -> uint;
} }
impl<'a,T> MutableSliceAllocating<'a, T> for &'a mut [T] { impl<T> MutableSliceAllocating<T> for [T] {
#[inline] #[inline]
fn sort_by(self, compare: |&T, &T| -> Ordering) { fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
merge_sort(self, compare) merge_sort(self, compare)
} }
#[inline] #[inline]
fn move_from(self, mut src: Vec<T>, start: uint, end: uint) -> uint { fn move_from(&mut self, mut src: Vec<T>, start: uint, end: uint) -> uint {
for (a, b) in self.iter_mut().zip(src[mut start..end].iter_mut()) { for (a, b) in self.iter_mut().zip(src[mut start..end].iter_mut()) {
mem::swap(a, b); mem::swap(a, b);
} }
@ -625,7 +626,7 @@ impl<'a,T> MutableSliceAllocating<'a, T> for &'a mut [T] {
/// Methods for mutable vectors with orderable elements, such as /// Methods for mutable vectors with orderable elements, such as
/// in-place sorting. /// in-place sorting.
pub trait MutableOrdSlice<T> { pub trait MutableOrdSlice<T> for Sized? {
/// Sorts the slice, in place. /// Sorts the slice, in place.
/// ///
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
@ -638,7 +639,7 @@ pub trait MutableOrdSlice<T> {
/// v.sort(); /// v.sort();
/// assert!(v == [-5i, -3, 1, 2, 4]); /// assert!(v == [-5i, -3, 1, 2, 4]);
/// ``` /// ```
fn sort(self); fn sort(&mut self);
/// Mutates the slice to the next lexicographic permutation. /// Mutates the slice to the next lexicographic permutation.
/// ///
@ -656,7 +657,7 @@ pub trait MutableOrdSlice<T> {
/// let b: &mut [_] = &mut [1i, 0, 2]; /// let b: &mut [_] = &mut [1i, 0, 2];
/// assert!(v == b); /// assert!(v == b);
/// ``` /// ```
fn next_permutation(self) -> bool; fn next_permutation(&mut self) -> bool;
/// Mutates the slice to the previous lexicographic permutation. /// Mutates the slice to the previous lexicographic permutation.
/// ///
@ -674,16 +675,16 @@ pub trait MutableOrdSlice<T> {
/// let b: &mut [_] = &mut [0i, 1, 2]; /// let b: &mut [_] = &mut [0i, 1, 2];
/// assert!(v == b); /// assert!(v == b);
/// ``` /// ```
fn prev_permutation(self) -> bool; fn prev_permutation(&mut self) -> bool;
} }
impl<'a, T: Ord> MutableOrdSlice<T> for &'a mut [T] { impl<T: Ord> MutableOrdSlice<T> for [T] {
#[inline] #[inline]
fn sort(self) { fn sort(&mut self) {
self.sort_by(|a,b| a.cmp(b)) self.sort_by(|a, b| a.cmp(b))
} }
fn next_permutation(self) -> bool { fn next_permutation(&mut self) -> bool {
// These cases only have 1 permutation each, so we can't do anything. // These cases only have 1 permutation each, so we can't do anything.
if self.len() < 2 { return false; } if self.len() < 2 { return false; }
@ -713,7 +714,7 @@ impl<'a, T: Ord> MutableOrdSlice<T> for &'a mut [T] {
true true
} }
fn prev_permutation(self) -> bool { fn prev_permutation(&mut self) -> bool {
// These cases only have 1 permutation each, so we can't do anything. // These cases only have 1 permutation each, so we can't do anything.
if self.len() < 2 { return false; } if self.len() < 2 { return false; }

View File

@ -58,6 +58,7 @@ use core::default::Default;
use core::fmt; use core::fmt;
use core::cmp; use core::cmp;
use core::iter::AdditiveIterator; use core::iter::AdditiveIterator;
use core::kinds::Sized;
use core::prelude::{Char, Clone, Collection, Eq, Equiv, ImmutableSlice}; use core::prelude::{Char, Clone, Collection, Eq, Equiv, ImmutableSlice};
use core::prelude::{Iterator, MutableSlice, None, Option, Ord, Ordering}; use core::prelude::{Iterator, MutableSlice, None, Option, Ord, Ordering};
use core::prelude::{PartialEq, PartialOrd, Result, AsSlice, Some, Tuple2}; use core::prelude::{PartialEq, PartialOrd, Result, AsSlice, Some, Tuple2};
@ -84,7 +85,7 @@ Section: Creating a string
*/ */
/// Methods for vectors of strings. /// Methods for vectors of strings.
pub trait StrVector { pub trait StrVector for Sized? {
/// Concatenates a vector of strings. /// Concatenates a vector of strings.
/// ///
/// # Example /// # Example
@ -110,7 +111,7 @@ pub trait StrVector {
fn connect(&self, sep: &str) -> String; fn connect(&self, sep: &str) -> String;
} }
impl<'a, S: Str> StrVector for &'a [S] { impl<S: Str> StrVector for [S] {
fn concat(&self) -> String { fn concat(&self) -> String {
if self.is_empty() { if self.is_empty() {
return String::new(); return String::new();
@ -157,7 +158,7 @@ impl<'a, S: Str> StrVector for &'a [S] {
} }
} }
impl<'a, S: Str> StrVector for Vec<S> { impl<S: Str> StrVector for Vec<S> {
#[inline] #[inline]
fn concat(&self) -> String { fn concat(&self) -> String {
self.as_slice().concat() self.as_slice().concat()

View File

@ -19,6 +19,7 @@
//! Their definition should always match the ABI defined in `rustc::back::abi`. //! Their definition should always match the ABI defined in `rustc::back::abi`.
use mem; use mem;
use kinds::Sized;
/// The representation of a Rust slice /// The representation of a Rust slice
#[repr(C)] #[repr(C)]
@ -53,14 +54,14 @@ pub struct TraitObject {
/// This trait is meant to map equivalences between raw structs and their /// This trait is meant to map equivalences between raw structs and their
/// corresponding rust values. /// corresponding rust values.
pub trait Repr<T> { pub trait Repr<T> for Sized? {
/// This function "unwraps" a rust value (without consuming it) into its raw /// This function "unwraps" a rust value (without consuming it) into its raw
/// struct representation. This can be used to read/write different values /// struct representation. This can be used to read/write different values
/// for the struct. This is a safe method because by default it does not /// for the struct. This is a safe method because by default it does not
/// enable write-access to the fields of the return value in safe code. /// enable write-access to the fields of the return value in safe code.
#[inline] #[inline]
fn repr(&self) -> T { unsafe { mem::transmute_copy(self) } } fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } }
} }
impl<'a, T> Repr<Slice<T>> for &'a [T] {} impl<T> Repr<Slice<T>> for [T] {}
impl<'a> Repr<Slice<u8>> for &'a str {} impl Repr<Slice<u8>> for str {}

View File

@ -48,7 +48,7 @@ use ptr;
use ptr::RawPtr; use ptr::RawPtr;
use mem; use mem;
use mem::size_of; use mem::size_of;
use kinds::marker; use kinds::{Sized, marker};
use raw::Repr; use raw::Repr;
// Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module. // Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
use raw::Slice as RawSlice; use raw::Slice as RawSlice;
@ -60,7 +60,7 @@ use raw::Slice as RawSlice;
/// Extension methods for immutable slices. /// Extension methods for immutable slices.
#[unstable = "may merge with other traits; region parameter may disappear"] #[unstable = "may merge with other traits; region parameter may disappear"]
pub trait ImmutableSlice<'a, T> { pub trait ImmutableSlice<T> for Sized? {
/// Returns a subslice spanning the interval [`start`, `end`). /// Returns a subslice spanning the interval [`start`, `end`).
/// ///
/// Fails when the end of the new slice lies beyond the end of the /// Fails when the end of the new slice lies beyond the end of the
@ -68,7 +68,7 @@ pub trait ImmutableSlice<'a, T> {
/// ///
/// Slicing with `start` equal to `end` yields an empty slice. /// Slicing with `start` equal to `end` yields an empty slice.
#[unstable = "waiting on final error conventions/slicing syntax"] #[unstable = "waiting on final error conventions/slicing syntax"]
fn slice(&self, start: uint, end: uint) -> &'a [T]; fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T];
/// Returns a subslice from `start` to the end of the slice. /// Returns a subslice from `start` to the end of the slice.
/// ///
@ -76,7 +76,7 @@ pub trait ImmutableSlice<'a, T> {
/// ///
/// Slicing from `self.len()` yields an empty slice. /// Slicing from `self.len()` yields an empty slice.
#[unstable = "waiting on final error conventions/slicing syntax"] #[unstable = "waiting on final error conventions/slicing syntax"]
fn slice_from(&self, start: uint) -> &'a [T]; fn slice_from<'a>(&'a self, start: uint) -> &'a [T];
/// Returns a subslice from the start of the slice to `end`. /// Returns a subslice from the start of the slice to `end`.
/// ///
@ -84,7 +84,7 @@ pub trait ImmutableSlice<'a, T> {
/// ///
/// Slicing to `0` yields an empty slice. /// Slicing to `0` yields an empty slice.
#[unstable = "waiting on final error conventions/slicing syntax"] #[unstable = "waiting on final error conventions/slicing syntax"]
fn slice_to(&self, end: uint) -> &'a [T]; fn slice_to<'a>(&'a self, end: uint) -> &'a [T];
/// Divides one slice into two at an index. /// Divides one slice into two at an index.
/// ///
@ -94,29 +94,29 @@ pub trait ImmutableSlice<'a, T> {
/// ///
/// Fails if `mid > len`. /// Fails if `mid > len`.
#[unstable = "waiting on final error conventions"] #[unstable = "waiting on final error conventions"]
fn split_at(&self, mid: uint) -> (&'a [T], &'a [T]); fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]);
/// Returns an iterator over the slice /// Returns an iterator over the slice
#[unstable = "iterator type may change"] #[unstable = "iterator type may change"]
fn iter(self) -> Items<'a, T>; fn iter<'a>(&'a self) -> Items<'a, T>;
/// Returns an iterator over subslices separated by elements that match /// Returns an iterator over subslices separated by elements that match
/// `pred`. The matched element is not contained in the subslices. /// `pred`. The matched element is not contained in the subslices.
#[unstable = "iterator type may change, waiting on unboxed closures"] #[unstable = "iterator type may change, waiting on unboxed closures"]
fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T>; fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
/// Returns an iterator over subslices separated by elements that match /// Returns an iterator over subslices separated by elements that match
/// `pred`, limited to splitting at most `n` times. The matched element is /// `pred`, limited to splitting at most `n` times. The matched element is
/// not contained in the subslices. /// not contained in the subslices.
#[unstable = "iterator type may change"] #[unstable = "iterator type may change"]
fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>; fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
/// Returns an iterator over subslices separated by elements that match /// Returns an iterator over subslices separated by elements that match
/// `pred` limited to splitting at most `n` times. This starts at the end of /// `pred` limited to splitting at most `n` times. This starts at the end of
/// the slice and works backwards. The matched element is not contained in /// the slice and works backwards. The matched element is not contained in
/// the subslices. /// the subslices.
#[unstable = "iterator type may change"] #[unstable = "iterator type may change"]
fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>; fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>>;
/// Returns an iterator over all contiguous windows of length /// Returns an iterator over all contiguous windows of length
/// `size`. The windows overlap. If the slice is shorter than /// `size`. The windows overlap. If the slice is shorter than
@ -138,7 +138,7 @@ pub trait ImmutableSlice<'a, T> {
/// } /// }
/// ``` /// ```
#[unstable = "iterator type may change"] #[unstable = "iterator type may change"]
fn windows(self, size: uint) -> Windows<'a, T>; fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>;
/// Returns an iterator over `size` elements of the slice at a /// Returns an iterator over `size` elements of the slice at a
/// time. The chunks do not overlap. If `size` does not divide the /// time. The chunks do not overlap. If `size` does not divide the
@ -161,33 +161,33 @@ pub trait ImmutableSlice<'a, T> {
/// } /// }
/// ``` /// ```
#[unstable = "iterator type may change"] #[unstable = "iterator type may change"]
fn chunks(self, size: uint) -> Chunks<'a, T>; fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>;
/// Returns the element of a slice at the given index, or `None` if the /// Returns the element of a slice at the given index, or `None` if the
/// index is out of bounds. /// index is out of bounds.
#[unstable = "waiting on final collection conventions"] #[unstable = "waiting on final collection conventions"]
fn get(&self, index: uint) -> Option<&'a T>; fn get<'a>(&'a self, index: uint) -> Option<&'a T>;
/// Returns the first element of a slice, or `None` if it is empty. /// Returns the first element of a slice, or `None` if it is empty.
#[unstable = "name may change"] #[unstable = "name may change"]
fn head(&self) -> Option<&'a T>; fn head<'a>(&'a self) -> Option<&'a T>;
/// Returns all but the first element of a slice. /// Returns all but the first element of a slice.
#[unstable = "name may change"] #[unstable = "name may change"]
fn tail(&self) -> &'a [T]; fn tail<'a>(&'a self) -> &'a [T];
/// Returns all but the last element of a slice. /// Returns all but the last element of a slice.
#[unstable = "name may change"] #[unstable = "name may change"]
fn init(&self) -> &'a [T]; fn init<'a>(&'a self) -> &'a [T];
/// Returns the last element of a slice, or `None` if it is empty. /// Returns the last element of a slice, or `None` if it is empty.
#[unstable = "name may change"] #[unstable = "name may change"]
fn last(&self) -> Option<&'a T>; fn last<'a>(&'a self) -> Option<&'a T>;
/// Returns a pointer to the element at the given index, without doing /// Returns a pointer to the element at the given index, without doing
/// bounds checking. /// bounds checking.
#[unstable] #[unstable]
unsafe fn unsafe_get(self, index: uint) -> &'a T; unsafe fn unsafe_get<'a>(&'a self, index: uint) -> &'a T;
/// Returns an unsafe pointer to the slice's buffer /// Returns an unsafe pointer to the slice's buffer
/// ///
@ -237,9 +237,9 @@ pub trait ImmutableSlice<'a, T> {
} }
#[unstable] #[unstable]
impl<'a,T> ImmutableSlice<'a, T> for &'a [T] { impl<T> ImmutableSlice<T> for [T] {
#[inline] #[inline]
fn slice(&self, start: uint, end: uint) -> &'a [T] { fn slice(&self, start: uint, end: uint) -> &[T] {
assert!(start <= end); assert!(start <= end);
assert!(end <= self.len()); assert!(end <= self.len());
unsafe { unsafe {
@ -251,22 +251,22 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
} }
#[inline] #[inline]
fn slice_from(&self, start: uint) -> &'a [T] { fn slice_from(&self, start: uint) -> &[T] {
self.slice(start, self.len()) self.slice(start, self.len())
} }
#[inline] #[inline]
fn slice_to(&self, end: uint) -> &'a [T] { fn slice_to(&self, end: uint) -> &[T] {
self.slice(0, end) self.slice(0, end)
} }
#[inline] #[inline]
fn split_at(&self, mid: uint) -> (&'a [T], &'a [T]) { fn split_at(&self, mid: uint) -> (&[T], &[T]) {
((*self)[..mid], (*self)[mid..]) (self[..mid], self[mid..])
} }
#[inline] #[inline]
fn iter(self) -> Items<'a, T> { fn iter<'a>(&'a self) -> Items<'a, T> {
unsafe { unsafe {
let p = self.as_ptr(); let p = self.as_ptr();
if mem::size_of::<T>() == 0 { if mem::size_of::<T>() == 0 {
@ -282,7 +282,7 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
} }
#[inline] #[inline]
fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T> { fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
Splits { Splits {
v: self, v: self,
pred: pred, pred: pred,
@ -291,7 +291,7 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
} }
#[inline] #[inline]
fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> { fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
SplitsN { SplitsN {
iter: self.split(pred), iter: self.split(pred),
count: n, count: n,
@ -300,7 +300,7 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
} }
#[inline] #[inline]
fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> { fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> {
SplitsN { SplitsN {
iter: self.split(pred), iter: self.split(pred),
count: n, count: n,
@ -309,42 +309,42 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
} }
#[inline] #[inline]
fn windows(self, size: uint) -> Windows<'a, T> { fn windows(&self, size: uint) -> Windows<T> {
assert!(size != 0); assert!(size != 0);
Windows { v: self, size: size } Windows { v: self, size: size }
} }
#[inline] #[inline]
fn chunks(self, size: uint) -> Chunks<'a, T> { fn chunks(&self, size: uint) -> Chunks<T> {
assert!(size != 0); assert!(size != 0);
Chunks { v: self, size: size } Chunks { v: self, size: size }
} }
#[inline] #[inline]
fn get(&self, index: uint) -> Option<&'a T> { fn get(&self, index: uint) -> Option<&T> {
if index < self.len() { Some(&self[index]) } else { None } if index < self.len() { Some(&self[index]) } else { None }
} }
#[inline] #[inline]
fn head(&self) -> Option<&'a T> { fn head(&self) -> Option<&T> {
if self.len() == 0 { None } else { Some(&self[0]) } if self.len() == 0 { None } else { Some(&self[0]) }
} }
#[inline] #[inline]
fn tail(&self) -> &'a [T] { (*self)[1..] } fn tail(&self) -> &[T] { self[1..] }
#[inline] #[inline]
fn init(&self) -> &'a [T] { fn init(&self) -> &[T] {
(*self)[..self.len() - 1] self[..self.len() - 1]
} }
#[inline] #[inline]
fn last(&self) -> Option<&'a T> { fn last(&self) -> Option<&T> {
if self.len() == 0 { None } else { Some(&self[self.len() - 1]) } if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
} }
#[inline] #[inline]
unsafe fn unsafe_get(self, index: uint) -> &'a T { unsafe fn unsafe_get(&self, index: uint) -> &T {
transmute(self.repr().data.offset(index as int)) transmute(self.repr().data.offset(index as int))
} }
@ -436,14 +436,14 @@ impl<T> ops::SliceMut<uint, [T]> for [T] {
/// Extension methods for slices such that their elements are /// Extension methods for slices such that their elements are
/// mutable. /// mutable.
#[experimental = "may merge with other traits; may lose region param; needs review"] #[experimental = "may merge with other traits; may lose region param; needs review"]
pub trait MutableSlice<'a, T> { pub trait MutableSlice<T> for Sized? {
/// Returns a mutable reference to the element at the given index, /// Returns a mutable reference to the element at the given index,
/// or `None` if the index is out of bounds /// or `None` if the index is out of bounds
#[unstable = "waiting on final error conventions"] #[unstable = "waiting on final error conventions"]
fn get_mut(self, index: uint) -> Option<&'a mut T>; fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>;
/// Work with `self` as a mut slice. /// Work with `self` as a mut slice.
/// Primarily intended for getting a &mut [T] from a [T, ..N]. /// Primarily intended for getting a &mut [T] from a [T, ..N].
fn as_mut_slice(self) -> &'a mut [T]; fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T];
/// Returns a mutable subslice spanning the interval [`start`, `end`). /// Returns a mutable subslice spanning the interval [`start`, `end`).
/// ///
@ -452,7 +452,7 @@ pub trait MutableSlice<'a, T> {
/// ///
/// Slicing with `start` equal to `end` yields an empty slice. /// Slicing with `start` equal to `end` yields an empty slice.
#[unstable = "waiting on final error conventions"] #[unstable = "waiting on final error conventions"]
fn slice_mut(self, start: uint, end: uint) -> &'a mut [T]; fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T];
/// Returns a mutable subslice from `start` to the end of the slice. /// Returns a mutable subslice from `start` to the end of the slice.
/// ///
@ -460,7 +460,7 @@ pub trait MutableSlice<'a, T> {
/// ///
/// Slicing from `self.len()` yields an empty slice. /// Slicing from `self.len()` yields an empty slice.
#[unstable = "waiting on final error conventions"] #[unstable = "waiting on final error conventions"]
fn slice_from_mut(self, start: uint) -> &'a mut [T]; fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T];
/// Returns a mutable subslice from the start of the slice to `end`. /// Returns a mutable subslice from the start of the slice to `end`.
/// ///
@ -468,45 +468,45 @@ pub trait MutableSlice<'a, T> {
/// ///
/// Slicing to `0` yields an empty slice. /// Slicing to `0` yields an empty slice.
#[unstable = "waiting on final error conventions"] #[unstable = "waiting on final error conventions"]
fn slice_to_mut(self, end: uint) -> &'a mut [T]; fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T];
/// Returns an iterator that allows modifying each value /// Returns an iterator that allows modifying each value
#[unstable = "waiting on iterator type name conventions"] #[unstable = "waiting on iterator type name conventions"]
fn iter_mut(self) -> MutItems<'a, T>; fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T>;
/// Returns a mutable pointer to the first element of a slice, or `None` if it is empty /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
#[unstable = "name may change"] #[unstable = "name may change"]
fn head_mut(self) -> Option<&'a mut T>; fn head_mut<'a>(&'a mut self) -> Option<&'a mut T>;
/// Returns all but the first element of a mutable slice /// Returns all but the first element of a mutable slice
#[unstable = "name may change"] #[unstable = "name may change"]
fn tail_mut(self) -> &'a mut [T]; fn tail_mut<'a>(&'a mut self) -> &'a mut [T];
/// Returns all but the last element of a mutable slice /// Returns all but the last element of a mutable slice
#[unstable = "name may change"] #[unstable = "name may change"]
fn init_mut(self) -> &'a mut [T]; fn init_mut<'a>(&'a mut self) -> &'a mut [T];
/// Returns a mutable pointer to the last item in the slice. /// Returns a mutable pointer to the last item in the slice.
#[unstable = "name may change"] #[unstable = "name may change"]
fn last_mut(self) -> Option<&'a mut T>; fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>;
/// Returns an iterator over mutable subslices separated by elements that /// Returns an iterator over mutable subslices separated by elements that
/// match `pred`. The matched element is not contained in the subslices. /// match `pred`. The matched element is not contained in the subslices.
#[unstable = "waiting on unboxed closures, iterator type name conventions"] #[unstable = "waiting on unboxed closures, iterator type name conventions"]
fn split_mut(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>; fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
/// Returns an iterator over subslices separated by elements that match /// Returns an iterator over subslices separated by elements that match
/// `pred`, limited to splitting at most `n` times. The matched element is /// `pred`, limited to splitting at most `n` times. The matched element is
/// not contained in the subslices. /// not contained in the subslices.
#[unstable = "waiting on unboxed closures, iterator type name conventions"] #[unstable = "waiting on unboxed closures, iterator type name conventions"]
fn splitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>; fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
/// Returns an iterator over subslices separated by elements that match /// Returns an iterator over subslices separated by elements that match
/// `pred` limited to splitting at most `n` times. This starts at the end of /// `pred` limited to splitting at most `n` times. This starts at the end of
/// the slice and works backwards. The matched element is not contained in /// the slice and works backwards. The matched element is not contained in
/// the subslices. /// the subslices.
#[unstable = "waiting on unboxed closures, iterator type name conventions"] #[unstable = "waiting on unboxed closures, iterator type name conventions"]
fn rsplitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>; fn rsplitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>>;
/// Returns an iterator over `chunk_size` elements of the slice at a time. /// Returns an iterator over `chunk_size` elements of the slice at a time.
/// The chunks are mutable and do not overlap. If `chunk_size` does /// The chunks are mutable and do not overlap. If `chunk_size` does
@ -517,7 +517,7 @@ pub trait MutableSlice<'a, T> {
/// ///
/// Fails if `chunk_size` is 0. /// Fails if `chunk_size` is 0.
#[unstable = "waiting on iterator type name conventions"] #[unstable = "waiting on iterator type name conventions"]
fn chunks_mut(self, chunk_size: uint) -> MutChunks<'a, T>; fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T>;
/// Swaps two elements in a slice. /// Swaps two elements in a slice.
/// ///
@ -536,7 +536,7 @@ pub trait MutableSlice<'a, T> {
/// assert!(v == ["a", "d", "c", "b"]); /// assert!(v == ["a", "d", "c", "b"]);
/// ``` /// ```
#[unstable = "waiting on final error conventions"] #[unstable = "waiting on final error conventions"]
fn swap(self, a: uint, b: uint); fn swap(&mut self, a: uint, b: uint);
/// Divides one `&mut` into two at an index. /// Divides one `&mut` into two at an index.
/// ///
@ -571,7 +571,7 @@ pub trait MutableSlice<'a, T> {
/// } /// }
/// ``` /// ```
#[unstable = "waiting on final error conventions"] #[unstable = "waiting on final error conventions"]
fn split_at_mut(self, mid: uint) -> (&'a mut [T], &'a mut [T]); fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]);
/// Reverse the order of elements in a slice, in place. /// Reverse the order of elements in a slice, in place.
/// ///
@ -583,11 +583,11 @@ pub trait MutableSlice<'a, T> {
/// assert!(v == [3i, 2, 1]); /// assert!(v == [3i, 2, 1]);
/// ``` /// ```
#[experimental = "may be moved to iterators instead"] #[experimental = "may be moved to iterators instead"]
fn reverse(self); fn reverse(&mut self);
/// Returns an unsafe mutable pointer to the element in index /// Returns an unsafe mutable pointer to the element in index
#[experimental = "waiting on unsafe conventions"] #[experimental = "waiting on unsafe conventions"]
unsafe fn unsafe_mut(self, index: uint) -> &'a mut T; unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T;
/// Return an unsafe mutable pointer to the slice's buffer. /// Return an unsafe mutable pointer to the slice's buffer.
/// ///
@ -598,43 +598,43 @@ pub trait MutableSlice<'a, T> {
/// would also make any pointers to it invalid. /// would also make any pointers to it invalid.
#[inline] #[inline]
#[unstable] #[unstable]
fn as_mut_ptr(self) -> *mut T; fn as_mut_ptr(&mut self) -> *mut T;
} }
#[experimental = "trait is experimental"] #[experimental = "trait is experimental"]
impl<'a,T> MutableSlice<'a, T> for &'a mut [T] { impl<T> MutableSlice<T> for [T] {
#[inline] #[inline]
fn get_mut(self, index: uint) -> Option<&'a mut T> { fn get_mut(&mut self, index: uint) -> Option<&mut T> {
if index < self.len() { Some(&mut self[index]) } else { None } if index < self.len() { Some(&mut self[index]) } else { None }
} }
#[inline] #[inline]
fn as_mut_slice(self) -> &'a mut [T] { self } fn as_mut_slice(&mut self) -> &mut [T] { self }
fn slice_mut(self, start: uint, end: uint) -> &'a mut [T] { fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] {
self[mut start..end] self[mut start..end]
} }
#[inline] #[inline]
fn slice_from_mut(self, start: uint) -> &'a mut [T] { fn slice_from_mut(&mut self, start: uint) -> &mut [T] {
self[mut start..] self[mut start..]
} }
#[inline] #[inline]
fn slice_to_mut(self, end: uint) -> &'a mut [T] { fn slice_to_mut(&mut self, end: uint) -> &mut [T] {
self[mut ..end] self[mut ..end]
} }
#[inline] #[inline]
fn split_at_mut(self, mid: uint) -> (&'a mut [T], &'a mut [T]) { fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) {
unsafe { unsafe {
let self2: &'a mut [T] = mem::transmute_copy(&self); let self2: &mut [T] = mem::transmute_copy(&self);
(self[mut ..mid], self2[mut mid..]) (self[mut ..mid], self2[mut mid..])
} }
} }
#[inline] #[inline]
fn iter_mut(self) -> MutItems<'a, T> { fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
unsafe { unsafe {
let p = self.as_mut_ptr(); let p = self.as_mut_ptr();
if mem::size_of::<T>() == 0 { if mem::size_of::<T>() == 0 {
@ -652,36 +652,36 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
} }
#[inline] #[inline]
fn last_mut(self) -> Option<&'a mut T> { fn last_mut(&mut self) -> Option<&mut T> {
let len = self.len(); let len = self.len();
if len == 0 { return None; } if len == 0 { return None; }
Some(&mut self[len - 1]) Some(&mut self[len - 1])
} }
#[inline] #[inline]
fn head_mut(self) -> Option<&'a mut T> { fn head_mut(&mut self) -> Option<&mut T> {
if self.len() == 0 { None } else { Some(&mut self[0]) } if self.len() == 0 { None } else { Some(&mut self[0]) }
} }
#[inline] #[inline]
fn tail_mut(self) -> &'a mut [T] { fn tail_mut(&mut self) -> &mut [T] {
let len = self.len(); let len = self.len();
self[mut 1..len] self[mut 1..len]
} }
#[inline] #[inline]
fn init_mut(self) -> &'a mut [T] { fn init_mut(&mut self) -> &mut [T] {
let len = self.len(); let len = self.len();
self[mut 0..len - 1] self[mut 0..len - 1]
} }
#[inline] #[inline]
fn split_mut(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> { fn split_mut<'a>(&'a mut self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> {
MutSplits { v: self, pred: pred, finished: false } MutSplits { v: self, pred: pred, finished: false }
} }
#[inline] #[inline]
fn splitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> { fn splitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
SplitsN { SplitsN {
iter: self.split_mut(pred), iter: self.split_mut(pred),
count: n, count: n,
@ -690,7 +690,7 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
} }
#[inline] #[inline]
fn rsplitn_mut(self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> { fn rsplitn_mut<'a>(&'a mut self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<MutSplits<'a, T>> {
SplitsN { SplitsN {
iter: self.split_mut(pred), iter: self.split_mut(pred),
count: n, count: n,
@ -699,12 +699,12 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
} }
#[inline] #[inline]
fn chunks_mut(self, chunk_size: uint) -> MutChunks<'a, T> { fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks<T> {
assert!(chunk_size > 0); assert!(chunk_size > 0);
MutChunks { v: self, chunk_size: chunk_size } MutChunks { v: self, chunk_size: chunk_size }
} }
fn swap(self, a: uint, b: uint) { fn swap(&mut self, a: uint, b: uint) {
unsafe { unsafe {
// Can't take two mutable loans from one vector, so instead just cast // Can't take two mutable loans from one vector, so instead just cast
// them to their raw pointers to do the swap // them to their raw pointers to do the swap
@ -714,7 +714,7 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
} }
} }
fn reverse(self) { fn reverse(&mut self) {
let mut i: uint = 0; let mut i: uint = 0;
let ln = self.len(); let ln = self.len();
while i < ln / 2 { while i < ln / 2 {
@ -729,19 +729,19 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
} }
#[inline] #[inline]
unsafe fn unsafe_mut(self, index: uint) -> &'a mut T { unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T {
transmute((self.repr().data as *mut T).offset(index as int)) transmute((self.repr().data as *mut T).offset(index as int))
} }
#[inline] #[inline]
fn as_mut_ptr(self) -> *mut T { fn as_mut_ptr(&mut self) -> *mut T {
self.repr().data as *mut T self.repr().data as *mut T
} }
} }
/// Extension methods for slices containing `PartialEq` elements. /// Extension methods for slices containing `PartialEq` elements.
#[unstable = "may merge with other traits"] #[unstable = "may merge with other traits"]
pub trait ImmutablePartialEqSlice<T:PartialEq> { pub trait ImmutablePartialEqSlice<T: PartialEq> for Sized? {
/// Find the first index containing a matching value. /// Find the first index containing a matching value.
fn position_elem(&self, t: &T) -> Option<uint>; fn position_elem(&self, t: &T) -> Option<uint>;
@ -759,7 +759,7 @@ pub trait ImmutablePartialEqSlice<T:PartialEq> {
} }
#[unstable = "trait is unstable"] #[unstable = "trait is unstable"]
impl<'a,T:PartialEq> ImmutablePartialEqSlice<T> for &'a [T] { impl<T: PartialEq> ImmutablePartialEqSlice<T> for [T] {
#[inline] #[inline]
fn position_elem(&self, x: &T) -> Option<uint> { fn position_elem(&self, x: &T) -> Option<uint> {
self.iter().position(|y| *x == *y) self.iter().position(|y| *x == *y)
@ -778,19 +778,19 @@ impl<'a,T:PartialEq> ImmutablePartialEqSlice<T> for &'a [T] {
#[inline] #[inline]
fn starts_with(&self, needle: &[T]) -> bool { fn starts_with(&self, needle: &[T]) -> bool {
let n = needle.len(); let n = needle.len();
self.len() >= n && needle == (*self)[..n] self.len() >= n && needle == self[..n]
} }
#[inline] #[inline]
fn ends_with(&self, needle: &[T]) -> bool { fn ends_with(&self, needle: &[T]) -> bool {
let (m, n) = (self.len(), needle.len()); let (m, n) = (self.len(), needle.len());
m >= n && needle == (*self)[m-n..] m >= n && needle == self[m-n..]
} }
} }
/// Extension methods for slices containing `Ord` elements. /// Extension methods for slices containing `Ord` elements.
#[unstable = "may merge with other traits"] #[unstable = "may merge with other traits"]
pub trait ImmutableOrdSlice<T: Ord> { pub trait ImmutableOrdSlice<T: Ord> for Sized? {
/// Binary search a sorted slice for a given element. /// Binary search a sorted slice for a given element.
/// ///
/// If the value is found then `Found` is returned, containing the /// If the value is found then `Found` is returned, containing the
@ -820,7 +820,7 @@ pub trait ImmutableOrdSlice<T: Ord> {
} }
#[unstable = "trait is unstable"] #[unstable = "trait is unstable"]
impl<'a, T: Ord> ImmutableOrdSlice<T> for &'a [T] { impl<T: Ord> ImmutableOrdSlice<T> for [T] {
#[unstable] #[unstable]
fn binary_search_elem(&self, x: &T) -> BinarySearchResult { fn binary_search_elem(&self, x: &T) -> BinarySearchResult {
self.binary_search(|p| p.cmp(x)) self.binary_search(|p| p.cmp(x))
@ -829,7 +829,7 @@ impl<'a, T: Ord> ImmutableOrdSlice<T> for &'a [T] {
/// Trait for &[T] where T is Cloneable /// Trait for &[T] where T is Cloneable
#[unstable = "may merge with other traits"] #[unstable = "may merge with other traits"]
pub trait MutableCloneableSlice<T> { pub trait MutableCloneableSlice<T> for Sized? {
/// Copies as many elements from `src` as it can into `self` (the /// Copies as many elements from `src` as it can into `self` (the
/// shorter of `self.len()` and `src.len()`). Returns the number /// shorter of `self.len()` and `src.len()`). Returns the number
/// of elements copied. /// of elements copied.
@ -849,13 +849,13 @@ pub trait MutableCloneableSlice<T> {
/// assert!(dst.clone_from_slice(src2) == 3); /// assert!(dst.clone_from_slice(src2) == 3);
/// assert!(dst == [3i, 4, 5]); /// assert!(dst == [3i, 4, 5]);
/// ``` /// ```
fn clone_from_slice(self, &[T]) -> uint; fn clone_from_slice(&mut self, &[T]) -> uint;
} }
#[unstable = "trait is unstable"] #[unstable = "trait is unstable"]
impl<'a, T: Clone> MutableCloneableSlice<T> for &'a mut [T] { impl<T: Clone> MutableCloneableSlice<T> for [T] {
#[inline] #[inline]
fn clone_from_slice(self, src: &[T]) -> uint { fn clone_from_slice(&mut self, src: &[T]) -> uint {
let min = cmp::min(self.len(), src.len()); let min = cmp::min(self.len(), src.len());
let dst = self.slice_to_mut(min); let dst = self.slice_to_mut(min);
let src = src.slice_to(min); let src = src.slice_to(min);
@ -1509,19 +1509,20 @@ pub mod raw {
#[experimental = "needs review"] #[experimental = "needs review"]
pub mod bytes { pub mod bytes {
use collections::Collection; use collections::Collection;
use kinds::Sized;
use ptr; use ptr;
use slice::{ImmutableSlice, MutableSlice}; use slice::{ImmutableSlice, MutableSlice};
/// A trait for operations on mutable `[u8]`s. /// A trait for operations on mutable `[u8]`s.
pub trait MutableByteVector { pub trait MutableByteVector for Sized? {
/// Sets all bytes of the receiver to the given value. /// Sets all bytes of the receiver to the given value.
fn set_memory(self, value: u8); fn set_memory(&mut self, value: u8);
} }
impl<'a> MutableByteVector for &'a mut [u8] { impl MutableByteVector for [u8] {
#[inline] #[inline]
#[allow(experimental)] #[allow(experimental)]
fn set_memory(self, value: u8) { fn set_memory(&mut self, value: u8) {
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) }; unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
} }
} }
@ -1623,53 +1624,51 @@ impl<'a, T: PartialOrd> PartialOrd for &'a [T] {
/// Extension methods for immutable slices containing integers. /// Extension methods for immutable slices containing integers.
#[experimental] #[experimental]
pub trait ImmutableIntSlice<'a, U, S> { pub trait ImmutableIntSlice<U, S> for Sized? {
/// Converts the slice to an immutable slice of unsigned integers with the same width. /// Converts the slice to an immutable slice of unsigned integers with the same width.
fn as_unsigned(self) -> &'a [U]; fn as_unsigned<'a>(&'a self) -> &'a [U];
/// Converts the slice to an immutable slice of signed integers with the same width. /// Converts the slice to an immutable slice of signed integers with the same width.
fn as_signed(self) -> &'a [S]; fn as_signed<'a>(&'a self) -> &'a [S];
} }
/// Extension methods for mutable slices containing integers. /// Extension methods for mutable slices containing integers.
#[experimental] #[experimental]
pub trait MutableIntSlice<'a, U, S>: ImmutableIntSlice<'a, U, S> { pub trait MutableIntSlice<U, S> for Sized?: ImmutableIntSlice<U, S> {
/// Converts the slice to a mutable slice of unsigned integers with the same width. /// Converts the slice to a mutable slice of unsigned integers with the same width.
fn as_unsigned_mut(self) -> &'a mut [U]; fn as_unsigned_mut<'a>(&'a mut self) -> &'a mut [U];
/// Converts the slice to a mutable slice of signed integers with the same width. /// Converts the slice to a mutable slice of signed integers with the same width.
fn as_signed_mut(self) -> &'a mut [S]; fn as_signed_mut<'a>(&'a mut self) -> &'a mut [S];
} }
macro_rules! impl_immut_int_slice { macro_rules! impl_immut_int_slice {
($u:ty, $s:ty, $t:ty) => { ($u:ty, $s:ty, $t:ty) => {
#[experimental] #[experimental]
impl<'a> ImmutableIntSlice<'a, $u, $s> for $t { impl ImmutableIntSlice<$u, $s> for [$t] {
#[inline] #[inline]
fn as_unsigned(self) -> &'a [$u] { unsafe { transmute(self) } } fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } }
#[inline] #[inline]
fn as_signed(self) -> &'a [$s] { unsafe { transmute(self) } } fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } }
} }
} }
} }
macro_rules! impl_mut_int_slice { macro_rules! impl_mut_int_slice {
($u:ty, $s:ty, $t:ty) => { ($u:ty, $s:ty, $t:ty) => {
#[experimental] #[experimental]
impl<'a> MutableIntSlice<'a, $u, $s> for $t { impl MutableIntSlice<$u, $s> for [$t] {
#[inline] #[inline]
fn as_unsigned_mut(self) -> &'a mut [$u] { unsafe { transmute(self) } } fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } }
#[inline] #[inline]
fn as_signed_mut(self) -> &'a mut [$s] { unsafe { transmute(self) } } fn as_signed_mut(&mut self) -> &mut [$s] { unsafe { transmute(self) } }
} }
} }
} }
macro_rules! impl_int_slice { macro_rules! impl_int_slice {
($u:ty, $s:ty) => { ($u:ty, $s:ty) => {
impl_immut_int_slice!($u, $s, &'a [$u]) impl_immut_int_slice!($u, $s, $u)
impl_immut_int_slice!($u, $s, &'a [$s]) impl_immut_int_slice!($u, $s, $s)
impl_immut_int_slice!($u, $s, &'a mut [$u]) impl_mut_int_slice!($u, $s, $u)
impl_immut_int_slice!($u, $s, &'a mut [$s]) impl_mut_int_slice!($u, $s, $s)
impl_mut_int_slice!($u, $s, &'a mut [$u])
impl_mut_int_slice!($u, $s, &'a mut [$s])
} }
} }

View File

@ -27,6 +27,7 @@ use default::Default;
use iter::{Map, Iterator}; use iter::{Map, Iterator};
use iter::{DoubleEndedIterator, ExactSize}; use iter::{DoubleEndedIterator, ExactSize};
use iter::range; use iter::range;
use kinds::Sized;
use num::{CheckedMul, Saturating}; use num::{CheckedMul, Saturating};
use option::{Option, None, Some}; use option::{Option, None, Some};
use raw::Repr; use raw::Repr;
@ -1206,7 +1207,7 @@ impl<'a> Collection for &'a str {
} }
/// Methods for string slices /// Methods for string slices
pub trait StrSlice<'a> { pub trait StrSlice for Sized? {
/// Returns true if one string contains another /// Returns true if one string contains another
/// ///
/// # Arguments /// # Arguments
@ -1218,7 +1219,7 @@ pub trait StrSlice<'a> {
/// ```rust /// ```rust
/// assert!("bananas".contains("nana")); /// assert!("bananas".contains("nana"));
/// ``` /// ```
fn contains<'a>(&self, needle: &'a str) -> bool; fn contains(&self, needle: &str) -> bool;
/// Returns true if a string contains a char. /// Returns true if a string contains a char.
/// ///
@ -1242,7 +1243,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<char> = "abc åäö".chars().collect(); /// let v: Vec<char> = "abc åäö".chars().collect();
/// assert_eq!(v, vec!['a', 'b', 'c', ' ', 'å', 'ä', 'ö']); /// assert_eq!(v, vec!['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
/// ``` /// ```
fn chars(&self) -> Chars<'a>; fn chars<'a>(&'a self) -> Chars<'a>;
/// An iterator over the bytes of `self` /// An iterator over the bytes of `self`
/// ///
@ -1252,10 +1253,10 @@ pub trait StrSlice<'a> {
/// let v: Vec<u8> = "bors".bytes().collect(); /// let v: Vec<u8> = "bors".bytes().collect();
/// assert_eq!(v, b"bors".to_vec()); /// assert_eq!(v, b"bors".to_vec());
/// ``` /// ```
fn bytes(&self) -> Bytes<'a>; fn bytes<'a>(&'a self) -> Bytes<'a>;
/// An iterator over the characters of `self` and their byte offsets. /// An iterator over the characters of `self` and their byte offsets.
fn char_indices(&self) -> CharOffsets<'a>; fn char_indices<'a>(&'a self) -> CharOffsets<'a>;
/// An iterator over substrings of `self`, separated by characters /// An iterator over substrings of `self`, separated by characters
/// matched by `sep`. /// matched by `sep`.
@ -1275,7 +1276,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = "".split('X').collect(); /// let v: Vec<&str> = "".split('X').collect();
/// assert_eq!(v, vec![""]); /// assert_eq!(v, vec![""]);
/// ``` /// ```
fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep>; fn split<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
/// An iterator over substrings of `self`, separated by characters /// An iterator over substrings of `self`, separated by characters
/// matched by `sep`, restricted to splitting at most `count` /// matched by `sep`, restricted to splitting at most `count`
@ -1299,7 +1300,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = "".splitn(1, 'X').collect(); /// let v: Vec<&str> = "".splitn(1, 'X').collect();
/// assert_eq!(v, vec![""]); /// assert_eq!(v, vec![""]);
/// ``` /// ```
fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>; fn splitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
/// An iterator over substrings of `self`, separated by characters /// An iterator over substrings of `self`, separated by characters
/// matched by `sep`. /// matched by `sep`.
@ -1325,7 +1326,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect(); /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
/// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]); /// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]);
/// ``` /// ```
fn split_terminator<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep>; fn split_terminator<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
/// An iterator over substrings of `self`, separated by characters /// An iterator over substrings of `self`, separated by characters
/// matched by `sep`, starting from the end of the string. /// matched by `sep`, starting from the end of the string.
@ -1343,7 +1344,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect(); /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
/// assert_eq!(v, vec!["leopard", "tiger", "lionX"]); /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
/// ``` /// ```
fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>; fn rsplitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
/// An iterator over the start and end indices of the disjoint /// An iterator over the start and end indices of the disjoint
/// matches of `sep` within `self`. /// matches of `sep` within `self`.
@ -1365,7 +1366,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<(uint, uint)> = "ababa".match_indices("aba").collect(); /// let v: Vec<(uint, uint)> = "ababa".match_indices("aba").collect();
/// assert_eq!(v, vec![(0, 3)]); // only the first `aba` /// assert_eq!(v, vec![(0, 3)]); // only the first `aba`
/// ``` /// ```
fn match_indices(&self, sep: &'a str) -> MatchIndices<'a>; fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a>;
/// An iterator over the substrings of `self` separated by `sep`. /// An iterator over the substrings of `self` separated by `sep`.
/// ///
@ -1378,7 +1379,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = "1abcabc2".split_str("abc").collect(); /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect();
/// assert_eq!(v, vec!["1", "", "2"]); /// assert_eq!(v, vec!["1", "", "2"]);
/// ``` /// ```
fn split_str(&self, &'a str) -> StrSplits<'a>; fn split_str<'a>(&'a self, &'a str) -> StrSplits<'a>;
/// An iterator over the lines of a string (subsequences separated /// An iterator over the lines of a string (subsequences separated
/// by `\n`). This does not include the empty string after a /// by `\n`). This does not include the empty string after a
@ -1391,7 +1392,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = four_lines.lines().collect(); /// let v: Vec<&str> = four_lines.lines().collect();
/// assert_eq!(v, vec!["foo", "bar", "", "baz"]); /// assert_eq!(v, vec!["foo", "bar", "", "baz"]);
/// ``` /// ```
fn lines(&self) -> CharSplits<'a, char>; fn lines<'a>(&'a self) -> CharSplits<'a, char>;
/// An iterator over the lines of a string, separated by either /// An iterator over the lines of a string, separated by either
/// `\n` or `\r\n`. As with `.lines()`, this does not include an /// `\n` or `\r\n`. As with `.lines()`, this does not include an
@ -1404,7 +1405,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = four_lines.lines_any().collect(); /// let v: Vec<&str> = four_lines.lines_any().collect();
/// assert_eq!(v, vec!["foo", "bar", "", "baz"]); /// assert_eq!(v, vec!["foo", "bar", "", "baz"]);
/// ``` /// ```
fn lines_any(&self) -> AnyLines<'a>; fn lines_any<'a>(&'a self) -> AnyLines<'a>;
/// Returns the number of Unicode code points (`char`) that a /// Returns the number of Unicode code points (`char`) that a
/// string holds. /// string holds.
@ -1469,7 +1470,7 @@ pub trait StrSlice<'a> {
/// // byte 100 is outside the string /// // byte 100 is outside the string
/// // s.slice(3, 100); /// // s.slice(3, 100);
/// ``` /// ```
fn slice(&self, begin: uint, end: uint) -> &'a str; fn slice<'a>(&'a self, begin: uint, end: uint) -> &'a str;
/// Returns a slice of the string from `begin` to its end. /// Returns a slice of the string from `begin` to its end.
/// ///
@ -1479,7 +1480,7 @@ pub trait StrSlice<'a> {
/// out of bounds. /// out of bounds.
/// ///
/// See also `slice`, `slice_to` and `slice_chars`. /// See also `slice`, `slice_to` and `slice_chars`.
fn slice_from(&self, begin: uint) -> &'a str; fn slice_from<'a>(&'a self, begin: uint) -> &'a str;
/// Returns a slice of the string from the beginning to byte /// Returns a slice of the string from the beginning to byte
/// `end`. /// `end`.
@ -1490,7 +1491,7 @@ pub trait StrSlice<'a> {
/// out of bounds. /// out of bounds.
/// ///
/// See also `slice`, `slice_from` and `slice_chars`. /// See also `slice`, `slice_from` and `slice_chars`.
fn slice_to(&self, end: uint) -> &'a str; fn slice_to<'a>(&'a self, end: uint) -> &'a str;
/// Returns a slice of the string from the character range /// Returns a slice of the string from the character range
/// [`begin`..`end`). /// [`begin`..`end`).
@ -1515,7 +1516,7 @@ pub trait StrSlice<'a> {
/// assert_eq!(s.slice_chars(0, 4), "Löwe"); /// assert_eq!(s.slice_chars(0, 4), "Löwe");
/// assert_eq!(s.slice_chars(5, 7), "老虎"); /// assert_eq!(s.slice_chars(5, 7), "老虎");
/// ``` /// ```
fn slice_chars(&self, begin: uint, end: uint) -> &'a str; fn slice_chars<'a>(&'a self, begin: uint, end: uint) -> &'a str;
/// Returns true if `needle` is a prefix of the string. /// Returns true if `needle` is a prefix of the string.
/// ///
@ -1549,7 +1550,7 @@ pub trait StrSlice<'a> {
/// assert_eq!("12foo1bar12".trim_chars(x), "foo1bar") /// assert_eq!("12foo1bar12".trim_chars(x), "foo1bar")
/// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar") /// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar")
/// ``` /// ```
fn trim_chars<C: CharEq>(&self, to_trim: C) -> &'a str; fn trim_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
/// Returns a string with leading `chars_to_trim` removed. /// Returns a string with leading `chars_to_trim` removed.
/// ///
@ -1565,7 +1566,7 @@ pub trait StrSlice<'a> {
/// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12") /// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12")
/// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123") /// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123")
/// ``` /// ```
fn trim_left_chars<C: CharEq>(&self, to_trim: C) -> &'a str; fn trim_left_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
/// Returns a string with trailing `chars_to_trim` removed. /// Returns a string with trailing `chars_to_trim` removed.
/// ///
@ -1581,7 +1582,7 @@ pub trait StrSlice<'a> {
/// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar") /// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar")
/// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar") /// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar")
/// ``` /// ```
fn trim_right_chars<C: CharEq>(&self, to_trim: C) -> &'a str; fn trim_right_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
/// Check that `index`-th byte lies at the start and/or end of a /// Check that `index`-th byte lies at the start and/or end of a
/// UTF-8 code point sequence. /// UTF-8 code point sequence.
@ -1707,7 +1708,7 @@ pub trait StrSlice<'a> {
/// ```rust /// ```rust
/// assert_eq!("bors".as_bytes(), b"bors"); /// assert_eq!("bors".as_bytes(), b"bors");
/// ``` /// ```
fn as_bytes(&self) -> &'a [u8]; fn as_bytes<'a>(&'a self) -> &'a [u8];
/// Returns the byte index of the first character of `self` that /// Returns the byte index of the first character of `self` that
/// matches `search`. /// matches `search`.
@ -1798,7 +1799,7 @@ pub trait StrSlice<'a> {
/// assert_eq!(c, Some('ö')); /// assert_eq!(c, Some('ö'));
/// assert_eq!(s2, "we 老虎 Léopard"); /// assert_eq!(s2, "we 老虎 Léopard");
/// ``` /// ```
fn slice_shift_char(&self) -> (Option<char>, &'a str); fn slice_shift_char<'a>(&'a self) -> (Option<char>, &'a str);
/// Returns the byte offset of an inner slice relative to an enclosing outer slice. /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
/// ///
@ -1825,7 +1826,7 @@ pub trait StrSlice<'a> {
fn as_ptr(&self) -> *const u8; fn as_ptr(&self) -> *const u8;
/// Return an iterator of `u16` over the string encoded as UTF-16. /// Return an iterator of `u16` over the string encoded as UTF-16.
fn utf16_units(&self) -> Utf16CodeUnits<'a>; fn utf16_units<'a>(&'a self) -> Utf16CodeUnits<'a>;
} }
#[inline(never)] #[inline(never)]
@ -1835,9 +1836,9 @@ fn slice_error_fail(s: &str, begin: uint, end: uint) -> ! {
begin, end, s); begin, end, s);
} }
impl<'a> StrSlice<'a> for &'a str { impl StrSlice for str {
#[inline] #[inline]
fn contains<'a>(&self, needle: &'a str) -> bool { fn contains(&self, needle: &str) -> bool {
self.find_str(needle).is_some() self.find_str(needle).is_some()
} }
@ -1847,24 +1848,24 @@ impl<'a> StrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn chars(&self) -> Chars<'a> { fn chars(&self) -> Chars {
Chars{iter: self.as_bytes().iter()} Chars{iter: self.as_bytes().iter()}
} }
#[inline] #[inline]
fn bytes(&self) -> Bytes<'a> { fn bytes(&self) -> Bytes {
self.as_bytes().iter().map(|&b| b) self.as_bytes().iter().map(|&b| b)
} }
#[inline] #[inline]
fn char_indices(&self) -> CharOffsets<'a> { fn char_indices(&self) -> CharOffsets {
CharOffsets{front_offset: 0, iter: self.chars()} CharOffsets{front_offset: 0, iter: self.chars()}
} }
#[inline] #[inline]
fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep> { fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<Sep> {
CharSplits { CharSplits {
string: *self, string: self,
only_ascii: sep.only_ascii(), only_ascii: sep.only_ascii(),
sep: sep, sep: sep,
allow_trailing_empty: true, allow_trailing_empty: true,
@ -1874,7 +1875,7 @@ impl<'a> StrSlice<'a> for &'a str {
#[inline] #[inline]
fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep) fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep)
-> CharSplitsN<'a, Sep> { -> CharSplitsN<Sep> {
CharSplitsN { CharSplitsN {
iter: self.split(sep), iter: self.split(sep),
count: count, count: count,
@ -1884,7 +1885,7 @@ impl<'a> StrSlice<'a> for &'a str {
#[inline] #[inline]
fn split_terminator<Sep: CharEq>(&self, sep: Sep) fn split_terminator<Sep: CharEq>(&self, sep: Sep)
-> CharSplits<'a, Sep> { -> CharSplits<Sep> {
CharSplits { CharSplits {
allow_trailing_empty: false, allow_trailing_empty: false,
..self.split(sep) ..self.split(sep)
@ -1893,7 +1894,7 @@ impl<'a> StrSlice<'a> for &'a str {
#[inline] #[inline]
fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep) fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep)
-> CharSplitsN<'a, Sep> { -> CharSplitsN<Sep> {
CharSplitsN { CharSplitsN {
iter: self.split(sep), iter: self.split(sep),
count: count, count: count,
@ -1902,17 +1903,17 @@ impl<'a> StrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn match_indices(&self, sep: &'a str) -> MatchIndices<'a> { fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a> {
assert!(!sep.is_empty()) assert!(!sep.is_empty())
MatchIndices { MatchIndices {
haystack: *self, haystack: self,
needle: sep, needle: sep,
searcher: Searcher::new(self.as_bytes(), sep.as_bytes()) searcher: Searcher::new(self.as_bytes(), sep.as_bytes())
} }
} }
#[inline] #[inline]
fn split_str(&self, sep: &'a str) -> StrSplits<'a> { fn split_str<'a>(&'a self, sep: &'a str) -> StrSplits<'a> {
StrSplits { StrSplits {
it: self.match_indices(sep), it: self.match_indices(sep),
last_end: 0, last_end: 0,
@ -1921,11 +1922,11 @@ impl<'a> StrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn lines(&self) -> CharSplits<'a, char> { fn lines(&self) -> CharSplits<char> {
self.split_terminator('\n') self.split_terminator('\n')
} }
fn lines_any(&self) -> AnyLines<'a> { fn lines_any(&self) -> AnyLines {
self.lines().map(|line| { self.lines().map(|line| {
let l = line.len(); let l = line.len();
if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) } if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) }
@ -1937,38 +1938,38 @@ impl<'a> StrSlice<'a> for &'a str {
fn char_len(&self) -> uint { self.chars().count() } fn char_len(&self) -> uint { self.chars().count() }
#[inline] #[inline]
fn slice(&self, begin: uint, end: uint) -> &'a str { fn slice(&self, begin: uint, end: uint) -> &str {
// is_char_boundary checks that the index is in [0, .len()] // is_char_boundary checks that the index is in [0, .len()]
if begin <= end && if begin <= end &&
self.is_char_boundary(begin) && self.is_char_boundary(begin) &&
self.is_char_boundary(end) { self.is_char_boundary(end) {
unsafe { raw::slice_unchecked(*self, begin, end) } unsafe { raw::slice_unchecked(self, begin, end) }
} else { } else {
slice_error_fail(*self, begin, end) slice_error_fail(self, begin, end)
} }
} }
#[inline] #[inline]
fn slice_from(&self, begin: uint) -> &'a str { fn slice_from(&self, begin: uint) -> &str {
// is_char_boundary checks that the index is in [0, .len()] // is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(begin) { if self.is_char_boundary(begin) {
unsafe { raw::slice_unchecked(*self, begin, self.len()) } unsafe { raw::slice_unchecked(self, begin, self.len()) }
} else { } else {
slice_error_fail(*self, begin, self.len()) slice_error_fail(self, begin, self.len())
} }
} }
#[inline] #[inline]
fn slice_to(&self, end: uint) -> &'a str { fn slice_to(&self, end: uint) -> &str {
// is_char_boundary checks that the index is in [0, .len()] // is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(end) { if self.is_char_boundary(end) {
unsafe { raw::slice_unchecked(*self, 0, end) } unsafe { raw::slice_unchecked(self, 0, end) }
} else { } else {
slice_error_fail(*self, 0, end) slice_error_fail(self, 0, end)
} }
} }
fn slice_chars(&self, begin: uint, end: uint) -> &'a str { fn slice_chars(&self, begin: uint, end: uint) -> &str {
assert!(begin <= end); assert!(begin <= end);
let mut count = 0; let mut count = 0;
let mut begin_byte = None; let mut begin_byte = None;
@ -1987,12 +1988,12 @@ impl<'a> StrSlice<'a> for &'a str {
match (begin_byte, end_byte) { match (begin_byte, end_byte) {
(None, _) => fail!("slice_chars: `begin` is beyond end of string"), (None, _) => fail!("slice_chars: `begin` is beyond end of string"),
(_, None) => fail!("slice_chars: `end` is beyond end of string"), (_, None) => fail!("slice_chars: `end` is beyond end of string"),
(Some(a), Some(b)) => unsafe { raw::slice_bytes(*self, a, b) } (Some(a), Some(b)) => unsafe { raw::slice_bytes(self, a, b) }
} }
} }
#[inline] #[inline]
fn starts_with<'a>(&self, needle: &'a str) -> bool { fn starts_with(&self, needle: &str) -> bool {
let n = needle.len(); let n = needle.len();
self.len() >= n && needle.as_bytes() == self.as_bytes()[..n] self.len() >= n && needle.as_bytes() == self.as_bytes()[..n]
} }
@ -2004,10 +2005,10 @@ impl<'a> StrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str { fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
let cur = match self.find(|c: char| !to_trim.matches(c)) { let cur = match self.find(|c: char| !to_trim.matches(c)) {
None => "", None => "",
Some(i) => unsafe { raw::slice_bytes(*self, i, self.len()) } Some(i) => unsafe { raw::slice_bytes(self, i, self.len()) }
}; };
match cur.rfind(|c: char| !to_trim.matches(c)) { match cur.rfind(|c: char| !to_trim.matches(c)) {
None => "", None => "",
@ -2019,20 +2020,20 @@ impl<'a> StrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str { fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
match self.find(|c: char| !to_trim.matches(c)) { match self.find(|c: char| !to_trim.matches(c)) {
None => "", None => "",
Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) } Some(first) => unsafe { raw::slice_bytes(self, first, self.len()) }
} }
} }
#[inline] #[inline]
fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str { fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
match self.rfind(|c: char| !to_trim.matches(c)) { match self.rfind(|c: char| !to_trim.matches(c)) {
None => "", None => "",
Some(last) => { Some(last) => {
let next = self.char_range_at(last).next; let next = self.char_range_at(last).next;
unsafe { raw::slice_bytes(*self, 0u, next) } unsafe { raw::slice_bytes(self, 0u, next) }
} }
} }
} }
@ -2066,7 +2067,7 @@ impl<'a> StrSlice<'a> for &'a str {
return CharRange {ch: unsafe { mem::transmute(val) }, next: i + w}; return CharRange {ch: unsafe { mem::transmute(val) }, next: i + w};
} }
return multibyte_char_range_at(*self, i); return multibyte_char_range_at(self, i);
} }
#[inline] #[inline]
@ -2097,7 +2098,7 @@ impl<'a> StrSlice<'a> for &'a str {
return CharRange {ch: unsafe { mem::transmute(val) }, next: i}; return CharRange {ch: unsafe { mem::transmute(val) }, next: i};
} }
return multibyte_char_range_at_reverse(*self, prev); return multibyte_char_range_at_reverse(self, prev);
} }
#[inline] #[inline]
@ -2111,8 +2112,8 @@ impl<'a> StrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn as_bytes(&self) -> &'a [u8] { fn as_bytes(&self) -> &[u8] {
unsafe { mem::transmute(*self) } unsafe { mem::transmute(self) }
} }
fn find<C: CharEq>(&self, mut search: C) -> Option<uint> { fn find<C: CharEq>(&self, mut search: C) -> Option<uint> {
@ -2148,12 +2149,12 @@ impl<'a> StrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn slice_shift_char(&self) -> (Option<char>, &'a str) { fn slice_shift_char(&self) -> (Option<char>, &str) {
if self.is_empty() { if self.is_empty() {
return (None, *self); return (None, self);
} else { } else {
let CharRange {ch, next} = self.char_range_at(0u); let CharRange {ch, next} = self.char_range_at(0u);
let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) }; let next_s = unsafe { raw::slice_bytes(self, next, self.len()) };
return (Some(ch), next_s); return (Some(ch), next_s);
} }
} }
@ -2175,7 +2176,7 @@ impl<'a> StrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn utf16_units(&self) -> Utf16CodeUnits<'a> { fn utf16_units(&self) -> Utf16CodeUnits {
Utf16CodeUnits{ chars: self.chars(), extra: 0} Utf16CodeUnits{ chars: self.chars(), extra: 0}
} }
} }

View File

@ -15,6 +15,7 @@
#![experimental] #![experimental]
use collections::Collection; use collections::Collection;
use core::kinds::Sized;
use fmt; use fmt;
use iter::Iterator; use iter::Iterator;
use mem; use mem;
@ -272,7 +273,7 @@ impl OwnedAsciiCast for Vec<u8> {
/// Trait for converting an ascii type to a string. Needed to convert /// Trait for converting an ascii type to a string. Needed to convert
/// `&[Ascii]` to `&str`. /// `&[Ascii]` to `&str`.
pub trait AsciiStr { pub trait AsciiStr for Sized? {
/// Convert to a string. /// Convert to a string.
fn as_str_ascii<'a>(&'a self) -> &'a str; fn as_str_ascii<'a>(&'a self) -> &'a str;
@ -291,13 +292,13 @@ pub trait AsciiStr {
fn to_uppercase(&self) -> Vec<Ascii>; fn to_uppercase(&self) -> Vec<Ascii>;
/// Compares two Ascii strings ignoring case. /// Compares two Ascii strings ignoring case.
fn eq_ignore_case(self, other: &[Ascii]) -> bool; fn eq_ignore_case(&self, other: &[Ascii]) -> bool;
} }
impl<'a> AsciiStr for &'a [Ascii] { impl AsciiStr for [Ascii] {
#[inline] #[inline]
fn as_str_ascii<'a>(&'a self) -> &'a str { fn as_str_ascii<'a>(&'a self) -> &'a str {
unsafe { mem::transmute(*self) } unsafe { mem::transmute(self) }
} }
#[inline] #[inline]
@ -321,7 +322,7 @@ impl<'a> AsciiStr for &'a [Ascii] {
} }
#[inline] #[inline]
fn eq_ignore_case(self, other: &[Ascii]) -> bool { fn eq_ignore_case(&self, other: &[Ascii]) -> bool {
self.iter().zip(other.iter()).all(|(&a, &b)| a.eq_ignore_case(b)) self.iter().zip(other.iter()).all(|(&a, &b)| a.eq_ignore_case(b))
} }
} }
@ -372,7 +373,7 @@ pub trait OwnedAsciiExt {
} }
/// Extension methods for ASCII-subset only operations on string slices /// Extension methods for ASCII-subset only operations on string slices
pub trait AsciiExt<T> { pub trait AsciiExt<T> for Sized? {
/// Makes a copy of the string in ASCII upper case: /// Makes a copy of the string in ASCII upper case:
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged. /// but non-ASCII letters are unchanged.
@ -386,10 +387,10 @@ pub trait AsciiExt<T> {
/// Check that two strings are an ASCII case-insensitive match. /// Check that two strings are an ASCII case-insensitive match.
/// Same as `to_ascii_lower(a) == to_ascii_lower(b)`, /// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
/// but without allocating and copying temporary strings. /// but without allocating and copying temporary strings.
fn eq_ignore_ascii_case(&self, other: Self) -> bool; fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
} }
impl<'a> AsciiExt<String> for &'a str { impl AsciiExt<String> for str {
#[inline] #[inline]
fn to_ascii_upper(&self) -> String { fn to_ascii_upper(&self) -> String {
// Vec<u8>::to_ascii_upper() preserves the UTF-8 invariant. // Vec<u8>::to_ascii_upper() preserves the UTF-8 invariant.
@ -422,7 +423,7 @@ impl OwnedAsciiExt for String {
} }
} }
impl<'a> AsciiExt<Vec<u8>> for &'a [u8] { impl AsciiExt<Vec<u8>> for [u8] {
#[inline] #[inline]
fn to_ascii_upper(&self) -> Vec<u8> { fn to_ascii_upper(&self) -> Vec<u8> {
self.iter().map(|&byte| ASCII_UPPER_MAP[byte as uint]).collect() self.iter().map(|&byte| ASCII_UPPER_MAP[byte as uint]).collect()

View File

@ -367,7 +367,7 @@ impl Path {
/// Returns a normalized byte vector representation of a path, by removing all empty /// Returns a normalized byte vector representation of a path, by removing all empty
/// components, and unnecessary . and .. components. /// components, and unnecessary . and .. components.
fn normalize<V: AsSlice<u8>+CloneableVector<u8>>(v: V) -> Vec<u8> { fn normalize<V: AsSlice<u8>>(v: V) -> Vec<u8> {
// borrowck is being very picky // borrowck is being very picky
let val = { let val = {
let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE; let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE;

View File

@ -21,6 +21,7 @@ use core::clone::Clone;
use core::cmp; use core::cmp;
use core::collections::Collection; use core::collections::Collection;
use core::iter::{Filter, AdditiveIterator, Iterator, DoubleEndedIterator}; use core::iter::{Filter, AdditiveIterator, Iterator, DoubleEndedIterator};
use core::kinds::Sized;
use core::option::{Option, None, Some}; use core::option::{Option, None, Some};
use core::str::{CharSplits, StrSlice}; use core::str::{CharSplits, StrSlice};
use u_char; use u_char;
@ -32,7 +33,7 @@ pub type Words<'a> =
Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>; Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>;
/// Methods for Unicode string slices /// Methods for Unicode string slices
pub trait UnicodeStrSlice<'a> { pub trait UnicodeStrSlice for Sized? {
/// Returns an iterator over the /// Returns an iterator over the
/// [grapheme clusters](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) /// [grapheme clusters](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
/// of the string. /// of the string.
@ -52,7 +53,7 @@ pub trait UnicodeStrSlice<'a> {
/// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"]; /// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
/// assert_eq!(gr2.as_slice(), b); /// assert_eq!(gr2.as_slice(), b);
/// ``` /// ```
fn graphemes(&self, is_extended: bool) -> Graphemes<'a>; fn graphemes<'a>(&'a self, is_extended: bool) -> Graphemes<'a>;
/// Returns an iterator over the grapheme clusters of self and their byte offsets. /// Returns an iterator over the grapheme clusters of self and their byte offsets.
/// See `graphemes()` method for more information. /// See `graphemes()` method for more information.
@ -64,7 +65,7 @@ pub trait UnicodeStrSlice<'a> {
/// let b: &[_] = &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")]; /// let b: &[_] = &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
/// assert_eq!(gr_inds.as_slice(), b); /// assert_eq!(gr_inds.as_slice(), b);
/// ``` /// ```
fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices<'a>; fn grapheme_indices<'a>(&'a self, is_extended: bool) -> GraphemeIndices<'a>;
/// An iterator over the words of a string (subsequences separated /// An iterator over the words of a string (subsequences separated
/// by any sequence of whitespace). Sequences of whitespace are /// by any sequence of whitespace). Sequences of whitespace are
@ -77,7 +78,7 @@ pub trait UnicodeStrSlice<'a> {
/// let v: Vec<&str> = some_words.words().collect(); /// let v: Vec<&str> = some_words.words().collect();
/// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
/// ``` /// ```
fn words(&self) -> Words<'a>; fn words<'a>(&'a self) -> Words<'a>;
/// Returns true if the string contains only whitespace. /// Returns true if the string contains only whitespace.
/// ///
@ -120,28 +121,28 @@ pub trait UnicodeStrSlice<'a> {
fn width(&self, is_cjk: bool) -> uint; fn width(&self, is_cjk: bool) -> uint;
/// Returns a string with leading and trailing whitespace removed. /// Returns a string with leading and trailing whitespace removed.
fn trim(&self) -> &'a str; fn trim<'a>(&'a self) -> &'a str;
/// Returns a string with leading whitespace removed. /// Returns a string with leading whitespace removed.
fn trim_left(&self) -> &'a str; fn trim_left<'a>(&'a self) -> &'a str;
/// Returns a string with trailing whitespace removed. /// Returns a string with trailing whitespace removed.
fn trim_right(&self) -> &'a str; fn trim_right<'a>(&'a self) -> &'a str;
} }
impl<'a> UnicodeStrSlice<'a> for &'a str { impl UnicodeStrSlice for str {
#[inline] #[inline]
fn graphemes(&self, is_extended: bool) -> Graphemes<'a> { fn graphemes(&self, is_extended: bool) -> Graphemes {
Graphemes { string: *self, extended: is_extended, cat: None, catb: None } Graphemes { string: self, extended: is_extended, cat: None, catb: None }
} }
#[inline] #[inline]
fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices<'a> { fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
GraphemeIndices { start_offset: self.as_ptr() as uint, iter: self.graphemes(is_extended) } GraphemeIndices { start_offset: self.as_ptr() as uint, iter: self.graphemes(is_extended) }
} }
#[inline] #[inline]
fn words(&self) -> Words<'a> { fn words(&self) -> Words {
self.split(u_char::is_whitespace).filter(|s| !s.is_empty()) self.split(u_char::is_whitespace).filter(|s| !s.is_empty())
} }
@ -157,17 +158,17 @@ impl<'a> UnicodeStrSlice<'a> for &'a str {
} }
#[inline] #[inline]
fn trim(&self) -> &'a str { fn trim(&self) -> &str {
self.trim_left().trim_right() self.trim_left().trim_right()
} }
#[inline] #[inline]
fn trim_left(&self) -> &'a str { fn trim_left(&self) -> &str {
self.trim_left_chars(u_char::is_whitespace) self.trim_left_chars(u_char::is_whitespace)
} }
#[inline] #[inline]
fn trim_right(&self) -> &'a str { fn trim_right(&self) -> &str {
self.trim_right_chars(u_char::is_whitespace) self.trim_right_chars(u_char::is_whitespace)
} }
} }