merge *SliceExt traits, use assoc types in SliceExt, Raw[Mut]Ptr

This commit is contained in:
Jorge Aparicio 2015-01-02 09:12:27 -05:00
parent 167683da23
commit cc5ecaf765
20 changed files with 489 additions and 494 deletions

View File

@ -25,6 +25,7 @@
#![feature(macro_rules, default_type_params, phase, globs)]
#![feature(unsafe_destructor, slicing_syntax)]
#![feature(unboxed_closures)]
#![feature(associated_types)]
#![no_std]
#[phase(plugin, link)] extern crate core;
@ -120,7 +121,6 @@ mod prelude {
pub use core::result::Result::{Ok, Err};
// in core and collections (may differ).
pub use slice::{PartialEqSliceExt, OrdSliceExt};
pub use slice::{AsSlice, SliceExt};
pub use str::{from_str, Str, StrExt};
@ -129,7 +129,7 @@ mod prelude {
pub use unicode::char::UnicodeChar;
// from collections.
pub use slice::{CloneSliceExt, SliceConcatExt};
pub use slice::SliceConcatExt;
pub use str::IntoMaybeOwned;
pub use string::{String, ToString};
pub use vec::Vec;

View File

@ -96,7 +96,7 @@ use core::mem::size_of;
use core::mem;
use core::ops::{FnMut,SliceMut};
use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
use core::prelude::{Ord, Ordering, PtrExt, Some, range, IteratorCloneExt, Result};
use core::prelude::{Ord, Ordering, PartialEq, PtrExt, Some, range, IteratorCloneExt, Result};
use core::ptr;
use core::slice as core_slice;
use self::Direction::*;
@ -104,7 +104,7 @@ use self::Direction::*;
use vec::Vec;
pub use core::slice::{Chunks, AsSlice, Windows};
pub use core::slice::{Iter, IterMut, PartialEqSliceExt};
pub use core::slice::{Iter, IterMut};
pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split};
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
pub use core::slice::{bytes, mut_ref_slice, ref_slice};
@ -122,7 +122,9 @@ pub type MutItems<'a, T:'a> = IterMut<'a, T>;
/// Allocating extension methods for slices.
#[unstable = "needs associated types, may merge with other traits"]
pub trait SliceExt<T> for Sized? {
pub trait SliceExt for Sized? {
type Item;
/// Sorts the slice, in place, using `compare` to compare
/// elements.
///
@ -141,7 +143,7 @@ pub trait SliceExt<T> for Sized? {
/// assert!(v == [5, 4, 3, 2, 1]);
/// ```
#[stable]
fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering;
fn sort_by<F>(&mut self, compare: F) where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
/// Consumes `src` and moves as many elements as it can into `self`
/// from the range [start,end).
@ -165,7 +167,7 @@ pub trait SliceExt<T> for Sized? {
/// assert!(a == [6i, 7, 8, 4, 5]);
/// ```
#[experimental = "uncertain about this API approach"]
fn move_from(&mut self, src: Vec<T>, start: uint, end: uint) -> uint;
fn move_from(&mut self, src: Vec<Self::Item>, start: uint, end: uint) -> uint;
/// Returns a subslice spanning the interval [`start`, `end`).
///
@ -174,7 +176,7 @@ pub trait SliceExt<T> for Sized? {
///
/// Slicing with `start` equal to `end` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
fn slice(&self, start: uint, end: uint) -> &[T];
fn slice(&self, start: uint, end: uint) -> &[Self::Item];
/// Returns a subslice from `start` to the end of the slice.
///
@ -182,7 +184,7 @@ pub trait SliceExt<T> for Sized? {
///
/// Slicing from `self.len()` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
fn slice_from(&self, start: uint) -> &[T];
fn slice_from(&self, start: uint) -> &[Self::Item];
/// Returns a subslice from the start of the slice to `end`.
///
@ -190,7 +192,7 @@ pub trait SliceExt<T> for Sized? {
///
/// Slicing to `0` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
fn slice_to(&self, end: uint) -> &[T];
fn slice_to(&self, end: uint) -> &[Self::Item];
/// Divides one slice into two at an index.
///
@ -200,32 +202,32 @@ pub trait SliceExt<T> for Sized? {
///
/// Panics if `mid > len`.
#[stable]
fn split_at(&self, mid: uint) -> (&[T], &[T]);
fn split_at(&self, mid: uint) -> (&[Self::Item], &[Self::Item]);
/// Returns an iterator over the slice
#[stable]
fn iter(&self) -> Iter<T>;
fn iter(&self) -> Iter<Self::Item>;
/// Returns an iterator over subslices separated by elements that match
/// `pred`. The matched element is not contained in the subslices.
#[stable]
fn split<F>(&self, pred: F) -> Split<T, F>
where F: FnMut(&T) -> bool;
fn split<F>(&self, pred: F) -> Split<Self::Item, F>
where F: FnMut(&Self::Item) -> bool;
/// 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.
#[stable]
fn splitn<F>(&self, n: uint, pred: F) -> SplitN<T, F>
where F: FnMut(&T) -> bool;
fn splitn<F>(&self, n: uint, pred: F) -> SplitN<Self::Item, F>
where F: FnMut(&Self::Item) -> bool;
/// 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.
#[stable]
fn rsplitn<F>(&self, n: uint, pred: F) -> RSplitN<T, F>
where F: FnMut(&T) -> bool;
fn rsplitn<F>(&self, n: uint, pred: F) -> RSplitN<Self::Item, F>
where F: FnMut(&Self::Item) -> bool;
/// Returns an iterator over all contiguous windows of length
/// `size`. The windows overlap. If the slice is shorter than
@ -247,7 +249,7 @@ pub trait SliceExt<T> for Sized? {
/// }
/// ```
#[stable]
fn windows(&self, size: uint) -> Windows<T>;
fn windows(&self, size: uint) -> Windows<Self::Item>;
/// Returns an iterator over `size` elements of the slice at a
/// time. The chunks do not overlap. If `size` does not divide the
@ -270,41 +272,41 @@ pub trait SliceExt<T> for Sized? {
/// }
/// ```
#[stable]
fn chunks(&self, size: uint) -> Chunks<T>;
fn chunks(&self, size: uint) -> Chunks<Self::Item>;
/// Returns the element of a slice at the given index, or `None` if the
/// index is out of bounds.
#[stable]
fn get(&self, index: uint) -> Option<&T>;
fn get(&self, index: uint) -> Option<&Self::Item>;
/// Returns the first element of a slice, or `None` if it is empty.
#[stable]
fn first(&self) -> Option<&T>;
fn first(&self) -> Option<&Self::Item>;
/// Deprecated: renamed to `first`.
#[deprecated = "renamed to `first`"]
fn head(&self) -> Option<&T> { self.first() }
fn head(&self) -> Option<&Self::Item> { self.first() }
/// Returns all but the first element of a slice.
#[experimental = "likely to be renamed"]
fn tail(&self) -> &[T];
fn tail(&self) -> &[Self::Item];
/// Returns all but the last element of a slice.
#[experimental = "likely to be renamed"]
fn init(&self) -> &[T];
fn init(&self) -> &[Self::Item];
/// Returns the last element of a slice, or `None` if it is empty.
#[stable]
fn last(&self) -> Option<&T>;
fn last(&self) -> Option<&Self::Item>;
/// Returns a pointer to the element at the given index, without doing
/// bounds checking.
#[stable]
unsafe fn get_unchecked(&self, index: uint) -> &T;
unsafe fn get_unchecked(&self, index: uint) -> &Self::Item;
/// Deprecated: renamed to `get_unchecked`.
#[deprecated = "renamed to get_unchecked"]
unsafe fn unsafe_get(&self, index: uint) -> &T {
unsafe fn unsafe_get(&self, index: uint) -> &Self::Item {
self.get_unchecked(index)
}
@ -316,7 +318,7 @@ pub trait SliceExt<T> for Sized? {
/// Modifying the slice may cause its buffer to be reallocated, which
/// would also make any pointers to it invalid.
#[stable]
fn as_ptr(&self) -> *const T;
fn as_ptr(&self) -> *const Self::Item;
/// Binary search a sorted slice with a comparator function.
///
@ -352,7 +354,7 @@ pub trait SliceExt<T> for Sized? {
/// ```
#[stable]
fn binary_search_by<F>(&self, f: F) -> Result<uint, uint> where
F: FnMut(&T) -> Ordering;
F: FnMut(&Self::Item) -> Ordering;
/// Return the number of elements in the slice
///
@ -379,12 +381,12 @@ pub trait SliceExt<T> for Sized? {
/// Returns a mutable reference to the element at the given index,
/// or `None` if the index is out of bounds
#[stable]
fn get_mut(&mut self, index: uint) -> Option<&mut T>;
fn get_mut(&mut self, index: uint) -> Option<&mut Self::Item>;
/// Work with `self` as a mut slice.
/// Primarily intended for getting a &mut [T] from a [T; N].
#[stable]
fn as_mut_slice(&mut self) -> &mut [T];
fn as_mut_slice(&mut self) -> &mut [Self::Item];
/// Returns a mutable subslice spanning the interval [`start`, `end`).
///
@ -393,7 +395,7 @@ pub trait SliceExt<T> for Sized? {
///
/// Slicing with `start` equal to `end` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T];
fn slice_mut(&mut self, start: uint, end: uint) -> &mut [Self::Item];
/// Returns a mutable subslice from `start` to the end of the slice.
///
@ -401,7 +403,7 @@ pub trait SliceExt<T> for Sized? {
///
/// Slicing from `self.len()` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
fn slice_from_mut(&mut self, start: uint) -> &mut [T];
fn slice_from_mut(&mut self, start: uint) -> &mut [Self::Item];
/// Returns a mutable subslice from the start of the slice to `end`.
///
@ -409,54 +411,54 @@ pub trait SliceExt<T> for Sized? {
///
/// Slicing to `0` yields an empty slice.
#[experimental = "will be replaced by slice syntax"]
fn slice_to_mut(&mut self, end: uint) -> &mut [T];
fn slice_to_mut(&mut self, end: uint) -> &mut [Self::Item];
/// Returns an iterator that allows modifying each value
#[stable]
fn iter_mut(&mut self) -> IterMut<T>;
fn iter_mut(&mut self) -> IterMut<Self::Item>;
/// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
#[stable]
fn first_mut(&mut self) -> Option<&mut T>;
fn first_mut(&mut self) -> Option<&mut Self::Item>;
/// Depreated: renamed to `first_mut`.
#[deprecated = "renamed to first_mut"]
fn head_mut(&mut self) -> Option<&mut T> {
fn head_mut(&mut self) -> Option<&mut Self::Item> {
self.first_mut()
}
/// Returns all but the first element of a mutable slice
#[experimental = "likely to be renamed or removed"]
fn tail_mut(&mut self) -> &mut [T];
fn tail_mut(&mut self) -> &mut [Self::Item];
/// Returns all but the last element of a mutable slice
#[experimental = "likely to be renamed or removed"]
fn init_mut(&mut self) -> &mut [T];
fn init_mut(&mut self) -> &mut [Self::Item];
/// Returns a mutable pointer to the last item in the slice.
#[stable]
fn last_mut(&mut self) -> Option<&mut T>;
fn last_mut(&mut self) -> Option<&mut Self::Item>;
/// Returns an iterator over mutable subslices separated by elements that
/// match `pred`. The matched element is not contained in the subslices.
#[stable]
fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
where F: FnMut(&T) -> bool;
fn split_mut<F>(&mut self, pred: F) -> SplitMut<Self::Item, F>
where F: FnMut(&Self::Item) -> bool;
/// 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.
#[stable]
fn splitn_mut<F>(&mut self, n: uint, pred: F) -> SplitNMut<T, F>
where F: FnMut(&T) -> bool;
fn splitn_mut<F>(&mut self, n: uint, pred: F) -> SplitNMut<Self::Item, F>
where F: FnMut(&Self::Item) -> bool;
/// 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.
#[stable]
fn rsplitn_mut<F>(&mut self, n: uint, pred: F) -> RSplitNMut<T, F>
where F: FnMut(&T) -> bool;
fn rsplitn_mut<F>(&mut self, n: uint, pred: F) -> RSplitNMut<Self::Item, F>
where F: FnMut(&Self::Item) -> bool;
/// 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
@ -467,7 +469,7 @@ pub trait SliceExt<T> for Sized? {
///
/// Panics if `chunk_size` is 0.
#[stable]
fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<T>;
fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut<Self::Item>;
/// Swaps two elements in a slice.
///
@ -525,7 +527,7 @@ pub trait SliceExt<T> for Sized? {
/// }
/// ```
#[stable]
fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]);
fn split_at_mut(&mut self, mid: uint) -> (&mut [Self::Item], &mut [Self::Item]);
/// Reverse the order of elements in a slice, in place.
///
@ -541,11 +543,11 @@ pub trait SliceExt<T> for Sized? {
/// Returns an unsafe mutable pointer to the element in index
#[stable]
unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T;
unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut Self::Item;
/// Deprecated: renamed to `get_unchecked_mut`.
#[deprecated = "renamed to get_unchecked_mut"]
unsafe fn unchecked_mut(&mut self, index: uint) -> &mut T {
unsafe fn unchecked_mut(&mut self, index: uint) -> &mut Self::Item {
self.get_unchecked_mut(index)
}
@ -558,11 +560,179 @@ pub trait SliceExt<T> for Sized? {
/// would also make any pointers to it invalid.
#[inline]
#[stable]
fn as_mut_ptr(&mut self) -> *mut T;
fn as_mut_ptr(&mut self) -> *mut Self::Item;
/// Copies `self` into a new `Vec`.
#[stable]
fn to_vec(&self) -> Vec<Self::Item> where Self::Item: Clone;
/// Deprecated: use `iter().cloned().partition(f)` instead.
#[deprecated = "use iter().cloned().partition(f) instead"]
fn partitioned<F>(&self, f: F) -> (Vec<Self::Item>, Vec<Self::Item>) where
Self::Item: Clone,
F: FnMut(&Self::Item) -> bool;
/// Creates an iterator that yields every possible permutation of the
/// vector in succession.
///
/// # Examples
///
/// ```rust
/// let v = [1i, 2, 3];
/// let mut perms = v.permutations();
///
/// for p in perms {
/// println!("{}", p);
/// }
/// ```
///
/// Iterating through permutations one by one.
///
/// ```rust
/// let v = [1i, 2, 3];
/// let mut perms = v.permutations();
///
/// assert_eq!(Some(vec![1i, 2, 3]), perms.next());
/// assert_eq!(Some(vec![1i, 3, 2]), perms.next());
/// assert_eq!(Some(vec![3i, 1, 2]), perms.next());
/// ```
#[unstable]
fn permutations(&self) -> Permutations<Self::Item> where Self::Item: Clone;
/// 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.
///
/// # Example
///
/// ```rust
/// let mut dst = [0i, 0, 0];
/// let src = [1i, 2];
///
/// assert!(dst.clone_from_slice(&src) == 2);
/// assert!(dst == [1, 2, 0]);
///
/// let src2 = [3i, 4, 5, 6];
/// assert!(dst.clone_from_slice(&src2) == 3);
/// assert!(dst == [3i, 4, 5]);
/// ```
#[experimental]
fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone;
/// Sorts the slice, in place.
///
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
///
/// # Examples
///
/// ```rust
/// let mut v = [-5i, 4, 1, -3, 2];
///
/// v.sort();
/// assert!(v == [-5i, -3, 1, 2, 4]);
/// ```
#[stable]
fn sort(&mut self) where Self::Item: Ord;
/// Binary search a sorted slice for a given element.
///
/// If the value is found then `Ok` is returned, containing the
/// index of the matching element; if the value is not found then
/// `Err` is returned, containing the index where a matching
/// element could be inserted while maintaining sorted order.
///
/// # Example
///
/// Looks up a series of four elements. The first is found, with a
/// uniquely determined position; the second and third are not
/// found; the fourth could match any position in `[1,4]`.
///
/// ```rust
/// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
/// let s = s.as_slice();
///
/// assert_eq!(s.binary_search(&13), Ok(9));
/// assert_eq!(s.binary_search(&4), Err(7));
/// assert_eq!(s.binary_search(&100), Err(13));
/// let r = s.binary_search(&1);
/// assert!(match r { Ok(1...4) => true, _ => false, });
/// ```
#[stable]
fn binary_search(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord;
/// Deprecated: use `binary_search` instead.
#[deprecated = "use binary_search instead"]
fn binary_search_elem(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord {
self.binary_search(x)
}
/// Mutates the slice to the next lexicographic permutation.
///
/// Returns `true` if successful and `false` if the slice is at the
/// last-ordered permutation.
///
/// # Example
///
/// ```rust
/// let v: &mut [_] = &mut [0i, 1, 2];
/// v.next_permutation();
/// let b: &mut [_] = &mut [0i, 2, 1];
/// assert!(v == b);
/// v.next_permutation();
/// let b: &mut [_] = &mut [1i, 0, 2];
/// assert!(v == b);
/// ```
#[unstable = "uncertain if this merits inclusion in std"]
fn next_permutation(&mut self) -> bool where Self::Item: Ord;
/// Mutates the slice to the previous lexicographic permutation.
///
/// Returns `true` if successful and `false` if the slice is at the
/// first-ordered permutation.
///
/// # Example
///
/// ```rust
/// let v: &mut [_] = &mut [1i, 0, 2];
/// v.prev_permutation();
/// let b: &mut [_] = &mut [0i, 2, 1];
/// assert!(v == b);
/// v.prev_permutation();
/// let b: &mut [_] = &mut [0i, 1, 2];
/// assert!(v == b);
/// ```
#[unstable = "uncertain if this merits inclusion in std"]
fn prev_permutation(&mut self) -> bool where Self::Item: Ord;
/// Find the first index containing a matching value.
#[experimental]
fn position_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
/// Find the last index containing a matching value.
#[experimental]
fn rposition_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
/// Return true if the slice contains an element with the given value.
#[stable]
fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
/// Returns true if `needle` is a prefix of the slice.
#[stable]
fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
/// Returns true if `needle` is a suffix of the slice.
#[stable]
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
/// Convert `self` into a vector without clones or allocation.
#[experimental]
fn into_vec(self: Box<Self>) -> Vec<Self::Item>;
}
#[unstable = "trait is unstable"]
impl<T> SliceExt<T> for [T] {
impl<T> SliceExt for [T] {
type Item = T;
#[inline]
fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering {
merge_sort(self, compare)
@ -777,23 +947,71 @@ impl<T> SliceExt<T> for [T] {
fn as_mut_ptr(&mut self) -> *mut T {
core_slice::SliceExt::as_mut_ptr(self)
}
}
////////////////////////////////////////////////////////////////////////////////
// Extension traits for slices over specifc kinds of data
////////////////////////////////////////////////////////////////////////////////
/// Returns a copy of `v`.
#[inline]
fn to_vec(&self) -> Vec<T> where T: Clone {
let mut vector = Vec::with_capacity(self.len());
vector.push_all(self);
vector
}
/// Extension methods for boxed slices.
#[experimental = "likely to merge into SliceExt if it survives"]
pub trait BoxedSliceExt<T> {
/// Convert `self` into a vector without clones or allocation.
#[experimental]
fn into_vec(self) -> Vec<T>;
}
#[experimental = "trait is experimental"]
impl<T> BoxedSliceExt<T> for Box<[T]> {
fn into_vec(mut self) -> Vec<T> {
#[inline]
fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool, T: Clone {
self.iter().cloned().partition(f)
}
/// Returns an iterator over all permutations of a vector.
fn permutations(&self) -> Permutations<T> where T: Clone {
Permutations{
swaps: ElementSwaps::new(self.len()),
v: self.to_vec(),
}
}
fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone {
core_slice::SliceExt::clone_from_slice(self, src)
}
#[inline]
fn sort(&mut self) where T: Ord {
self.sort_by(|a, b| a.cmp(b))
}
fn binary_search(&self, x: &T) -> Result<uint, uint> where T: Ord {
core_slice::SliceExt::binary_search(self, x)
}
fn next_permutation(&mut self) -> bool where T: Ord {
core_slice::SliceExt::next_permutation(self)
}
fn prev_permutation(&mut self) -> bool where T: Ord {
core_slice::SliceExt::prev_permutation(self)
}
fn position_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
core_slice::SliceExt::position_elem(self, t)
}
fn rposition_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
core_slice::SliceExt::rposition_elem(self, t)
}
fn contains(&self, x: &T) -> bool where T: PartialEq {
core_slice::SliceExt::contains(self, x)
}
fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
core_slice::SliceExt::starts_with(self, needle)
}
fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
core_slice::SliceExt::ends_with(self, needle)
}
fn into_vec(mut self: Box<Self>) -> Vec<T> {
unsafe {
let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len());
mem::forget(self);
@ -802,204 +1020,9 @@ impl<T> BoxedSliceExt<T> for Box<[T]> {
}
}
/// Allocating extension methods for slices containing `Clone` elements.
#[unstable = "likely to be merged into SliceExt"]
pub trait CloneSliceExt<T> for Sized? {
/// Copies `self` into a new `Vec`.
#[stable]
fn to_vec(&self) -> Vec<T>;
/// Deprecated: use `iter().cloned().partition(f)` instead.
#[deprecated = "use iter().cloned().partition(f) instead"]
fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool;
/// Creates an iterator that yields every possible permutation of the
/// vector in succession.
///
/// # Examples
///
/// ```rust
/// let v = [1i, 2, 3];
/// let mut perms = v.permutations();
///
/// for p in perms {
/// println!("{}", p);
/// }
/// ```
///
/// Iterating through permutations one by one.
///
/// ```rust
/// let v = [1i, 2, 3];
/// let mut perms = v.permutations();
///
/// assert_eq!(Some(vec![1i, 2, 3]), perms.next());
/// assert_eq!(Some(vec![1i, 3, 2]), perms.next());
/// assert_eq!(Some(vec![3i, 1, 2]), perms.next());
/// ```
#[unstable]
fn permutations(&self) -> Permutations<T>;
/// 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.
///
/// # Example
///
/// ```rust
/// let mut dst = [0i, 0, 0];
/// let src = [1i, 2];
///
/// assert!(dst.clone_from_slice(&src) == 2);
/// assert!(dst == [1, 2, 0]);
///
/// let src2 = [3i, 4, 5, 6];
/// assert!(dst.clone_from_slice(&src2) == 3);
/// assert!(dst == [3i, 4, 5]);
/// ```
#[experimental]
fn clone_from_slice(&mut self, &[T]) -> uint;
}
#[unstable = "trait is unstable"]
impl<T: Clone> CloneSliceExt<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
}
#[inline]
fn partitioned<F>(&self, f: F) -> (Vec<T>, Vec<T>) where F: FnMut(&T) -> bool {
self.iter().cloned().partition(f)
}
/// Returns an iterator over all permutations of a vector.
fn permutations(&self) -> Permutations<T> {
Permutations{
swaps: ElementSwaps::new(self.len()),
v: self.to_vec(),
}
}
fn clone_from_slice(&mut self, src: &[T]) -> uint {
core_slice::CloneSliceExt::clone_from_slice(self, src)
}
}
/// Allocating extension methods for slices on Ord values.
#[unstable = "likely to merge with SliceExt"]
pub trait OrdSliceExt<T> for Sized? {
/// Sorts the slice, in place.
///
/// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
///
/// # Examples
///
/// ```rust
/// let mut v = [-5i, 4, 1, -3, 2];
///
/// v.sort();
/// assert!(v == [-5i, -3, 1, 2, 4]);
/// ```
#[stable]
fn sort(&mut self);
/// Binary search a sorted slice for a given element.
///
/// If the value is found then `Ok` is returned, containing the
/// index of the matching element; if the value is not found then
/// `Err` is returned, containing the index where a matching
/// element could be inserted while maintaining sorted order.
///
/// # Example
///
/// Looks up a series of four elements. The first is found, with a
/// uniquely determined position; the second and third are not
/// found; the fourth could match any position in `[1,4]`.
///
/// ```rust
/// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
/// let s = s.as_slice();
///
/// assert_eq!(s.binary_search(&13), Ok(9));
/// assert_eq!(s.binary_search(&4), Err(7));
/// assert_eq!(s.binary_search(&100), Err(13));
/// let r = s.binary_search(&1);
/// assert!(match r { Ok(1...4) => true, _ => false, });
/// ```
#[stable]
fn binary_search(&self, x: &T) -> Result<uint, uint>;
/// Deprecated: use `binary_search` instead.
#[deprecated = "use binary_search instead"]
fn binary_search_elem(&self, x: &T) -> Result<uint, uint> {
self.binary_search(x)
}
/// Mutates the slice to the next lexicographic permutation.
///
/// Returns `true` if successful and `false` if the slice is at the
/// last-ordered permutation.
///
/// # Example
///
/// ```rust
/// let v: &mut [_] = &mut [0i, 1, 2];
/// v.next_permutation();
/// let b: &mut [_] = &mut [0i, 2, 1];
/// assert!(v == b);
/// v.next_permutation();
/// let b: &mut [_] = &mut [1i, 0, 2];
/// assert!(v == b);
/// ```
#[unstable = "uncertain if this merits inclusion in std"]
fn next_permutation(&mut self) -> bool;
/// Mutates the slice to the previous lexicographic permutation.
///
/// Returns `true` if successful and `false` if the slice is at the
/// first-ordered permutation.
///
/// # Example
///
/// ```rust
/// let v: &mut [_] = &mut [1i, 0, 2];
/// v.prev_permutation();
/// let b: &mut [_] = &mut [0i, 2, 1];
/// assert!(v == b);
/// v.prev_permutation();
/// let b: &mut [_] = &mut [0i, 1, 2];
/// assert!(v == b);
/// ```
#[unstable = "uncertain if this merits inclusion in std"]
fn prev_permutation(&mut self) -> bool;
}
#[unstable = "trait is unstable"]
impl<T: Ord> OrdSliceExt<T> for [T] {
#[inline]
fn sort(&mut self) {
self.sort_by(|a, b| a.cmp(b))
}
fn binary_search(&self, x: &T) -> Result<uint, uint> {
core_slice::OrdSliceExt::binary_search(self, x)
}
fn next_permutation(&mut self) -> bool {
core_slice::OrdSliceExt::next_permutation(self)
}
fn prev_permutation(&mut self) -> bool {
core_slice::OrdSliceExt::prev_permutation(self)
}
}
////////////////////////////////////////////////////////////////////////////////
// Extension traits for slices over specifc kinds of data
////////////////////////////////////////////////////////////////////////////////
#[unstable = "U should be an associated type"]
/// An extension trait for concatenating slices
pub trait SliceConcatExt<Sized? T, U> for Sized? {
@ -1419,7 +1442,7 @@ mod tests {
use std::boxed::Box;
use prelude::{Some, None, range, Vec, ToString, Clone, Greater, Less, Equal};
use prelude::{SliceExt, Iterator, IteratorExt, DoubleEndedIteratorExt};
use prelude::{OrdSliceExt, CloneSliceExt, PartialEqSliceExt, AsSlice};
use prelude::AsSlice;
use prelude::{RandomAccessIterator, Ord, SliceConcatExt};
use core::cell::Cell;
use core::default::Default;

View File

@ -27,7 +27,6 @@ use core::raw::Slice as RawSlice;
use unicode::str as unicode_str;
use unicode::str::Utf16Item;
use slice::CloneSliceExt;
use str::{mod, CharRange, FromStr, Utf8Error};
use vec::{DerefVec, Vec, as_vec};
@ -94,7 +93,7 @@ impl String {
#[inline]
#[experimental = "needs investigation to see if to_string() can match perf"]
pub fn from_str(string: &str) -> String {
String { vec: string.as_bytes().to_vec() }
String { vec: ::slice::SliceExt::to_vec(string.as_bytes()) }
}
/// Returns the vector as a string buffer, if possible, taking care not to

View File

@ -63,8 +63,6 @@ use core::ptr;
use core::raw::Slice as RawSlice;
use core::uint;
use slice::CloneSliceExt;
/// A growable list type, written `Vec<T>` but pronounced 'vector.'
///
/// # Examples
@ -1218,7 +1216,7 @@ unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
#[unstable]
impl<T:Clone> Clone for Vec<T> {
fn clone(&self) -> Vec<T> { self.as_slice().to_vec() }
fn clone(&self) -> Vec<T> { ::slice::SliceExt::to_vec(self.as_slice()) }
fn clone_from(&mut self, other: &Vec<T>) {
// drop anything in self that will not be overwritten

View File

@ -64,5 +64,4 @@ pub use str::{Str, StrExt};
pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
pub use slice::{PartialEqSliceExt, OrdSliceExt};
pub use slice::{AsSlice, SliceExt};

View File

@ -243,7 +243,9 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
/// Methods on raw pointers
#[stable]
pub trait PtrExt<T> {
pub trait PtrExt {
type Target;
/// Returns the null pointer.
#[deprecated = "call ptr::null instead"]
fn null() -> Self;
@ -271,7 +273,7 @@ pub trait PtrExt<T> {
/// memory.
#[unstable = "Option is not clearly the right return type, and we may want \
to tie the return lifetime to a borrow of the raw pointer"]
unsafe fn as_ref<'a>(&self) -> Option<&'a T>;
unsafe fn as_ref<'a>(&self) -> Option<&'a Self::Target>;
/// Calculates the offset from a pointer. `count` is in units of T; e.g. a
/// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
@ -287,7 +289,9 @@ pub trait PtrExt<T> {
/// Methods on mutable raw pointers
#[stable]
pub trait MutPtrExt<T>{
pub trait MutPtrExt {
type Target;
/// Returns `None` if the pointer is null, or else returns a mutable
/// reference to the value wrapped in `Some`.
///
@ -297,11 +301,13 @@ pub trait MutPtrExt<T>{
/// of the returned pointer.
#[unstable = "Option is not clearly the right return type, and we may want \
to tie the return lifetime to a borrow of the raw pointer"]
unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
unsafe fn as_mut<'a>(&self) -> Option<&'a mut Self::Target>;
}
#[stable]
impl<T> PtrExt<T> for *const T {
impl<T> PtrExt for *const T {
type Target = T;
#[inline]
#[deprecated = "call ptr::null instead"]
fn null() -> *const T { null() }
@ -333,7 +339,9 @@ impl<T> PtrExt<T> for *const T {
}
#[stable]
impl<T> PtrExt<T> for *mut T {
impl<T> PtrExt for *mut T {
type Target = T;
#[inline]
#[deprecated = "call ptr::null instead"]
fn null() -> *mut T { null_mut() }
@ -365,7 +373,9 @@ impl<T> PtrExt<T> for *mut T {
}
#[stable]
impl<T> MutPtrExt<T> for *mut T {
impl<T> MutPtrExt for *mut T {
type Target = T;
#[inline]
#[unstable = "return value does not necessarily convey all possible \
information"]

View File

@ -64,57 +64,77 @@ use raw::Slice as RawSlice;
/// Extension methods for slices.
#[allow(missing_docs)] // docs in libcollections
pub trait SliceExt<T> for Sized? {
fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T];
fn slice_from<'a>(&'a self, start: uint) -> &'a [T];
fn slice_to<'a>(&'a self, end: uint) -> &'a [T];
fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]);
fn iter<'a>(&'a self) -> Iter<'a, T>;
fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P>
where P: FnMut(&T) -> bool;
fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P>
where P: FnMut(&T) -> bool;
fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, T, P>
where P: FnMut(&T) -> bool;
fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>;
fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>;
fn get<'a>(&'a self, index: uint) -> Option<&'a T>;
fn first<'a>(&'a self) -> Option<&'a T>;
fn tail<'a>(&'a self) -> &'a [T];
fn init<'a>(&'a self) -> &'a [T];
fn last<'a>(&'a self) -> Option<&'a T>;
unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T;
fn as_ptr(&self) -> *const T;
pub trait SliceExt for Sized? {
type Item;
fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [Self::Item];
fn slice_from<'a>(&'a self, start: uint) -> &'a [Self::Item];
fn slice_to<'a>(&'a self, end: uint) -> &'a [Self::Item];
fn split_at<'a>(&'a self, mid: uint) -> (&'a [Self::Item], &'a [Self::Item]);
fn iter<'a>(&'a self) -> Iter<'a, Self::Item>;
fn split<'a, P>(&'a self, pred: P) -> Split<'a, Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
fn windows<'a>(&'a self, size: uint) -> Windows<'a, Self::Item>;
fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, Self::Item>;
fn get<'a>(&'a self, index: uint) -> Option<&'a Self::Item>;
fn first<'a>(&'a self) -> Option<&'a Self::Item>;
fn tail<'a>(&'a self) -> &'a [Self::Item];
fn init<'a>(&'a self) -> &'a [Self::Item];
fn last<'a>(&'a self) -> Option<&'a Self::Item>;
unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a Self::Item;
fn as_ptr(&self) -> *const Self::Item;
fn binary_search_by<F>(&self, f: F) -> Result<uint, uint> where
F: FnMut(&T) -> Ordering;
F: FnMut(&Self::Item) -> Ordering;
fn len(&self) -> uint;
fn is_empty(&self) -> bool { self.len() == 0 }
fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>;
fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T];
fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T];
fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T];
fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T];
fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T>;
fn first_mut<'a>(&'a mut self) -> Option<&'a mut T>;
fn tail_mut<'a>(&'a mut self) -> &'a mut [T];
fn init_mut<'a>(&'a mut self) -> &'a mut [T];
fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>;
fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P>
where P: FnMut(&T) -> bool;
fn splitn_mut<P>(&mut self, n: uint, pred: P) -> SplitNMut<T, P>
where P: FnMut(&T) -> bool;
fn rsplitn_mut<P>(&mut self, n: uint, pred: P) -> RSplitNMut<T, P>
where P: FnMut(&T) -> bool;
fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, T>;
fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut Self::Item>;
fn as_mut_slice<'a>(&'a mut self) -> &'a mut [Self::Item];
fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [Self::Item];
fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [Self::Item];
fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [Self::Item];
fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>;
fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
fn init_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
fn last_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
fn splitn_mut<P>(&mut self, n: uint, pred: P) -> SplitNMut<Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
fn rsplitn_mut<P>(&mut self, n: uint, pred: P) -> RSplitNMut<Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, Self::Item>;
fn swap(&mut self, a: uint, b: uint);
fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]);
fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [Self::Item], &'a mut [Self::Item]);
fn reverse(&mut self);
unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T;
fn as_mut_ptr(&mut self) -> *mut T;
unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut Self::Item;
fn as_mut_ptr(&mut self) -> *mut Self::Item;
fn position_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
fn rposition_elem(&self, t: &Self::Item) -> Option<uint> where Self::Item: PartialEq;
fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
fn binary_search(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord;
fn next_permutation(&mut self) -> bool where Self::Item: Ord;
fn prev_permutation(&mut self) -> bool where Self::Item: Ord;
fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone;
}
#[unstable]
impl<T> SliceExt<T> for [T] {
impl<T> SliceExt for [T] {
type Item = T;
#[inline]
fn slice(&self, start: uint, end: uint) -> &[T] {
assert!(start <= end);
@ -404,6 +424,111 @@ impl<T> SliceExt<T> for [T] {
fn as_mut_ptr(&mut self) -> *mut T {
self.repr().data as *mut T
}
#[inline]
fn position_elem(&self, x: &T) -> Option<uint> where T: PartialEq {
self.iter().position(|y| *x == *y)
}
#[inline]
fn rposition_elem(&self, t: &T) -> Option<uint> where T: PartialEq {
self.iter().rposition(|x| *x == *t)
}
#[inline]
fn contains(&self, x: &T) -> bool where T: PartialEq {
self.iter().any(|elt| *x == *elt)
}
#[inline]
fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
let n = needle.len();
self.len() >= n && needle == self[..n]
}
#[inline]
fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
let (m, n) = (self.len(), needle.len());
m >= n && needle == self[m-n..]
}
#[unstable]
fn binary_search(&self, x: &T) -> Result<uint, uint> where T: Ord {
self.binary_search_by(|p| p.cmp(x))
}
#[experimental]
fn next_permutation(&mut self) -> bool where T: Ord {
// These cases only have 1 permutation each, so we can't do anything.
if self.len() < 2 { return false; }
// Step 1: Identify the longest, rightmost weakly decreasing part of the vector
let mut i = self.len() - 1;
while i > 0 && self[i-1] >= self[i] {
i -= 1;
}
// If that is the entire vector, this is the last-ordered permutation.
if i == 0 {
return false;
}
// Step 2: Find the rightmost element larger than the pivot (i-1)
let mut j = self.len() - 1;
while j >= i && self[j] <= self[i-1] {
j -= 1;
}
// Step 3: Swap that element with the pivot
self.swap(j, i-1);
// Step 4: Reverse the (previously) weakly decreasing part
self.slice_from_mut(i).reverse();
true
}
#[experimental]
fn prev_permutation(&mut self) -> bool where T: Ord {
// These cases only have 1 permutation each, so we can't do anything.
if self.len() < 2 { return false; }
// Step 1: Identify the longest, rightmost weakly increasing part of the vector
let mut i = self.len() - 1;
while i > 0 && self[i-1] <= self[i] {
i -= 1;
}
// If that is the entire vector, this is the first-ordered permutation.
if i == 0 {
return false;
}
// Step 2: Reverse the weakly increasing part
self.slice_from_mut(i).reverse();
// Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
let mut j = self.len() - 1;
while j >= i && self[j-1] < self[i-1] {
j -= 1;
}
// Step 4: Swap that element with the pivot
self.swap(i-1, j);
true
}
#[inline]
fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone {
let min = cmp::min(self.len(), src.len());
let dst = self.slice_to_mut(min);
let src = src.slice_to(min);
for i in range(0, min) {
dst[i].clone_from(&src[i]);
}
min
}
}
impl<T> ops::Index<uint, T> for [T] {
@ -479,160 +604,6 @@ impl<T> ops::SliceMut<uint, [T]> for [T] {
}
}
/// Extension methods for slices containing `PartialEq` elements.
#[unstable = "may merge with SliceExt"]
pub trait PartialEqSliceExt<T: PartialEq> for Sized? {
/// Find the first index containing a matching value.
#[experimental]
fn position_elem(&self, t: &T) -> Option<uint>;
/// Find the last index containing a matching value.
#[experimental]
fn rposition_elem(&self, t: &T) -> Option<uint>;
/// Return true if the slice contains an element with the given value.
#[stable]
fn contains(&self, x: &T) -> bool;
/// Returns true if `needle` is a prefix of the slice.
#[stable]
fn starts_with(&self, needle: &[T]) -> bool;
/// Returns true if `needle` is a suffix of the slice.
#[stable]
fn ends_with(&self, needle: &[T]) -> bool;
}
#[unstable = "trait is unstable"]
impl<T: PartialEq> PartialEqSliceExt<T> for [T] {
#[inline]
fn position_elem(&self, x: &T) -> Option<uint> {
self.iter().position(|y| *x == *y)
}
#[inline]
fn rposition_elem(&self, t: &T) -> Option<uint> {
self.iter().rposition(|x| *x == *t)
}
#[inline]
fn contains(&self, x: &T) -> bool {
self.iter().any(|elt| *x == *elt)
}
#[inline]
fn starts_with(&self, needle: &[T]) -> bool {
let n = needle.len();
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..]
}
}
/// Extension methods for slices containing `Ord` elements.
#[unstable = "may merge with other traits"]
#[allow(missing_docs)] // docs in libcollections
pub trait OrdSliceExt<T: Ord> for Sized? {
fn binary_search(&self, x: &T) -> Result<uint, uint>;
fn next_permutation(&mut self) -> bool;
fn prev_permutation(&mut self) -> bool;
}
#[unstable = "trait is unstable"]
impl<T: Ord> OrdSliceExt<T> for [T] {
#[unstable]
fn binary_search(&self, x: &T) -> Result<uint, uint> {
self.binary_search_by(|p| p.cmp(x))
}
#[experimental]
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; }
// Step 1: Identify the longest, rightmost weakly decreasing part of the vector
let mut i = self.len() - 1;
while i > 0 && self[i-1] >= self[i] {
i -= 1;
}
// If that is the entire vector, this is the last-ordered permutation.
if i == 0 {
return false;
}
// Step 2: Find the rightmost element larger than the pivot (i-1)
let mut j = self.len() - 1;
while j >= i && self[j] <= self[i-1] {
j -= 1;
}
// Step 3: Swap that element with the pivot
self.swap(j, i-1);
// Step 4: Reverse the (previously) weakly decreasing part
self.slice_from_mut(i).reverse();
true
}
#[experimental]
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; }
// Step 1: Identify the longest, rightmost weakly increasing part of the vector
let mut i = self.len() - 1;
while i > 0 && self[i-1] <= self[i] {
i -= 1;
}
// If that is the entire vector, this is the first-ordered permutation.
if i == 0 {
return false;
}
// Step 2: Reverse the weakly increasing part
self.slice_from_mut(i).reverse();
// Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
let mut j = self.len() - 1;
while j >= i && self[j-1] < self[i-1] {
j -= 1;
}
// Step 4: Swap that element with the pivot
self.swap(i-1, j);
true
}
}
/// Extension methods for slices on Clone elements
#[unstable = "may merge with other traits"]
#[allow(missing_docs)] // docs in libcollections
pub trait CloneSliceExt<T> for Sized? {
fn clone_from_slice(&mut self, &[T]) -> uint;
}
#[unstable = "trait is unstable"]
impl<T: Clone> CloneSliceExt<T> for [T] {
#[inline]
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);
for i in range(0, min) {
dst[i].clone_from(&src[i]);
}
min
}
}
////////////////////////////////////////////////////////////////////////////////
// Common traits
////////////////////////////////////////////////////////////////////////////////

View File

@ -539,7 +539,7 @@ pub unsafe fn from_c_multistring<F>(buf: *const libc::c_char,
#[cfg(test)]
mod tests {
use super::*;
use prelude::{spawn, Some, None, Option, FnOnce, ToString, CloneSliceExt};
use prelude::{spawn, Some, None, Option, FnOnce, ToString};
use prelude::{Clone, PtrExt, Iterator, SliceExt, StrExt};
use ptr;
use thread::Thread;

View File

@ -14,7 +14,7 @@ use comm::{Sender, Receiver};
use io;
use option::Option::{None, Some};
use result::Result::{Ok, Err};
use slice::{bytes, CloneSliceExt, SliceExt};
use slice::{bytes, SliceExt};
use super::{Buffer, Reader, Writer, IoResult};
use vec::Vec;

View File

@ -401,7 +401,7 @@ mod test {
extern crate "test" as test_crate;
use super::*;
use io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek};
use prelude::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt, IteratorExt, CloneSliceExt};
use prelude::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt, IteratorExt};
use io;
use self::test_crate::Bencher;

View File

@ -1919,7 +1919,7 @@ impl fmt::Show for FilePermission {
mod tests {
use self::BadReaderBehavior::*;
use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput, Writer};
use prelude::{Ok, Vec, Buffer, CloneSliceExt};
use prelude::{Ok, Vec, Buffer, SliceExt};
use uint;
#[deriving(Clone, PartialEq, Show)]

View File

@ -25,7 +25,7 @@ use ops::FnOnce;
use option::Option;
use option::Option::{None, Some};
use result::Result::{Ok, Err};
use slice::{CloneSliceExt, SliceExt};
use slice::SliceExt;
use str::{FromStr, StrExt};
use vec::Vec;

View File

@ -107,6 +107,7 @@
#![feature(macro_rules, globs, linkage, thread_local, asm)]
#![feature(default_type_params, phase, lang_items, unsafe_destructor)]
#![feature(slicing_syntax, unboxed_closures)]
#![feature(associated_types)]
// Don't link to std. We are std.
#![no_std]

View File

@ -317,9 +317,8 @@ macro_rules! try {
#[macro_export]
macro_rules! vec {
($($x:expr),*) => ({
use std::slice::BoxedSliceExt;
let xs: ::std::boxed::Box<[_]> = box [$($x),*];
xs.into_vec()
::std::slice::SliceExt::into_vec(xs)
});
($($x:expr,)*) => (vec![$($x),*])
}

View File

@ -20,7 +20,7 @@ use char::{mod, Char};
use num::{mod, Int, Float, ToPrimitive};
use num::FpCategory as Fp;
use ops::FnMut;
use slice::{SliceExt, CloneSliceExt};
use slice::SliceExt;
use str::StrExt;
use string::String;
use vec::Vec;

View File

@ -52,7 +52,6 @@ use ptr;
use result::Result;
use result::Result::{Err, Ok};
use slice::{AsSlice, SliceExt};
use slice::CloneSliceExt;
use str::{Str, StrExt};
use string::{String, ToString};
use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};

View File

@ -71,8 +71,7 @@ use option::Option::{None, Some};
use str;
use str::{CowString, MaybeOwned, Str, StrExt};
use string::String;
use slice::{AsSlice, CloneSliceExt};
use slice::{PartialEqSliceExt, SliceExt};
use slice::{AsSlice, SliceExt};
use vec::Vec;
/// Typedef for POSIX file paths.

View File

@ -22,8 +22,7 @@ use option::Option::{None, Some};
use kinds::Sized;
use str::{FromStr, Str};
use str;
use slice::{CloneSliceExt, Split, AsSlice, SliceConcatExt,
PartialEqSliceExt, SliceExt};
use slice::{Split, AsSlice, SliceConcatExt, SliceExt};
use vec::Vec;
use super::{BytesContainer, GenericPath, GenericPathUnsafe};
@ -449,7 +448,7 @@ static dot_dot_static: &'static [u8] = b"..";
mod tests {
use super::*;
use prelude::Option::{mod, Some, None};
use prelude::{Vec, Clone, AsSlice, SliceExt, CloneSliceExt, IteratorExt};
use prelude::{Vec, Clone, AsSlice, SliceExt, IteratorExt};
use prelude::{DoubleEndedIteratorExt, Str, StrExt, ToString, GenericPath};
use str;

View File

@ -1121,7 +1121,7 @@ fn prefix_len(p: Option<PathPrefix>) -> uint {
mod tests {
use super::*;
use prelude::Option::{mod, Some, None};
use prelude::{Vec, Clone, AsSlice, SliceExt, CloneSliceExt, IteratorExt};
use prelude::{Vec, Clone, AsSlice, SliceExt, IteratorExt};
use prelude::{DoubleEndedIteratorExt, Str, ToString, GenericPath};
use super::PathPrefix::*;
use super::parse_prefix;

View File

@ -82,9 +82,7 @@
#[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12};
#[doc(no_inline)] pub use str::{Str, StrExt};
#[doc(no_inline)] pub use slice::AsSlice;
#[doc(no_inline)] pub use slice::{SliceConcatExt, PartialEqSliceExt};
#[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt};
#[doc(no_inline)] pub use slice::{BoxedSliceExt};
#[doc(no_inline)] pub use slice::{SliceConcatExt, SliceExt};
#[doc(no_inline)] pub use string::{IntoString, String, ToString};
#[doc(no_inline)] pub use vec::Vec;