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 core::cmp;
use core::kinds::Sized;
use core::mem::size_of;
use core::mem;
use core::prelude::{Clone, Collection, Greater, Iterator, Less, None, Option};
@ -109,7 +110,7 @@ pub use core::slice::{Found, NotFound};
// Functional utilities
#[allow(missing_doc)]
pub trait VectorVector<T> {
pub trait VectorVector<T> for Sized? {
// FIXME #5898: calling these .concat and .connect conflicts with
// StrVector::con{cat,nect}, since they have generic contents.
/// 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>;
}
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> {
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
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
pub trait CloneableVector<T> {
pub trait CloneableVector<T> for Sized? {
/// Copies `self` into a new `Vec`.
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`.
#[inline]
fn to_vec(&self) -> Vec<T> {
let mut vector = Vec::with_capacity(self.len());
vector.push_all(*self);
vector.push_all(self);
vector
}
}
@ -300,7 +301,7 @@ impl<T> BoxedSlice<T> for Box<[T]> {
}
/// 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
/// elements of `a` satisfy `f` and all elements of `b` do not.
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![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]
fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
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.
fn permutations(self) -> Permutations<T> {
fn permutations(&self) -> Permutations<T> {
Permutations{
swaps: ElementSwaps::new(self.len()),
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
/// mutable.
pub trait MutableSliceAllocating<'a, T> {
pub trait MutableSliceAllocating<T> for Sized? {
/// Sorts the slice, in place, using `compare` to compare
/// elements.
///
@ -582,7 +583,7 @@ pub trait MutableSliceAllocating<'a, T> {
/// v.sort_by(|a, b| b.cmp(a));
/// 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`
/// from the range [start,end).
@ -605,17 +606,17 @@ pub trait MutableSliceAllocating<'a, T> {
/// assert_eq!(num_moved, 3);
/// 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]
fn sort_by(self, compare: |&T, &T| -> Ordering) {
fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
merge_sort(self, compare)
}
#[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()) {
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
/// in-place sorting.
pub trait MutableOrdSlice<T> {
pub trait MutableOrdSlice<T> for Sized? {
/// Sorts the slice, in place.
///
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
@ -638,7 +639,7 @@ pub trait MutableOrdSlice<T> {
/// v.sort();
/// assert!(v == [-5i, -3, 1, 2, 4]);
/// ```
fn sort(self);
fn sort(&mut self);
/// Mutates the slice to the next lexicographic permutation.
///
@ -656,7 +657,7 @@ pub trait MutableOrdSlice<T> {
/// let b: &mut [_] = &mut [1i, 0, 2];
/// assert!(v == b);
/// ```
fn next_permutation(self) -> bool;
fn next_permutation(&mut self) -> bool;
/// Mutates the slice to the previous lexicographic permutation.
///
@ -674,16 +675,16 @@ pub trait MutableOrdSlice<T> {
/// let b: &mut [_] = &mut [0i, 1, 2];
/// 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]
fn sort(self) {
self.sort_by(|a,b| a.cmp(b))
fn sort(&mut self) {
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.
if self.len() < 2 { return false; }
@ -713,7 +714,7 @@ impl<'a, T: Ord> MutableOrdSlice<T> for &'a mut [T] {
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.
if self.len() < 2 { return false; }

View File

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

View File

@ -19,6 +19,7 @@
//! Their definition should always match the ABI defined in `rustc::back::abi`.
use mem;
use kinds::Sized;
/// The representation of a Rust slice
#[repr(C)]
@ -53,14 +54,14 @@ pub struct TraitObject {
/// This trait is meant to map equivalences between raw structs and their
/// 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
/// 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
/// enable write-access to the fields of the return value in safe code.
#[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<'a> Repr<Slice<u8>> for &'a str {}
impl<T> Repr<Slice<T>> for [T] {}
impl Repr<Slice<u8>> for str {}

View File

@ -48,7 +48,7 @@ use ptr;
use ptr::RawPtr;
use mem;
use mem::size_of;
use kinds::marker;
use kinds::{Sized, marker};
use raw::Repr;
// Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
use raw::Slice as RawSlice;
@ -60,7 +60,7 @@ use raw::Slice as RawSlice;
/// Extension methods for immutable slices.
#[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`).
///
/// 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.
#[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.
///
@ -76,7 +76,7 @@ pub trait ImmutableSlice<'a, T> {
///
/// Slicing from `self.len()` yields an empty slice.
#[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`.
///
@ -84,7 +84,7 @@ pub trait ImmutableSlice<'a, T> {
///
/// Slicing to `0` yields an empty slice.
#[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.
///
@ -94,29 +94,29 @@ pub trait ImmutableSlice<'a, T> {
///
/// Fails if `mid > len`.
#[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
#[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
/// `pred`. The matched element is not contained in the subslices.
#[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
/// `pred`, limited to splitting at most `n` times. The matched element is
/// not contained in the subslices.
#[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
/// `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 subslices.
#[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
/// `size`. The windows overlap. If the slice is shorter than
@ -138,7 +138,7 @@ pub trait ImmutableSlice<'a, T> {
/// }
/// ```
#[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
/// 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"]
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
/// index is out of bounds.
#[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.
#[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.
#[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.
#[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.
#[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
/// bounds checking.
#[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
///
@ -237,9 +237,9 @@ pub trait ImmutableSlice<'a, T> {
}
#[unstable]
impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
impl<T> ImmutableSlice<T> for [T] {
#[inline]
fn slice(&self, start: uint, end: uint) -> &'a [T] {
fn slice(&self, start: uint, end: uint) -> &[T] {
assert!(start <= end);
assert!(end <= self.len());
unsafe {
@ -251,22 +251,22 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
}
#[inline]
fn slice_from(&self, start: uint) -> &'a [T] {
fn slice_from(&self, start: uint) -> &[T] {
self.slice(start, self.len())
}
#[inline]
fn slice_to(&self, end: uint) -> &'a [T] {
fn slice_to(&self, end: uint) -> &[T] {
self.slice(0, end)
}
#[inline]
fn split_at(&self, mid: uint) -> (&'a [T], &'a [T]) {
((*self)[..mid], (*self)[mid..])
fn split_at(&self, mid: uint) -> (&[T], &[T]) {
(self[..mid], self[mid..])
}
#[inline]
fn iter(self) -> Items<'a, T> {
fn iter<'a>(&'a self) -> Items<'a, T> {
unsafe {
let p = self.as_ptr();
if mem::size_of::<T>() == 0 {
@ -282,7 +282,7 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
}
#[inline]
fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
Splits {
v: self,
pred: pred,
@ -291,7 +291,7 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
}
#[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 {
iter: self.split(pred),
count: n,
@ -300,7 +300,7 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
}
#[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 {
iter: self.split(pred),
count: n,
@ -309,42 +309,42 @@ impl<'a,T> ImmutableSlice<'a, T> for &'a [T] {
}
#[inline]
fn windows(self, size: uint) -> Windows<'a, T> {
fn windows(&self, size: uint) -> Windows<T> {
assert!(size != 0);
Windows { v: self, size: size }
}
#[inline]
fn chunks(self, size: uint) -> Chunks<'a, T> {
fn chunks(&self, size: uint) -> Chunks<T> {
assert!(size != 0);
Chunks { v: self, size: size }
}
#[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 }
}
#[inline]
fn head(&self) -> Option<&'a T> {
fn head(&self) -> Option<&T> {
if self.len() == 0 { None } else { Some(&self[0]) }
}
#[inline]
fn tail(&self) -> &'a [T] { (*self)[1..] }
fn tail(&self) -> &[T] { self[1..] }
#[inline]
fn init(&self) -> &'a [T] {
(*self)[..self.len() - 1]
fn init(&self) -> &[T] {
self[..self.len() - 1]
}
#[inline]
fn last(&self) -> Option<&'a T> {
fn last(&self) -> Option<&T> {
if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
}
#[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))
}
@ -436,14 +436,14 @@ impl<T> ops::SliceMut<uint, [T]> for [T] {
/// Extension methods for slices such that their elements are
/// mutable.
#[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,
/// or `None` if the index is out of bounds
#[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.
/// 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`).
///
@ -452,7 +452,7 @@ pub trait MutableSlice<'a, T> {
///
/// Slicing with `start` equal to `end` yields an empty slice.
#[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.
///
@ -460,7 +460,7 @@ pub trait MutableSlice<'a, T> {
///
/// Slicing from `self.len()` yields an empty slice.
#[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`.
///
@ -468,45 +468,45 @@ pub trait MutableSlice<'a, T> {
///
/// Slicing to `0` yields an empty slice.
#[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
#[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
#[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
#[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
#[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.
#[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
/// match `pred`. The matched element is not contained in the subslices.
#[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
/// `pred`, limited to splitting at most `n` times. The matched element is
/// not contained in the subslices.
#[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
/// `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 subslices.
#[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.
/// 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.
#[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.
///
@ -536,7 +536,7 @@ pub trait MutableSlice<'a, T> {
/// assert!(v == ["a", "d", "c", "b"]);
/// ```
#[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.
///
@ -571,7 +571,7 @@ pub trait MutableSlice<'a, T> {
/// }
/// ```
#[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.
///
@ -583,11 +583,11 @@ pub trait MutableSlice<'a, T> {
/// assert!(v == [3i, 2, 1]);
/// ```
#[experimental = "may be moved to iterators instead"]
fn reverse(self);
fn reverse(&mut self);
/// Returns an unsafe mutable pointer to the element in index
#[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.
///
@ -598,43 +598,43 @@ pub trait MutableSlice<'a, T> {
/// would also make any pointers to it invalid.
#[inline]
#[unstable]
fn as_mut_ptr(self) -> *mut T;
fn as_mut_ptr(&mut self) -> *mut T;
}
#[experimental = "trait is experimental"]
impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
impl<T> MutableSlice<T> for [T] {
#[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 }
}
#[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]
}
#[inline]
fn slice_from_mut(self, start: uint) -> &'a mut [T] {
fn slice_from_mut(&mut self, start: uint) -> &mut [T] {
self[mut start..]
}
#[inline]
fn slice_to_mut(self, end: uint) -> &'a mut [T] {
fn slice_to_mut(&mut self, end: uint) -> &mut [T] {
self[mut ..end]
}
#[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 {
let self2: &'a mut [T] = mem::transmute_copy(&self);
let self2: &mut [T] = mem::transmute_copy(&self);
(self[mut ..mid], self2[mut mid..])
}
}
#[inline]
fn iter_mut(self) -> MutItems<'a, T> {
fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
unsafe {
let p = self.as_mut_ptr();
if mem::size_of::<T>() == 0 {
@ -652,36 +652,36 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
}
#[inline]
fn last_mut(self) -> Option<&'a mut T> {
fn last_mut(&mut self) -> Option<&mut T> {
let len = self.len();
if len == 0 { return None; }
Some(&mut self[len - 1])
}
#[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]) }
}
#[inline]
fn tail_mut(self) -> &'a mut [T] {
fn tail_mut(&mut self) -> &mut [T] {
let len = self.len();
self[mut 1..len]
}
#[inline]
fn init_mut(self) -> &'a mut [T] {
fn init_mut(&mut self) -> &mut [T] {
let len = self.len();
self[mut 0..len - 1]
}
#[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 }
}
#[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 {
iter: self.split_mut(pred),
count: n,
@ -690,7 +690,7 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
}
#[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 {
iter: self.split_mut(pred),
count: n,
@ -699,12 +699,12 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
}
#[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);
MutChunks { v: self, chunk_size: chunk_size }
}
fn swap(self, a: uint, b: uint) {
fn swap(&mut self, a: uint, b: uint) {
unsafe {
// Can't take two mutable loans from one vector, so instead just cast
// 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 ln = self.len();
while i < ln / 2 {
@ -729,19 +729,19 @@ impl<'a,T> MutableSlice<'a, T> for &'a mut [T] {
}
#[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))
}
#[inline]
fn as_mut_ptr(self) -> *mut T {
fn as_mut_ptr(&mut self) -> *mut T {
self.repr().data as *mut T
}
}
/// Extension methods for slices containing `PartialEq` elements.
#[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.
fn position_elem(&self, t: &T) -> Option<uint>;
@ -759,7 +759,7 @@ pub trait ImmutablePartialEqSlice<T:PartialEq> {
}
#[unstable = "trait is unstable"]
impl<'a,T:PartialEq> ImmutablePartialEqSlice<T> for &'a [T] {
impl<T: PartialEq> ImmutablePartialEqSlice<T> for [T] {
#[inline]
fn position_elem(&self, x: &T) -> Option<uint> {
self.iter().position(|y| *x == *y)
@ -778,19 +778,19 @@ impl<'a,T:PartialEq> ImmutablePartialEqSlice<T> for &'a [T] {
#[inline]
fn starts_with(&self, needle: &[T]) -> bool {
let n = needle.len();
self.len() >= n && needle == (*self)[..n]
self.len() >= n && needle == self[..n]
}
#[inline]
fn ends_with(&self, needle: &[T]) -> bool {
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.
#[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.
///
/// If the value is found then `Found` is returned, containing the
@ -820,7 +820,7 @@ pub trait ImmutableOrdSlice<T: Ord> {
}
#[unstable = "trait is unstable"]
impl<'a, T: Ord> ImmutableOrdSlice<T> for &'a [T] {
impl<T: Ord> ImmutableOrdSlice<T> for [T] {
#[unstable]
fn binary_search_elem(&self, x: &T) -> BinarySearchResult {
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
#[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
/// shorter of `self.len()` and `src.len()`). Returns the number
/// of elements copied.
@ -849,13 +849,13 @@ pub trait MutableCloneableSlice<T> {
/// assert!(dst.clone_from_slice(src2) == 3);
/// assert!(dst == [3i, 4, 5]);
/// ```
fn clone_from_slice(self, &[T]) -> uint;
fn clone_from_slice(&mut self, &[T]) -> uint;
}
#[unstable = "trait is unstable"]
impl<'a, T: Clone> MutableCloneableSlice<T> for &'a mut [T] {
impl<T: Clone> MutableCloneableSlice<T> for [T] {
#[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 dst = self.slice_to_mut(min);
let src = src.slice_to(min);
@ -1509,19 +1509,20 @@ pub mod raw {
#[experimental = "needs review"]
pub mod bytes {
use collections::Collection;
use kinds::Sized;
use ptr;
use slice::{ImmutableSlice, MutableSlice};
/// 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.
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]
#[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()) };
}
}
@ -1623,53 +1624,51 @@ impl<'a, T: PartialOrd> PartialOrd for &'a [T] {
/// Extension methods for immutable slices containing integers.
#[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.
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.
fn as_signed(self) -> &'a [S];
fn as_signed<'a>(&'a self) -> &'a [S];
}
/// Extension methods for mutable slices containing integers.
#[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.
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.
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 {
($u:ty, $s:ty, $t:ty) => {
#[experimental]
impl<'a> ImmutableIntSlice<'a, $u, $s> for $t {
impl ImmutableIntSlice<$u, $s> for [$t] {
#[inline]
fn as_unsigned(self) -> &'a [$u] { unsafe { transmute(self) } }
fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } }
#[inline]
fn as_signed(self) -> &'a [$s] { unsafe { transmute(self) } }
fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } }
}
}
}
macro_rules! impl_mut_int_slice {
($u:ty, $s:ty, $t:ty) => {
#[experimental]
impl<'a> MutableIntSlice<'a, $u, $s> for $t {
impl MutableIntSlice<$u, $s> for [$t] {
#[inline]
fn as_unsigned_mut(self) -> &'a mut [$u] { unsafe { transmute(self) } }
fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } }
#[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 {
($u:ty, $s:ty) => {
impl_immut_int_slice!($u, $s, &'a [$u])
impl_immut_int_slice!($u, $s, &'a [$s])
impl_immut_int_slice!($u, $s, &'a mut [$u])
impl_immut_int_slice!($u, $s, &'a mut [$s])
impl_mut_int_slice!($u, $s, &'a mut [$u])
impl_mut_int_slice!($u, $s, &'a mut [$s])
impl_immut_int_slice!($u, $s, $u)
impl_immut_int_slice!($u, $s, $s)
impl_mut_int_slice!($u, $s, $u)
impl_mut_int_slice!($u, $s, $s)
}
}

View File

@ -27,6 +27,7 @@ use default::Default;
use iter::{Map, Iterator};
use iter::{DoubleEndedIterator, ExactSize};
use iter::range;
use kinds::Sized;
use num::{CheckedMul, Saturating};
use option::{Option, None, Some};
use raw::Repr;
@ -1206,7 +1207,7 @@ impl<'a> Collection for &'a str {
}
/// Methods for string slices
pub trait StrSlice<'a> {
pub trait StrSlice for Sized? {
/// Returns true if one string contains another
///
/// # Arguments
@ -1218,7 +1219,7 @@ pub trait StrSlice<'a> {
/// ```rust
/// 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.
///
@ -1242,7 +1243,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<char> = "abc åäö".chars().collect();
/// 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`
///
@ -1252,10 +1253,10 @@ pub trait StrSlice<'a> {
/// let v: Vec<u8> = "bors".bytes().collect();
/// 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.
fn char_indices(&self) -> CharOffsets<'a>;
fn char_indices<'a>(&'a self) -> CharOffsets<'a>;
/// An iterator over substrings of `self`, separated by characters
/// matched by `sep`.
@ -1275,7 +1276,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = "".split('X').collect();
/// 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
/// 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();
/// 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
/// matched by `sep`.
@ -1325,7 +1326,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
/// 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
/// 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();
/// 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
/// matches of `sep` within `self`.
@ -1365,7 +1366,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<(uint, uint)> = "ababa".match_indices("aba").collect();
/// 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`.
///
@ -1378,7 +1379,7 @@ pub trait StrSlice<'a> {
/// let v: Vec<&str> = "1abcabc2".split_str("abc").collect();
/// 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
/// 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();
/// 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
/// `\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();
/// 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
/// string holds.
@ -1469,7 +1470,7 @@ pub trait StrSlice<'a> {
/// // byte 100 is outside the string
/// // 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.
///
@ -1479,7 +1480,7 @@ pub trait StrSlice<'a> {
/// out of bounds.
///
/// 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
/// `end`.
@ -1490,7 +1491,7 @@ pub trait StrSlice<'a> {
/// out of bounds.
///
/// 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
/// [`begin`..`end`).
@ -1515,7 +1516,7 @@ pub trait StrSlice<'a> {
/// assert_eq!(s.slice_chars(0, 4), "Löwe");
/// 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.
///
@ -1549,7 +1550,7 @@ pub trait StrSlice<'a> {
/// assert_eq!("12foo1bar12".trim_chars(x), "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.
///
@ -1565,7 +1566,7 @@ pub trait StrSlice<'a> {
/// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12")
/// 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.
///
@ -1581,7 +1582,7 @@ pub trait StrSlice<'a> {
/// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar")
/// 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
/// UTF-8 code point sequence.
@ -1707,7 +1708,7 @@ pub trait StrSlice<'a> {
/// ```rust
/// 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
/// matches `search`.
@ -1798,7 +1799,7 @@ pub trait StrSlice<'a> {
/// assert_eq!(c, Some('ö'));
/// 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.
///
@ -1825,7 +1826,7 @@ pub trait StrSlice<'a> {
fn as_ptr(&self) -> *const u8;
/// 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)]
@ -1835,9 +1836,9 @@ fn slice_error_fail(s: &str, begin: uint, end: uint) -> ! {
begin, end, s);
}
impl<'a> StrSlice<'a> for &'a str {
impl StrSlice for str {
#[inline]
fn contains<'a>(&self, needle: &'a str) -> bool {
fn contains(&self, needle: &str) -> bool {
self.find_str(needle).is_some()
}
@ -1847,24 +1848,24 @@ impl<'a> StrSlice<'a> for &'a str {
}
#[inline]
fn chars(&self) -> Chars<'a> {
fn chars(&self) -> Chars {
Chars{iter: self.as_bytes().iter()}
}
#[inline]
fn bytes(&self) -> Bytes<'a> {
fn bytes(&self) -> Bytes {
self.as_bytes().iter().map(|&b| b)
}
#[inline]
fn char_indices(&self) -> CharOffsets<'a> {
fn char_indices(&self) -> CharOffsets {
CharOffsets{front_offset: 0, iter: self.chars()}
}
#[inline]
fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep> {
fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<Sep> {
CharSplits {
string: *self,
string: self,
only_ascii: sep.only_ascii(),
sep: sep,
allow_trailing_empty: true,
@ -1874,7 +1875,7 @@ impl<'a> StrSlice<'a> for &'a str {
#[inline]
fn splitn<Sep: CharEq>(&self, count: uint, sep: Sep)
-> CharSplitsN<'a, Sep> {
-> CharSplitsN<Sep> {
CharSplitsN {
iter: self.split(sep),
count: count,
@ -1884,7 +1885,7 @@ impl<'a> StrSlice<'a> for &'a str {
#[inline]
fn split_terminator<Sep: CharEq>(&self, sep: Sep)
-> CharSplits<'a, Sep> {
-> CharSplits<Sep> {
CharSplits {
allow_trailing_empty: false,
..self.split(sep)
@ -1893,7 +1894,7 @@ impl<'a> StrSlice<'a> for &'a str {
#[inline]
fn rsplitn<Sep: CharEq>(&self, count: uint, sep: Sep)
-> CharSplitsN<'a, Sep> {
-> CharSplitsN<Sep> {
CharSplitsN {
iter: self.split(sep),
count: count,
@ -1902,17 +1903,17 @@ impl<'a> StrSlice<'a> for &'a str {
}
#[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())
MatchIndices {
haystack: *self,
haystack: self,
needle: sep,
searcher: Searcher::new(self.as_bytes(), sep.as_bytes())
}
}
#[inline]
fn split_str(&self, sep: &'a str) -> StrSplits<'a> {
fn split_str<'a>(&'a self, sep: &'a str) -> StrSplits<'a> {
StrSplits {
it: self.match_indices(sep),
last_end: 0,
@ -1921,11 +1922,11 @@ impl<'a> StrSlice<'a> for &'a str {
}
#[inline]
fn lines(&self) -> CharSplits<'a, char> {
fn lines(&self) -> CharSplits<char> {
self.split_terminator('\n')
}
fn lines_any(&self) -> AnyLines<'a> {
fn lines_any(&self) -> AnyLines {
self.lines().map(|line| {
let l = line.len();
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() }
#[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()]
if begin <= end &&
self.is_char_boundary(begin) &&
self.is_char_boundary(end) {
unsafe { raw::slice_unchecked(*self, begin, end) }
unsafe { raw::slice_unchecked(self, begin, end) }
} else {
slice_error_fail(*self, begin, end)
slice_error_fail(self, begin, end)
}
}
#[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()]
if self.is_char_boundary(begin) {
unsafe { raw::slice_unchecked(*self, begin, self.len()) }
unsafe { raw::slice_unchecked(self, begin, self.len()) }
} else {
slice_error_fail(*self, begin, self.len())
slice_error_fail(self, begin, self.len())
}
}
#[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()]
if self.is_char_boundary(end) {
unsafe { raw::slice_unchecked(*self, 0, end) }
unsafe { raw::slice_unchecked(self, 0, end) }
} 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);
let mut count = 0;
let mut begin_byte = None;
@ -1987,12 +1988,12 @@ impl<'a> StrSlice<'a> for &'a str {
match (begin_byte, end_byte) {
(None, _) => fail!("slice_chars: `begin` 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]
fn starts_with<'a>(&self, needle: &'a str) -> bool {
fn starts_with(&self, needle: &str) -> bool {
let n = needle.len();
self.len() >= n && needle.as_bytes() == self.as_bytes()[..n]
}
@ -2004,10 +2005,10 @@ impl<'a> StrSlice<'a> for &'a str {
}
#[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)) {
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)) {
None => "",
@ -2019,20 +2020,20 @@ impl<'a> StrSlice<'a> for &'a str {
}
#[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)) {
None => "",
Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
Some(first) => unsafe { raw::slice_bytes(self, first, self.len()) }
}
}
#[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)) {
None => "",
Some(last) => {
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 multibyte_char_range_at(*self, i);
return multibyte_char_range_at(self, i);
}
#[inline]
@ -2097,7 +2098,7 @@ impl<'a> StrSlice<'a> for &'a str {
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]
@ -2111,8 +2112,8 @@ impl<'a> StrSlice<'a> for &'a str {
}
#[inline]
fn as_bytes(&self) -> &'a [u8] {
unsafe { mem::transmute(*self) }
fn as_bytes(&self) -> &[u8] {
unsafe { mem::transmute(self) }
}
fn find<C: CharEq>(&self, mut search: C) -> Option<uint> {
@ -2148,12 +2149,12 @@ impl<'a> StrSlice<'a> for &'a str {
}
#[inline]
fn slice_shift_char(&self) -> (Option<char>, &'a str) {
fn slice_shift_char(&self) -> (Option<char>, &str) {
if self.is_empty() {
return (None, *self);
return (None, self);
} else {
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);
}
}
@ -2175,7 +2176,7 @@ impl<'a> StrSlice<'a> for &'a str {
}
#[inline]
fn utf16_units(&self) -> Utf16CodeUnits<'a> {
fn utf16_units(&self) -> Utf16CodeUnits {
Utf16CodeUnits{ chars: self.chars(), extra: 0}
}
}

View File

@ -15,6 +15,7 @@
#![experimental]
use collections::Collection;
use core::kinds::Sized;
use fmt;
use iter::Iterator;
use mem;
@ -272,7 +273,7 @@ impl OwnedAsciiCast for Vec<u8> {
/// Trait for converting an ascii type to a string. Needed to convert
/// `&[Ascii]` to `&str`.
pub trait AsciiStr {
pub trait AsciiStr for Sized? {
/// Convert to a string.
fn as_str_ascii<'a>(&'a self) -> &'a str;
@ -291,13 +292,13 @@ pub trait AsciiStr {
fn to_uppercase(&self) -> Vec<Ascii>;
/// 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]
fn as_str_ascii<'a>(&'a self) -> &'a str {
unsafe { mem::transmute(*self) }
unsafe { mem::transmute(self) }
}
#[inline]
@ -321,7 +322,7 @@ impl<'a> AsciiStr for &'a [Ascii] {
}
#[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))
}
}
@ -372,7 +373,7 @@ pub trait OwnedAsciiExt {
}
/// 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:
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged.
@ -386,10 +387,10 @@ pub trait AsciiExt<T> {
/// Check that two strings are an ASCII case-insensitive match.
/// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
/// 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]
fn to_ascii_upper(&self) -> String {
// 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]
fn to_ascii_upper(&self) -> Vec<u8> {
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
/// 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
let val = {
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::collections::Collection;
use core::iter::{Filter, AdditiveIterator, Iterator, DoubleEndedIterator};
use core::kinds::Sized;
use core::option::{Option, None, Some};
use core::str::{CharSplits, StrSlice};
use u_char;
@ -32,7 +33,7 @@ pub type Words<'a> =
Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>;
/// Methods for Unicode string slices
pub trait UnicodeStrSlice<'a> {
pub trait UnicodeStrSlice for Sized? {
/// Returns an iterator over the
/// [grapheme clusters](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
/// of the string.
@ -52,7 +53,7 @@ pub trait UnicodeStrSlice<'a> {
/// let b: &[_] = &["a", "\r\n", "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.
/// See `graphemes()` method for more information.
@ -64,7 +65,7 @@ pub trait UnicodeStrSlice<'a> {
/// let b: &[_] = &[(0u, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
/// 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
/// 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();
/// 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.
///
@ -120,28 +121,28 @@ pub trait UnicodeStrSlice<'a> {
fn width(&self, is_cjk: bool) -> uint;
/// 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.
fn trim_left(&self) -> &'a str;
fn trim_left<'a>(&'a self) -> &'a str;
/// 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]
fn graphemes(&self, is_extended: bool) -> Graphemes<'a> {
Graphemes { string: *self, extended: is_extended, cat: None, catb: None }
fn graphemes(&self, is_extended: bool) -> Graphemes {
Graphemes { string: self, extended: is_extended, cat: None, catb: None }
}
#[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) }
}
#[inline]
fn words(&self) -> Words<'a> {
fn words(&self) -> Words {
self.split(u_char::is_whitespace).filter(|s| !s.is_empty())
}
@ -157,17 +158,17 @@ impl<'a> UnicodeStrSlice<'a> for &'a str {
}
#[inline]
fn trim(&self) -> &'a str {
fn trim(&self) -> &str {
self.trim_left().trim_right()
}
#[inline]
fn trim_left(&self) -> &'a str {
fn trim_left(&self) -> &str {
self.trim_left_chars(u_char::is_whitespace)
}
#[inline]
fn trim_right(&self) -> &'a str {
fn trim_right(&self) -> &str {
self.trim_right_chars(u_char::is_whitespace)
}
}