diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index c55a8ba104e..ec522ae9e5a 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -96,21 +96,902 @@ 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}; +use core::prelude::{Ord, Ordering, RawPtr, Some, range, IteratorCloneExt, Result}; use core::ptr; use core::slice as core_slice; use self::Direction::*; use vec::Vec; -pub use core::slice::{Chunks, AsSlice, SplitsN, Windows}; +pub use core::slice::{Chunks, AsSlice, SplitN, Windows}; pub use core::slice::{Iter, IterMut, PartialEqSliceExt}; -pub use core::slice::{ImmutableIntSlice, MutableIntSlice}; -pub use core::slice::{MutSplits, MutChunks, Splits}; +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}; -pub use core::slice::{from_raw_buf, from_raw_mut_buf, BinarySearchResult}; +pub use core::slice::{from_raw_buf, from_raw_mut_buf}; -// Functional utilities +//////////////////////////////////////////////////////////////////////////////// +// Basic slice extension methods +//////////////////////////////////////////////////////////////////////////////// + +/// Allocating extension methods for slices. +#[unstable = "needs associated types, may merge with other traits"] +pub trait SliceExt for Sized? { + /// Sorts the slice, in place, using `compare` to compare + /// elements. + /// + /// This sort is `O(n log n)` worst-case and stable, but allocates + /// approximately `2 * n`, where `n` is the length of `self`. + /// + /// # Examples + /// + /// ```rust + /// let mut v = [5i, 4, 1, 3, 2]; + /// v.sort_by(|a, b| a.cmp(b)); + /// assert!(v == [1, 2, 3, 4, 5]); + /// + /// // reverse sorting + /// v.sort_by(|a, b| b.cmp(a)); + /// assert!(v == [5, 4, 3, 2, 1]); + /// ``` + #[stable] + fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering; + + /// Consumes `src` and moves as many elements as it can into `self` + /// from the range [start,end). + /// + /// Returns the number of elements copied (the shorter of `self.len()` + /// and `end - start`). + /// + /// # Arguments + /// + /// * src - A mutable vector of `T` + /// * start - The index into `src` to start copying from + /// * end - The index into `src` to stop copying from + /// + /// # Examples + /// + /// ```rust + /// let mut a = [1i, 2, 3, 4, 5]; + /// let b = vec![6i, 7, 8]; + /// let num_moved = a.move_from(b, 0, 3); + /// assert_eq!(num_moved, 3); + /// assert!(a == [6i, 7, 8, 4, 5]); + /// ``` + #[experimental = "uncertain about this API approach"] + fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; + + /// Returns a subslice spanning the interval [`start`, `end`). + /// + /// Panics when the end of the new slice lies beyond the end of the + /// original slice (i.e. when `end > self.len()`) or when `start > end`. + /// + /// 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]; + + /// Returns a subslice from `start` to the end of the slice. + /// + /// Panics when `start` is strictly greater than the length of the original slice. + /// + /// Slicing from `self.len()` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice_from(&self, start: uint) -> &[T]; + + /// Returns a subslice from the start of the slice to `end`. + /// + /// Panics when `end` is strictly greater than the length of the original slice. + /// + /// Slicing to `0` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice_to(&self, end: uint) -> &[T]; + + /// Divides one slice into two at an index. + /// + /// The first will contain all indices from `[0, mid)` (excluding + /// the index `mid` itself) and the second will contain all + /// indices from `[mid, len)` (excluding the index `len` itself). + /// + /// Panics if `mid > len`. + #[stable] + fn split_at(&self, mid: uint) -> (&[T], &[T]); + + /// Returns an iterator over the slice + #[stable] + fn iter(&self) -> Iter; + + /// Returns an iterator over subslices separated by elements that match + /// `pred`. The matched element is not contained in the subslices. + #[stable] + fn split(&self, pred: F) -> Split + where F: FnMut(&T) -> 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(&self, n: uint, pred: F) -> SplitN + where F: FnMut(&T) -> 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(&self, n: uint, pred: F) -> RSplitN + where F: FnMut(&T) -> bool; + + /// Returns an iterator over all contiguous windows of length + /// `size`. The windows overlap. If the slice is shorter than + /// `size`, the iterator returns no values. + /// + /// # Panics + /// + /// Panics if `size` is 0. + /// + /// # Example + /// + /// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`, + /// `[3,4]`): + /// + /// ```rust + /// let v = &[1i, 2, 3, 4]; + /// for win in v.windows(2) { + /// println!("{}", win); + /// } + /// ``` + #[stable] + fn windows(&self, size: uint) -> Windows; + + /// Returns an iterator over `size` elements of the slice at a + /// time. The chunks do not overlap. If `size` does not divide the + /// length of the slice, then the last chunk will not have length + /// `size`. + /// + /// # Panics + /// + /// Panics if `size` is 0. + /// + /// # Example + /// + /// Print the slice two elements at a time (i.e. `[1,2]`, + /// `[3,4]`, `[5]`): + /// + /// ```rust + /// let v = &[1i, 2, 3, 4, 5]; + /// for win in v.chunks(2) { + /// println!("{}", win); + /// } + /// ``` + #[stable] + fn chunks(&self, size: uint) -> Chunks; + + /// 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>; + + /// Returns the first element of a slice, or `None` if it is empty. + #[stable] + fn first(&self) -> Option<&T>; + + /// Deprecated: renamed to `first`. + #[deprecated = "renamed to `first`"] + fn head(&self) -> Option<&T> { self.first() } + + /// Returns all but the first element of a slice. + #[experimental = "likely to be renamed"] + fn tail(&self) -> &[T]; + + /// Returns all but the last element of a slice. + #[experimental = "likely to be renamed"] + fn init(&self) -> &[T]; + + /// Returns the last element of a slice, or `None` if it is empty. + #[stable] + fn last(&self) -> Option<&T>; + + /// Returns a pointer to the element at the given index, without doing + /// bounds checking. + #[stable] + unsafe fn get_unchecked(&self, index: uint) -> &T; + + /// Deprecated: renamed to `get_unchecked`. + #[deprecated = "renamed to get_unchecked"] + unsafe fn unsafe_get(&self, index: uint) -> &T { + self.get_unchecked(index) + } + + /// Returns an unsafe pointer to the slice's buffer + /// + /// The caller must ensure that the slice outlives the pointer this + /// function returns, or else it will end up pointing to garbage. + /// + /// 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; + + /// Binary search a sorted slice with a comparator function. + /// + /// The comparator function should implement an order consistent + /// with the sort order of the underlying slice, returning an + /// order code that indicates whether its argument is `Less`, + /// `Equal` or `Greater` the desired target. + /// + /// If a matching value is found then returns `Ok`, containing + /// the index for the matched element; if no match is 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(); + /// + /// let seek = 13; + /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9)); + /// let seek = 4; + /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7)); + /// let seek = 100; + /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13)); + /// let seek = 1; + /// let r = s.binary_search_by(|probe| probe.cmp(&seek)); + /// assert!(match r { Ok(1...4) => true, _ => false, }); + /// ``` + #[stable] + fn binary_search_by(&self, f: F) -> Result where + F: FnMut(&T) -> Ordering; + + /// Return the number of elements in the slice + /// + /// # Example + /// + /// ``` + /// let a = [1i, 2, 3]; + /// assert_eq!(a.len(), 3); + /// ``` + #[stable] + fn len(&self) -> uint; + + /// Returns true if the slice has a length of 0 + /// + /// # Example + /// + /// ``` + /// let a = [1i, 2, 3]; + /// assert!(!a.is_empty()); + /// ``` + #[inline] + #[stable] + fn is_empty(&self) -> bool { self.len() == 0 } + /// 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>; + + /// 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]; + + /// Returns a mutable subslice spanning the interval [`start`, `end`). + /// + /// Panics when the end of the new slice lies beyond the end of the + /// original slice (i.e. when `end > self.len()`) or when `start > end`. + /// + /// 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]; + + /// Returns a mutable subslice from `start` to the end of the slice. + /// + /// Panics when `start` is strictly greater than the length of the original slice. + /// + /// 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]; + + /// Returns a mutable subslice from the start of the slice to `end`. + /// + /// Panics when `end` is strictly greater than the length of the original slice. + /// + /// Slicing to `0` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice_to_mut(&mut self, end: uint) -> &mut [T]; + + /// Returns an iterator that allows modifying each value + #[stable] + fn iter_mut(&mut self) -> IterMut; + + /// 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>; + + /// Depreated: renamed to `first_mut`. + #[deprecated = "renamed to first_mut"] + fn head_mut(&mut self) -> Option<&mut T> { + 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]; + + /// Returns all but the last element of a mutable slice + #[experimental = "likely to be renamed or removed"] + fn init_mut(&mut self) -> &mut [T]; + + /// Returns a mutable pointer to the last item in the slice. + #[stable] + fn last_mut(&mut self) -> Option<&mut T>; + + /// 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(&mut self, pred: F) -> SplitMut + where F: FnMut(&T) -> 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(&mut self, n: uint, pred: F) -> SplitNMut + where F: FnMut(&T) -> 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(&mut self, n: uint, pred: F) -> RSplitNMut + where F: FnMut(&T) -> 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 + /// not divide the length of the slice, then the last chunk will not + /// have length `chunk_size`. + /// + /// # Panics + /// + /// Panics if `chunk_size` is 0. + #[stable] + fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut; + + /// Swaps two elements in a slice. + /// + /// # Arguments + /// + /// * a - The index of the first element + /// * b - The index of the second element + /// + /// # Panics + /// + /// Panics if `a` or `b` are out of bounds. + /// + /// # Example + /// + /// ```rust + /// let mut v = ["a", "b", "c", "d"]; + /// v.swap(1, 3); + /// assert!(v == ["a", "d", "c", "b"]); + /// ``` + #[stable] + fn swap(&mut self, a: uint, b: uint); + + /// Divides one `&mut` into two at an index. + /// + /// The first will contain all indices from `[0, mid)` (excluding + /// the index `mid` itself) and the second will contain all + /// indices from `[mid, len)` (excluding the index `len` itself). + /// + /// # Panics + /// + /// Panics if `mid > len`. + /// + /// # Example + /// + /// ```rust + /// let mut v = [1i, 2, 3, 4, 5, 6]; + /// + /// // scoped to restrict the lifetime of the borrows + /// { + /// let (left, right) = v.split_at_mut(0); + /// assert!(left == []); + /// assert!(right == [1i, 2, 3, 4, 5, 6]); + /// } + /// + /// { + /// let (left, right) = v.split_at_mut(2); + /// assert!(left == [1i, 2]); + /// assert!(right == [3i, 4, 5, 6]); + /// } + /// + /// { + /// let (left, right) = v.split_at_mut(6); + /// assert!(left == [1i, 2, 3, 4, 5, 6]); + /// assert!(right == []); + /// } + /// ``` + #[stable] + fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]); + + /// Reverse the order of elements in a slice, in place. + /// + /// # Example + /// + /// ```rust + /// let mut v = [1i, 2, 3]; + /// v.reverse(); + /// assert!(v == [3i, 2, 1]); + /// ``` + #[stable] + fn reverse(&mut self); + + /// Returns an unsafe mutable pointer to the element in index + #[stable] + unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T; + + /// Deprecated: renamed to `get_unchecked_mut`. + #[deprecated = "renamed to get_unchecked_mut"] + unsafe fn unchecked_mut(&mut self, index: uint) -> &mut T { + self.get_unchecked_mut(index) + } + + /// Return an unsafe mutable pointer to the slice's buffer. + /// + /// The caller must ensure that the slice outlives the pointer this + /// function returns, or else it will end up pointing to garbage. + /// + /// Modifying the slice may cause its buffer to be reallocated, which + /// would also make any pointers to it invalid. + #[inline] + #[stable] + fn as_mut_ptr(&mut self) -> *mut T; +} + +#[unstable = "trait is unstable"] +impl SliceExt for [T] { + #[inline] + fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { + merge_sort(self, compare) + } + + #[inline] + fn move_from(&mut self, mut src: Vec, start: uint, end: uint) -> uint { + for (a, b) in self.iter_mut().zip(src.slice_mut(start, end).iter_mut()) { + mem::swap(a, b); + } + cmp::min(self.len(), end-start) + } + + #[inline] + fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] { + core_slice::SliceExt::slice(self, start, end) + } + + #[inline] + fn slice_from<'a>(&'a self, start: uint) -> &'a [T] { + core_slice::SliceExt::slice_from(self, start) + } + + #[inline] + fn slice_to<'a>(&'a self, end: uint) -> &'a [T] { + core_slice::SliceExt::slice_to(self, end) + } + + #[inline] + fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]) { + core_slice::SliceExt::split_at(self, mid) + } + + #[inline] + fn iter<'a>(&'a self) -> Iter<'a, T> { + core_slice::SliceExt::iter(self) + } + + #[inline] + fn split(&self, pred: F) -> Split + where F: FnMut(&T) -> bool { + core_slice::SliceExt::split(self, pred) + } + + #[inline] + fn splitn(&self, n: uint, pred: F) -> SplitN + where F: FnMut(&T) -> bool { + core_slice::SliceExt::splitn(self, n, pred) + } + + #[inline] + fn rsplitn(&self, n: uint, pred: F) -> RSplitN + where F: FnMut(&T) -> bool { + core_slice::SliceExt::rsplitn(self, n, pred) + } + + #[inline] + fn windows<'a>(&'a self, size: uint) -> Windows<'a, T> { + core_slice::SliceExt::windows(self, size) + } + + #[inline] + fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T> { + core_slice::SliceExt::chunks(self, size) + } + + #[inline] + fn get<'a>(&'a self, index: uint) -> Option<&'a T> { + core_slice::SliceExt::get(self, index) + } + + #[inline] + fn first<'a>(&'a self) -> Option<&'a T> { + core_slice::SliceExt::first(self) + } + + #[inline] + fn tail<'a>(&'a self) -> &'a [T] { + core_slice::SliceExt::tail(self) + } + + #[inline] + fn init<'a>(&'a self) -> &'a [T] { + core_slice::SliceExt::init(self) + } + + #[inline] + fn last<'a>(&'a self) -> Option<&'a T> { + core_slice::SliceExt::last(self) + } + + #[inline] + unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T { + core_slice::SliceExt::get_unchecked(self, index) + } + + #[inline] + fn as_ptr(&self) -> *const T { + core_slice::SliceExt::as_ptr(self) + } + + #[inline] + fn binary_search_by(&self, f: F) -> Result + where F: FnMut(&T) -> Ordering { + core_slice::SliceExt::binary_search_by(self, f) + } + + #[inline] + fn len(&self) -> uint { + core_slice::SliceExt::len(self) + } + + #[inline] + fn is_empty(&self) -> bool { + core_slice::SliceExt::is_empty(self) + } + + #[inline] + fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T> { + core_slice::SliceExt::get_mut(self, index) + } + + #[inline] + fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { + core_slice::SliceExt::as_mut_slice(self) + } + + #[inline] + fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T] { + core_slice::SliceExt::slice_mut(self, start, end) + } + + #[inline] + fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T] { + core_slice::SliceExt::slice_from_mut(self, start) + } + + #[inline] + fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T] { + core_slice::SliceExt::slice_to_mut(self, end) + } + + #[inline] + fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { + core_slice::SliceExt::iter_mut(self) + } + + #[inline] + fn first_mut<'a>(&'a mut self) -> Option<&'a mut T> { + core_slice::SliceExt::first_mut(self) + } + + #[inline] + fn tail_mut<'a>(&'a mut self) -> &'a mut [T] { + core_slice::SliceExt::tail_mut(self) + } + + #[inline] + fn init_mut<'a>(&'a mut self) -> &'a mut [T] { + core_slice::SliceExt::init_mut(self) + } + + #[inline] + fn last_mut<'a>(&'a mut self) -> Option<&'a mut T> { + core_slice::SliceExt::last_mut(self) + } + + #[inline] + fn split_mut(&mut self, pred: F) -> SplitMut + where F: FnMut(&T) -> bool { + core_slice::SliceExt::split_mut(self, pred) + } + + #[inline] + fn splitn_mut(&mut self, n: uint, pred: F) -> SplitNMut + where F: FnMut(&T) -> bool { + core_slice::SliceExt::splitn_mut(self, n, pred) + } + + #[inline] + fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut + where F: FnMut(&T) -> bool { + core_slice::SliceExt::rsplitn_mut(self, n, pred) + } + + #[inline] + fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, T> { + core_slice::SliceExt::chunks_mut(self, chunk_size) + } + + #[inline] + fn swap(&mut self, a: uint, b: uint) { + core_slice::SliceExt::swap(self, a, b) + } + + #[inline] + fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) { + core_slice::SliceExt::split_at_mut(self, mid) + } + + #[inline] + fn reverse(&mut self) { + core_slice::SliceExt::reverse(self) + } + + #[inline] + unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T { + core_slice::SliceExt::get_unchecked_mut(self, index) + } + + #[inline] + fn as_mut_ptr(&mut self) -> *mut T { + core_slice::SliceExt::as_mut_ptr(self) + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Extension traits for slices over specifc kinds of data +//////////////////////////////////////////////////////////////////////////////// + +/// Extension methods for boxed slices. +#[experimental = "likely to merge into SliceExt if it survives"] +pub trait BoxedSliceExt { + /// Convert `self` into a vector without clones or allocation. + #[experimental] + fn into_vec(self) -> Vec; +} + +#[experimental = "trait is experimental"] +impl BoxedSliceExt for Box<[T]> { + fn into_vec(mut self) -> Vec { + unsafe { + let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len()); + mem::forget(self); + xs + } + } +} + +/// Allocating extension methods for slices containing `Clone` elements. +#[unstable = "likely to be merged into SliceExt"] +pub trait CloneSliceExt for Sized? { + /// Copies `self` into a new `Vec`. + #[stable] + fn to_vec(&self) -> Vec; + + /// Deprecated: use `iter().cloned().partition(f)` instead. + #[deprecated = "use iter().cloned().partition(f) instead"] + fn partitioned(&self, f: F) -> (Vec, Vec) 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()); + /// ``` + #[stable] + fn permutations(&self) -> Permutations; + + /// 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 CloneSliceExt for [T] { + /// Returns a copy of `v`. + #[inline] + fn to_vec(&self) -> Vec { + let mut vector = Vec::with_capacity(self.len()); + vector.push_all(self); + vector + } + + + #[inline] + fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { + self.iter().cloned().partition(f) + } + + /// Returns an iterator over all permutations of a vector. + fn permutations(&self) -> Permutations { + 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 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; + + /// Deprecated: use `binary_search` instead. + #[deprecated = "use binary_search instead"] + fn binary_search_elem(&self, x: &T) -> Result { + 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); + /// ``` + #[stable] + 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); + /// ``` + #[stable] + fn prev_permutation(&mut self) -> bool; +} + +#[unstable = "trait is unstable"] +impl OrdSliceExt for [T] { + #[inline] + fn sort(&mut self) { + self.sort_by(|a, b| a.cmp(b)) + } + + fn binary_search(&self, x: &T) -> Result { + 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) + } +} #[allow(missing_docs)] pub trait VectorVector for Sized? { @@ -155,6 +1036,7 @@ impl<'a, T: Clone, V: AsSlice> VectorVector for [V] { /// /// The last generated swap is always (0, 1), and it returns the /// sequence to its initial order. +#[experimental] pub struct ElementSwaps { sdir: Vec, /// If `true`, emit the last swap that returns the sequence to initial @@ -165,6 +1047,7 @@ pub struct ElementSwaps { impl ElementSwaps { /// Creates an `ElementSwaps` iterator for a sequence of `length` elements. + #[experimental] pub fn new(length: uint) -> ElementSwaps { // Initialize `sdir` with a direction that position should move in // (all negative at the beginning) and the `size` of the @@ -177,6 +1060,29 @@ impl ElementSwaps { } } +//////////////////////////////////////////////////////////////////////////////// +// Standard trait implementations for slices +//////////////////////////////////////////////////////////////////////////////// + +#[unstable = "trait is unstable"] +impl BorrowFrom> for [T] { + fn borrow_from(owned: &Vec) -> &[T] { owned[] } +} + +#[unstable = "trait is unstable"] +impl BorrowFromMut> for [T] { + fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { owned.as_mut_slice_() } +} + +#[unstable = "trait is unstable"] +impl ToOwned> for [T] { + fn to_owned(&self) -> Vec { self.to_vec() } +} + +//////////////////////////////////////////////////////////////////////////////// +// Iterators +//////////////////////////////////////////////////////////////////////////////// + #[deriving(Copy)] enum Direction { Pos, Neg } @@ -247,11 +1153,13 @@ impl Iterator<(uint, uint)> for ElementSwaps { /// swap applied. /// /// Generates even and odd permutations alternately. +#[stable] pub struct Permutations { swaps: ElementSwaps, v: Vec, } +#[unstable = "trait is unstable"] impl Iterator> for Permutations { #[inline] fn next(&mut self) -> Option> { @@ -272,116 +1180,9 @@ impl Iterator> for Permutations { } } -/// Extension methods for boxed slices. -pub trait BoxedSliceExt { - /// Convert `self` into a vector without clones or allocation. - fn into_vec(self) -> Vec; -} - -impl BoxedSliceExt for Box<[T]> { - #[experimental] - fn into_vec(mut self) -> Vec { - unsafe { - let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len()); - mem::forget(self); - xs - } - } -} - -/// Allocating extension methods for slices containing `Clone` elements. -pub trait CloneSliceExt for Sized? { - /// Copies `self` into a new `Vec`. - fn to_vec(&self) -> Vec; - - /// 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: F) -> (Vec, Vec) 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()); - /// ``` - fn permutations(&self) -> Permutations; - - /// 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]); - /// ``` - fn clone_from_slice(&mut self, &[T]) -> uint; -} - -impl CloneSliceExt for [T] { - /// Returns a copy of `v`. - #[inline] - fn to_vec(&self) -> Vec { - let mut vector = Vec::with_capacity(self.len()); - vector.push_all(self); - vector - } - - - #[inline] - fn partitioned(&self, mut f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { - let mut lefts = Vec::new(); - let mut rights = Vec::new(); - - for elt in self.iter() { - if f(elt) { - lefts.push((*elt).clone()); - } else { - rights.push((*elt).clone()); - } - } - - (lefts, rights) - } - - /// Returns an iterator over all permutations of a vector. - fn permutations(&self) -> Permutations { - 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) - } -} +//////////////////////////////////////////////////////////////////////////////// +// Sorting +//////////////////////////////////////////////////////////////////////////////// fn insertion_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering { let len = v.len() as int; @@ -586,755 +1387,8 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order } } -/// Allocating extension methods for slices on Ord values. -#[experimental = "likely to merge with other traits"] -pub trait OrdSliceExt 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]); - /// ``` - #[experimental] - fn sort(&mut self); - - /// Binary search a sorted slice for a given element. - /// - /// If the value is found then `Found` is returned, containing the - /// index of the matching element; if the value is not found then - /// `NotFound` 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 - /// use std::slice::BinarySearchResult::{Found, NotFound}; - /// 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_elem(&13), Found(9)); - /// assert_eq!(s.binary_search_elem(&4), NotFound(7)); - /// assert_eq!(s.binary_search_elem(&100), NotFound(13)); - /// let r = s.binary_search_elem(&1); - /// assert!(match r { Found(1...4) => true, _ => false, }); - /// ``` - #[unstable = "name likely to change"] - fn binary_search_elem(&self, x: &T) -> BinarySearchResult; - - /// 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); - /// ``` - #[experimental] - 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); - /// ``` - #[experimental] - fn prev_permutation(&mut self) -> bool; -} - -impl OrdSliceExt for [T] { - #[inline] - fn sort(&mut self) { - self.sort_by(|a, b| a.cmp(b)) - } - - fn binary_search_elem(&self, x: &T) -> BinarySearchResult { - core_slice::OrdSliceExt::binary_search_elem(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) - } -} - -/// Allocating extension methods for slices. -#[experimental = "likely to merge with other traits"] -pub trait SliceExt for Sized? { - /// Sorts the slice, in place, using `compare` to compare - /// elements. - /// - /// This sort is `O(n log n)` worst-case and stable, but allocates - /// approximately `2 * n`, where `n` is the length of `self`. - /// - /// # Examples - /// - /// ```rust - /// let mut v = [5i, 4, 1, 3, 2]; - /// v.sort_by(|a, b| a.cmp(b)); - /// assert!(v == [1, 2, 3, 4, 5]); - /// - /// // reverse sorting - /// v.sort_by(|a, b| b.cmp(a)); - /// assert!(v == [5, 4, 3, 2, 1]); - /// ``` - fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering; - - /// Consumes `src` and moves as many elements as it can into `self` - /// from the range [start,end). - /// - /// Returns the number of elements copied (the shorter of `self.len()` - /// and `end - start`). - /// - /// # Arguments - /// - /// * src - A mutable vector of `T` - /// * start - The index into `src` to start copying from - /// * end - The index into `src` to stop copying from - /// - /// # Examples - /// - /// ```rust - /// let mut a = [1i, 2, 3, 4, 5]; - /// let b = vec![6i, 7, 8]; - /// let num_moved = a.move_from(b, 0, 3); - /// assert_eq!(num_moved, 3); - /// assert!(a == [6i, 7, 8, 4, 5]); - /// ``` - fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; - - /// Returns a subslice spanning the interval [`start`, `end`). - /// - /// Panics when the end of the new slice lies beyond the end of the - /// original slice (i.e. when `end > self.len()`) or when `start > end`. - /// - /// 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) -> &[T]; - - /// Returns a subslice from `start` to the end of the slice. - /// - /// Panics when `start` is strictly greater than the length of the original slice. - /// - /// Slicing from `self.len()` yields an empty slice. - #[unstable = "waiting on final error conventions/slicing syntax"] - fn slice_from(&self, start: uint) -> &[T]; - - /// Returns a subslice from the start of the slice to `end`. - /// - /// Panics when `end` is strictly greater than the length of the original slice. - /// - /// Slicing to `0` yields an empty slice. - #[unstable = "waiting on final error conventions/slicing syntax"] - fn slice_to(&self, end: uint) -> &[T]; - - /// Divides one slice into two at an index. - /// - /// The first will contain all indices from `[0, mid)` (excluding - /// the index `mid` itself) and the second will contain all - /// indices from `[mid, len)` (excluding the index `len` itself). - /// - /// Panics if `mid > len`. - #[unstable = "waiting on final error conventions"] - fn split_at(&self, mid: uint) -> (&[T], &[T]); - - /// Returns an iterator over the slice - #[unstable = "iterator type may change"] - fn iter(&self) -> Iter; - - /// 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: F) -> Splits - where F: FnMut(&T) -> 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. - #[unstable = "iterator type may change"] - fn splitn(&self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> 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. - #[unstable = "iterator type may change"] - fn rsplitn(&self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool; - - /// Returns an iterator over all contiguous windows of length - /// `size`. The windows overlap. If the slice is shorter than - /// `size`, the iterator returns no values. - /// - /// # Panics - /// - /// Panics if `size` is 0. - /// - /// # Example - /// - /// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`, - /// `[3,4]`): - /// - /// ```rust - /// let v = &[1i, 2, 3, 4]; - /// for win in v.windows(2) { - /// println!("{}", win); - /// } - /// ``` - #[unstable = "iterator type may change"] - fn windows(&self, size: uint) -> Windows; - - /// Returns an iterator over `size` elements of the slice at a - /// time. The chunks do not overlap. If `size` does not divide the - /// length of the slice, then the last chunk will not have length - /// `size`. - /// - /// # Panics - /// - /// Panics if `size` is 0. - /// - /// # Example - /// - /// Print the slice two elements at a time (i.e. `[1,2]`, - /// `[3,4]`, `[5]`): - /// - /// ```rust - /// let v = &[1i, 2, 3, 4, 5]; - /// for win in v.chunks(2) { - /// println!("{}", win); - /// } - /// ``` - #[unstable = "iterator type may change"] - fn chunks(&self, size: uint) -> Chunks; - - /// 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<&T>; - - /// Returns the first element of a slice, or `None` if it is empty. - #[unstable = "name may change"] - fn head(&self) -> Option<&T>; - - /// Returns all but the first element of a slice. - #[unstable = "name may change"] - fn tail(&self) -> &[T]; - - /// Returns all but the last element of a slice. - #[unstable = "name may change"] - fn init(&self) -> &[T]; - - /// Returns the last element of a slice, or `None` if it is empty. - #[unstable = "name may change"] - fn last(&self) -> Option<&T>; - - /// Returns a pointer to the element at the given index, without doing - /// bounds checking. - #[unstable] - unsafe fn unsafe_get(&self, index: uint) -> &T; - - /// Returns an unsafe pointer to the slice's buffer - /// - /// The caller must ensure that the slice outlives the pointer this - /// function returns, or else it will end up pointing to garbage. - /// - /// Modifying the slice may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. - #[unstable] - fn as_ptr(&self) -> *const T; - - /// Binary search a sorted slice with a comparator function. - /// - /// The comparator function should implement an order consistent - /// with the sort order of the underlying slice, returning an - /// order code that indicates whether its argument is `Less`, - /// `Equal` or `Greater` the desired target. - /// - /// If a matching value is found then returns `Found`, containing - /// the index for the matched element; if no match is found then - /// `NotFound` 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 - /// use std::slice::BinarySearchResult::{Found, NotFound}; - /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; - /// let s = s.as_slice(); - /// - /// let seek = 13; - /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), Found(9)); - /// let seek = 4; - /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), NotFound(7)); - /// let seek = 100; - /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), NotFound(13)); - /// let seek = 1; - /// let r = s.binary_search(|probe| probe.cmp(&seek)); - /// assert!(match r { Found(1...4) => true, _ => false, }); - /// ``` - #[unstable = "waiting on unboxed closures"] - fn binary_search(&self, f: F) -> BinarySearchResult - where F: FnMut(&T) -> Ordering; - - /// Return the number of elements in the slice - /// - /// # Example - /// - /// ``` - /// let a = [1i, 2, 3]; - /// assert_eq!(a.len(), 3); - /// ``` - #[experimental = "not triaged yet"] - fn len(&self) -> uint; - - /// Returns true if the slice has a length of 0 - /// - /// # Example - /// - /// ``` - /// let a = [1i, 2, 3]; - /// assert!(!a.is_empty()); - /// ``` - #[inline] - #[experimental = "not triaged yet"] - fn is_empty(&self) -> bool { self.len() == 0 } - /// 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(&mut self, index: uint) -> Option<&mut T>; - - /// Work with `self` as a mut slice. - /// Primarily intended for getting a &mut [T] from a [T, ..N]. - fn as_mut_slice(&mut self) -> &mut [T]; - - /// Returns a mutable subslice spanning the interval [`start`, `end`). - /// - /// Panics when the end of the new slice lies beyond the end of the - /// original slice (i.e. when `end > self.len()`) or when `start > end`. - /// - /// Slicing with `start` equal to `end` yields an empty slice. - #[unstable = "waiting on final error conventions"] - fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T]; - - /// Returns a mutable subslice from `start` to the end of the slice. - /// - /// Panics when `start` is strictly greater than the length of the original slice. - /// - /// Slicing from `self.len()` yields an empty slice. - #[unstable = "waiting on final error conventions"] - fn slice_from_mut(&mut self, start: uint) -> &mut [T]; - - /// Returns a mutable subslice from the start of the slice to `end`. - /// - /// Panics when `end` is strictly greater than the length of the original slice. - /// - /// Slicing to `0` yields an empty slice. - #[unstable = "waiting on final error conventions"] - fn slice_to_mut(&mut self, end: uint) -> &mut [T]; - - /// Returns an iterator that allows modifying each value - #[unstable = "waiting on iterator type name conventions"] - fn iter_mut(&mut self) -> IterMut; - - /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty - #[unstable = "name may change"] - fn head_mut(&mut self) -> Option<&mut T>; - - /// Returns all but the first element of a mutable slice - #[unstable = "name may change"] - fn tail_mut(&mut self) -> &mut [T]; - - /// Returns all but the last element of a mutable slice - #[unstable = "name may change"] - fn init_mut(&mut self) -> &mut [T]; - - /// Returns a mutable pointer to the last item in the slice. - #[unstable = "name may change"] - fn last_mut(&mut self) -> Option<&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(&mut self, pred: F) -> MutSplits - where F: FnMut(&T) -> 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. - #[unstable = "waiting on unboxed closures, iterator type name conventions"] - fn splitn_mut(&mut self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> 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. - #[unstable = "waiting on unboxed closures, iterator type name conventions"] - fn rsplitn_mut(&mut self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> 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 - /// not divide the length of the slice, then the last chunk will not - /// have length `chunk_size`. - /// - /// # Panics - /// - /// Panics if `chunk_size` is 0. - #[unstable = "waiting on iterator type name conventions"] - fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks; - - /// Swaps two elements in a slice. - /// - /// Panics if `a` or `b` are out of bounds. - /// - /// # Arguments - /// - /// * a - The index of the first element - /// * b - The index of the second element - /// - /// # Example - /// - /// ```rust - /// let mut v = ["a", "b", "c", "d"]; - /// v.swap(1, 3); - /// assert!(v == ["a", "d", "c", "b"]); - /// ``` - #[unstable = "waiting on final error conventions"] - fn swap(&mut self, a: uint, b: uint); - - /// Divides one `&mut` into two at an index. - /// - /// The first will contain all indices from `[0, mid)` (excluding - /// the index `mid` itself) and the second will contain all - /// indices from `[mid, len)` (excluding the index `len` itself). - /// - /// Panics if `mid > len`. - /// - /// # Example - /// - /// ```rust - /// let mut v = [1i, 2, 3, 4, 5, 6]; - /// - /// // scoped to restrict the lifetime of the borrows - /// { - /// let (left, right) = v.split_at_mut(0); - /// assert!(left == []); - /// assert!(right == [1i, 2, 3, 4, 5, 6]); - /// } - /// - /// { - /// let (left, right) = v.split_at_mut(2); - /// assert!(left == [1i, 2]); - /// assert!(right == [3i, 4, 5, 6]); - /// } - /// - /// { - /// let (left, right) = v.split_at_mut(6); - /// assert!(left == [1i, 2, 3, 4, 5, 6]); - /// assert!(right == []); - /// } - /// ``` - #[unstable = "waiting on final error conventions"] - fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]); - - /// Reverse the order of elements in a slice, in place. - /// - /// # Example - /// - /// ```rust - /// let mut v = [1i, 2, 3]; - /// v.reverse(); - /// assert!(v == [3i, 2, 1]); - /// ``` - #[experimental = "may be moved to iterators instead"] - fn reverse(&mut self); - - /// Returns an unsafe mutable pointer to the element in index - #[experimental = "waiting on unsafe conventions"] - unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T; - - /// Return an unsafe mutable pointer to the slice's buffer. - /// - /// The caller must ensure that the slice outlives the pointer this - /// function returns, or else it will end up pointing to garbage. - /// - /// Modifying the slice may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. - #[inline] - #[unstable] - fn as_mut_ptr(&mut self) -> *mut T; -} - -impl SliceExt for [T] { - #[inline] - fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { - merge_sort(self, compare) - } - - #[inline] - fn move_from(&mut self, mut src: Vec, start: uint, end: uint) -> uint { - for (a, b) in self.iter_mut().zip(src.slice_mut(start, end).iter_mut()) { - mem::swap(a, b); - } - cmp::min(self.len(), end-start) - } - - #[inline] - fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] { - core_slice::SliceExt::slice(self, start, end) - } - - #[inline] - fn slice_from<'a>(&'a self, start: uint) -> &'a [T] { - core_slice::SliceExt::slice_from(self, start) - } - - #[inline] - fn slice_to<'a>(&'a self, end: uint) -> &'a [T] { - core_slice::SliceExt::slice_to(self, end) - } - - #[inline] - fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]) { - core_slice::SliceExt::split_at(self, mid) - } - - #[inline] - fn iter<'a>(&'a self) -> Iter<'a, T> { - core_slice::SliceExt::iter(self) - } - - #[inline] - fn split(&self, pred: F) -> Splits - where F: FnMut(&T) -> bool { - core_slice::SliceExt::split(self, pred) - } - - #[inline] - fn splitn(&self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool { - core_slice::SliceExt::splitn(self, n, pred) - } - - #[inline] - fn rsplitn(&self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool { - core_slice::SliceExt::rsplitn(self, n, pred) - } - - #[inline] - fn windows<'a>(&'a self, size: uint) -> Windows<'a, T> { - core_slice::SliceExt::windows(self, size) - } - - #[inline] - fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T> { - core_slice::SliceExt::chunks(self, size) - } - - #[inline] - fn get<'a>(&'a self, index: uint) -> Option<&'a T> { - core_slice::SliceExt::get(self, index) - } - - #[inline] - fn head<'a>(&'a self) -> Option<&'a T> { - core_slice::SliceExt::head(self) - } - - #[inline] - fn tail<'a>(&'a self) -> &'a [T] { - core_slice::SliceExt::tail(self) - } - - #[inline] - fn init<'a>(&'a self) -> &'a [T] { - core_slice::SliceExt::init(self) - } - - #[inline] - fn last<'a>(&'a self) -> Option<&'a T> { - core_slice::SliceExt::last(self) - } - - #[inline] - unsafe fn unsafe_get<'a>(&'a self, index: uint) -> &'a T { - core_slice::SliceExt::unsafe_get(self, index) - } - - #[inline] - fn as_ptr(&self) -> *const T { - core_slice::SliceExt::as_ptr(self) - } - - #[inline] - fn binary_search(&self, f: F) -> BinarySearchResult - where F: FnMut(&T) -> Ordering { - core_slice::SliceExt::binary_search(self, f) - } - - #[inline] - fn len(&self) -> uint { - core_slice::SliceExt::len(self) - } - - #[inline] - fn is_empty(&self) -> bool { - core_slice::SliceExt::is_empty(self) - } - - #[inline] - fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T> { - core_slice::SliceExt::get_mut(self, index) - } - - #[inline] - fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { - core_slice::SliceExt::as_mut_slice(self) - } - - #[inline] - fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_mut(self, start, end) - } - - #[inline] - fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_from_mut(self, start) - } - - #[inline] - fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_to_mut(self, end) - } - - #[inline] - fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { - core_slice::SliceExt::iter_mut(self) - } - - #[inline] - fn head_mut<'a>(&'a mut self) -> Option<&'a mut T> { - core_slice::SliceExt::head_mut(self) - } - - #[inline] - fn tail_mut<'a>(&'a mut self) -> &'a mut [T] { - core_slice::SliceExt::tail_mut(self) - } - - #[inline] - fn init_mut<'a>(&'a mut self) -> &'a mut [T] { - core_slice::SliceExt::init_mut(self) - } - - #[inline] - fn last_mut<'a>(&'a mut self) -> Option<&'a mut T> { - core_slice::SliceExt::last_mut(self) - } - - #[inline] - fn split_mut(&mut self, pred: F) -> MutSplits - where F: FnMut(&T) -> bool { - core_slice::SliceExt::split_mut(self, pred) - } - - #[inline] - fn splitn_mut(&mut self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool { - core_slice::SliceExt::splitn_mut(self, n, pred) - } - - #[inline] - fn rsplitn_mut(&mut self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool { - core_slice::SliceExt::rsplitn_mut(self, n, pred) - } - - #[inline] - fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T> { - core_slice::SliceExt::chunks_mut(self, chunk_size) - } - - #[inline] - fn swap(&mut self, a: uint, b: uint) { - core_slice::SliceExt::swap(self, a, b) - } - - #[inline] - fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) { - core_slice::SliceExt::split_at_mut(self, mid) - } - - #[inline] - fn reverse(&mut self) { - core_slice::SliceExt::reverse(self) - } - - #[inline] - unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T { - core_slice::SliceExt::unsafe_mut(self, index) - } - - #[inline] - fn as_mut_ptr(&mut self) -> *mut T { - core_slice::SliceExt::as_mut_ptr(self) - } -} - -#[unstable = "trait is unstable"] -impl BorrowFrom> for [T] { - fn borrow_from(owned: &Vec) -> &[T] { owned[] } -} - -#[unstable = "trait is unstable"] -impl BorrowFromMut> for [T] { - fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { owned.as_mut_slice_() } -} - -#[unstable = "trait is unstable"] -impl ToOwned> for [T] { - fn to_owned(&self) -> Vec { self.to_vec() } -} - -/// Unsafe operations +/// Deprecated, unsafe operations +#[deprecated] pub mod raw { pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice}; pub use core::slice::raw::{shift_ptr, pop_ptr}; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index f356a0867d2..38d8977c0aa 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -68,23 +68,23 @@ pub trait SliceExt for Sized? { 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) -> Splits<'a, T, P> + 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) -> SplitsN> + 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) -> SplitsN> + 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 head<'a>(&'a self) -> 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 unsafe_get<'a>(&'a self, index: uint) -> &'a T; + unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T; fn as_ptr(&self) -> *const T; - fn binary_search(&self, f: F) -> BinarySearchResult - where F: FnMut(&T) -> Ordering; + fn binary_search_by(&self, f: F) -> Result where + F: FnMut(&T) -> 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>; @@ -93,21 +93,21 @@ pub trait SliceExt for Sized? { 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 head_mut<'a>(&'a mut self) -> Option<&'a mut 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) -> MutSplits<'a, T, P> + fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> where P: FnMut(&T) -> bool; - fn splitn_mut

(&mut self, n: uint, pred: P) -> SplitsN> + fn splitn_mut

(&mut self, n: uint, pred: P) -> SplitNMut where P: FnMut(&T) -> bool; - fn rsplitn_mut

(&mut self, n: uint, pred: P) -> SplitsN> + fn rsplitn_mut

(&mut self, n: uint, pred: P) -> RSplitNMut where P: FnMut(&T) -> bool; - fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T>; + fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, T>; 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 reverse(&mut self); - unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T; + unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T; fn as_mut_ptr(&mut self) -> *mut T; } @@ -145,11 +145,11 @@ impl SliceExt for [T] { unsafe { let p = self.as_ptr(); if mem::size_of::() == 0 { - Iter{ptr: p, + Iter {ptr: p, end: (p as uint + self.len()) as *const T, marker: marker::ContravariantLifetime::<'a>} } else { - Iter{ptr: p, + Iter {ptr: p, end: p.offset(self.len() as int), marker: marker::ContravariantLifetime::<'a>} } @@ -157,8 +157,8 @@ impl SliceExt for [T] { } #[inline] - fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where P: FnMut(&T) -> bool { - Splits { + fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P> where P: FnMut(&T) -> bool { + Split { v: self, pred: pred, finished: false @@ -166,24 +166,28 @@ impl SliceExt for [T] { } #[inline] - fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> where + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split(pred), - count: n, - invert: false + SplitN { + inner: GenericSplitN { + iter: self.split(pred), + count: n, + invert: false + } } } #[inline] - fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> where + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split(pred), - count: n, - invert: true + RSplitN { + inner: GenericSplitN { + iter: self.split(pred), + count: n, + invert: true + } } } @@ -205,7 +209,7 @@ impl SliceExt for [T] { } #[inline] - fn head(&self) -> Option<&T> { + fn first(&self) -> Option<&T> { if self.len() == 0 { None } else { Some(&self[0]) } } @@ -223,7 +227,7 @@ impl SliceExt for [T] { } #[inline] - unsafe fn unsafe_get(&self, index: uint) -> &T { + unsafe fn get_unchecked(&self, index: uint) -> &T { transmute(self.repr().data.offset(index as int)) } @@ -233,14 +237,16 @@ impl SliceExt for [T] { } #[unstable] - fn binary_search(&self, mut f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering { + fn binary_search_by(&self, mut f: F) -> Result where + F: FnMut(&T) -> Ordering + { let mut base : uint = 0; let mut lim : uint = self.len(); while lim != 0 { let ix = base + (lim >> 1); match f(&self[ix]) { - Equal => return BinarySearchResult::Found(ix), + Equal => return Ok(ix), Less => { base = ix + 1; lim -= 1; @@ -249,7 +255,7 @@ impl SliceExt for [T] { } lim >>= 1; } - return BinarySearchResult::NotFound(base); + Err(base); } #[inline] @@ -292,11 +298,11 @@ impl SliceExt for [T] { unsafe { let p = self.as_mut_ptr(); if mem::size_of::() == 0 { - IterMut{ptr: p, + IterMut {ptr: p, end: (p as uint + self.len()) as *mut T, marker: marker::ContravariantLifetime::<'a>} } else { - IterMut{ptr: p, + IterMut {ptr: p, end: p.offset(self.len() as int), marker: marker::ContravariantLifetime::<'a>} } @@ -311,7 +317,7 @@ impl SliceExt for [T] { } #[inline] - fn head_mut(&mut self) -> Option<&mut T> { + fn first_mut(&mut self) -> Option<&mut T> { if self.len() == 0 { None } else { Some(&mut self[0]) } } @@ -327,36 +333,40 @@ impl SliceExt for [T] { } #[inline] - fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where P: FnMut(&T) -> bool { - MutSplits { v: self, pred: pred, finished: false } + fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> where P: FnMut(&T) -> bool { + SplitMut { v: self, pred: pred, finished: false } } #[inline] - fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN> where + fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitNMut<'a, T, P> where P: FnMut(&T) -> bool { - SplitsN { - iter: self.split_mut(pred), - count: n, - invert: false + SplitNMut { + inner: GenericSplitN { + iter: self.split_mut(pred), + count: n, + invert: false + } } } #[inline] - fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN> where + fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> RSplitNMut<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split_mut(pred), - count: n, - invert: true + RSplitNMut { + inner: GenericSplitN { + iter: self.split_mut(pred), + count: n, + invert: true + } } } #[inline] - fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks { + fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut { assert!(chunk_size > 0); - MutChunks { v: self, chunk_size: chunk_size } + ChunksMut { v: self, chunk_size: chunk_size } } fn swap(&mut self, a: uint, b: uint) { @@ -375,8 +385,8 @@ impl SliceExt for [T] { while i < ln / 2 { // Unsafe swap to avoid the bounds check in safe swap. unsafe { - let pa: *mut T = self.unsafe_mut(i); - let pb: *mut T = self.unsafe_mut(ln - i - 1); + let pa: *mut T = self.get_unchecked_mut(i); + let pb: *mut T = self.get_unchecked_mut(ln - i - 1); ptr::swap(pa, pb); } i += 1; @@ -384,7 +394,7 @@ impl SliceExt for [T] { } #[inline] - unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T { + unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T { transmute((self.repr().data as *mut T).offset(index as int)) } @@ -468,21 +478,26 @@ impl ops::SliceMut for [T] { } /// Extension methods for slices containing `PartialEq` elements. -#[unstable = "may merge with other traits"] +#[unstable = "may merge with SliceExt"] pub trait PartialEqSliceExt for Sized? { /// Find the first index containing a matching value. + #[experimental] fn position_elem(&self, t: &T) -> Option; /// Find the last index containing a matching value. + #[experimental] fn rposition_elem(&self, t: &T) -> Option; /// 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; } @@ -520,19 +535,16 @@ impl PartialEqSliceExt for [T] { #[unstable = "may merge with other traits"] #[allow(missing_docs)] // docs in libcollections pub trait OrdSliceExt for Sized? { - #[unstable = "name likely to change"] - fn binary_search_elem(&self, x: &T) -> BinarySearchResult; - #[experimental] + fn binary_search(&self, x: &T) -> Result; fn next_permutation(&mut self) -> bool; - #[experimental] fn prev_permutation(&mut self) -> bool; } #[unstable = "trait is unstable"] impl OrdSliceExt for [T] { #[unstable] - fn binary_search_elem(&self, x: &T) -> BinarySearchResult { - self.binary_search(|p| p.cmp(x)) + fn binary_search(&self, x: &T) -> Result { + self.binary_search_by(|p| p.cmp(x)) } #[experimental] @@ -619,28 +631,30 @@ impl CloneSliceExt for [T] { } } -// +//////////////////////////////////////////////////////////////////////////////// // Common traits -// +//////////////////////////////////////////////////////////////////////////////// /// Data that is viewable as a slice. -#[unstable = "may merge with other traits"] +#[experimental = "will be replaced by slice syntax"] pub trait AsSlice for Sized? { /// Work with `self` as a slice. fn as_slice<'a>(&'a self) -> &'a [T]; } -#[unstable = "trait is unstable"] +#[experimental = "trait is experimental"] impl AsSlice for [T] { #[inline(always)] fn as_slice<'a>(&'a self) -> &'a [T] { self } } +#[experimental = "trait is experimental"] impl<'a, T, Sized? U: AsSlice> AsSlice for &'a U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } } +#[experimental = "trait is experimental"] impl<'a, T, Sized? U: AsSlice> AsSlice for &'a mut U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } @@ -656,7 +670,7 @@ impl<'a, T> Default for &'a [T] { // Iterators // -// The shared definition of the `Item` and `IterMut` iterators +// The shared definition of the `Iter` and `IterMut` iterators macro_rules! iterator { (struct $name:ident -> $ptr:ty, $elem:ty) => { #[experimental = "needs review"] @@ -736,9 +750,8 @@ macro_rules! make_slice { }} } - /// Immutable slice iterator -#[experimental = "needs review"] +#[stable] pub struct Iter<'a, T: 'a> { ptr: *const T, end: *const T, @@ -813,7 +826,7 @@ impl<'a, T> RandomAccessIterator<&'a T> for Iter<'a, T> { } /// Mutable slice iterator. -#[experimental = "needs review"] +#[stable] pub struct IterMut<'a, T: 'a> { ptr: *mut T, end: *mut T, @@ -876,9 +889,9 @@ iterator!{struct IterMut -> *mut T, &'a mut T} #[experimental = "needs review"] impl<'a, T> ExactSizeIterator<&'a mut T> for IterMut<'a, T> {} -/// An abstraction over the splitting iterators, so that splitn, splitn_mut etc -/// can be implemented once. -trait SplitsIter: DoubleEndedIterator { +/// An internal abstraction over the splitting iterators, so that +/// splitn, splitn_mut etc can be implemented once. +trait SplitIter: DoubleEndedIterator { /// Mark the underlying iterator as complete, extracting the remaining /// portion of the slice. fn finish(&mut self) -> Option; @@ -886,8 +899,8 @@ trait SplitsIter: DoubleEndedIterator { /// An iterator over subslices separated by elements that match a predicate /// function. -#[experimental = "needs review"] -pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool { +#[stable] +pub struct Split<'a, T:'a, P> where P: FnMut(&T) -> bool { v: &'a [T], pred: P, finished: bool @@ -895,9 +908,9 @@ pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool { // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` #[stable] -impl<'a, T, P> Clone for Splits<'a, T, P> where P: Clone + FnMut(&T) -> bool { - fn clone(&self) -> Splits<'a, T, P> { - Splits { +impl<'a, T, P> Clone for Split<'a, T, P> where P: Clone + FnMut(&T) -> bool { + fn clone(&self) -> Split<'a, T, P> { + Split { v: self.v, pred: self.pred.clone(), finished: self.finished, @@ -906,7 +919,7 @@ impl<'a, T, P> Clone for Splits<'a, T, P> where P: Clone + FnMut(&T) -> bool { } #[experimental = "needs review"] -impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator<&'a [T]> for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next(&mut self) -> Option<&'a [T]> { if self.finished { return None; } @@ -932,7 +945,7 @@ impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool } #[experimental = "needs review"] -impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next_back(&mut self) -> Option<&'a [T]> { if self.finished { return None; } @@ -948,7 +961,7 @@ impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut( } } -impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter<&'a [T]> for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn finish(&mut self) -> Option<&'a [T]> { if self.finished { None } else { self.finished = true; Some(self.v) } @@ -957,14 +970,14 @@ impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bo /// An iterator over the subslices of the vector which are separated /// by elements that match `pred`. -#[experimental = "needs review"] -pub struct MutSplits<'a, T:'a, P> where P: FnMut(&T) -> bool { +#[stable] +pub struct SplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { v: &'a mut [T], pred: P, finished: bool } -impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn finish(&mut self) -> Option<&'a mut [T]> { if self.finished { @@ -977,7 +990,7 @@ impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T } #[experimental = "needs review"] -impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next(&mut self) -> Option<&'a mut [T]> { if self.finished { return None; } @@ -1010,7 +1023,7 @@ impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) } #[experimental = "needs review"] -impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where +impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool, { #[inline] @@ -1033,17 +1046,17 @@ impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where } } -/// An iterator over subslices separated by elements that match a predicate -/// function, splitting at most a fixed number of times. -#[experimental = "needs review"] -pub struct SplitsN { +/// An private iterator over subslices separated by elements that +/// match a predicate function, splitting at most a fixed number of +/// times. +struct GenericSplitN { iter: I, count: uint, invert: bool } #[experimental = "needs review"] -impl> Iterator for SplitsN { +impl> Iterator for GenericSplitN { #[inline] fn next(&mut self) -> Option { if self.count == 0 { @@ -1061,6 +1074,55 @@ impl> Iterator for SplitsN { } } +/// An iterator over subslices separated by elements that match a predicate +/// function, limited to a given number of splits. +pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN> +} + +/// An iterator over subslices separated by elements that match a +/// predicate function, limited to a given number of splits, starting +/// from the end of the slice. +pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN> +} + +/// An iterator over subslices separated by elements that match a predicate +/// function, limited to a given number of splits. +pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN> +} + +/// An iterator over subslices separated by elements that match a +/// predicate function, limited to a given number of splits, starting +/// from the end of the slice. +pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN> +} + +macro_rules! forward_iterator { + ($name:ident: $elem:ident, $iter_of:ty) => { + impl<'a, $elem, P> Iterator<$iter_of> for $name<'a, $elem, P> where + P: FnMut(&T) -> bool + { + #[inline] + fn next(&mut self) -> Option<$iter_of> { + self.inner.next() + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.inner.size_hint() + } + } + } +} + +forward_iterator! { SplitN: T, &'a [T] } +forward_iterator! { RSplitN: T, &'a [T] } +forward_iterator! { SplitNMut: T, &'a mut [T] } +forward_iterator! { RSplitNMut: T, &'a mut [T] } + /// An iterator over overlapping subslices of length `size`. #[deriving(Clone)] #[experimental = "needs review"] @@ -1172,13 +1234,13 @@ impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> { /// elements at a time). When the slice len is not evenly divided by the chunk /// size, the last slice of the iteration will be the remainder. #[experimental = "needs review"] -pub struct MutChunks<'a, T:'a> { +pub struct ChunksMut<'a, T:'a> { v: &'a mut [T], chunk_size: uint } #[experimental = "needs review"] -impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> { +impl<'a, T> Iterator<&'a mut [T]> for ChunksMut<'a, T> { #[inline] fn next(&mut self) -> Option<&'a mut [T]> { if self.v.len() == 0 { @@ -1206,7 +1268,7 @@ impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> { } #[experimental = "needs review"] -impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> { +impl<'a, T> DoubleEndedIterator<&'a mut [T]> for ChunksMut<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a mut [T]> { if self.v.len() == 0 { @@ -1224,51 +1286,12 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> { } - -/// The result of calling `binary_search`. -/// -/// `Found` means the search succeeded, and the contained value is the -/// index of the matching element. `NotFound` means the search -/// succeeded, and the contained value is an index where a matching -/// value could be inserted while maintaining sort order. -#[deriving(Copy, PartialEq, Show)] -#[experimental = "needs review"] -pub enum BinarySearchResult { - /// The index of the found value. - Found(uint), - /// The index where the value should have been found. - NotFound(uint) -} - -#[experimental = "needs review"] -impl BinarySearchResult { - /// Converts a `Found` to `Some`, `NotFound` to `None`. - /// Similar to `Result::ok`. - pub fn found(&self) -> Option { - match *self { - BinarySearchResult::Found(i) => Some(i), - BinarySearchResult::NotFound(_) => None - } - } - - /// Convert a `Found` to `None`, `NotFound` to `Some`. - /// Similar to `Result::err`. - pub fn not_found(&self) -> Option { - match *self { - BinarySearchResult::Found(_) => None, - BinarySearchResult::NotFound(i) => Some(i) - } - } -} - - - // // Free functions // /// Converts a pointer to A into a slice of length 1 (without copying). -#[unstable = "waiting for DST"] +#[unstable] pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] { unsafe { transmute(RawSlice { data: s, len: 1 }) @@ -1276,7 +1299,7 @@ pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] { } /// Converts a pointer to A into a slice of length 1 (without copying). -#[unstable = "waiting for DST"] +#[unstable] pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { unsafe { let ptr: *const A = transmute(s); @@ -1310,7 +1333,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { /// } /// ``` #[inline] -#[unstable = "just renamed from `mod raw`"] +#[unstable = "should be renamed to from_raw_parts"] pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] { transmute(RawSlice { data: *p, len: len }) } @@ -1322,7 +1345,7 @@ pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] { /// not being able to provide a non-aliasing guarantee of the returned mutable /// slice. #[inline] -#[unstable = "just renamed from `mod raw`"] +#[unstable = "jshould be renamed to from_raw_parts_mut"] pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] { transmute(RawSlice { data: *p as *const T, len: len }) } @@ -1497,39 +1520,28 @@ impl PartialOrd for [T] { } } -/// Extension methods for immutable slices containing integers. +/// Extension methods for slices containing integers. #[experimental] -pub trait ImmutableIntSlice for Sized? { +pub trait IntSliceExt for Sized? { /// Converts the slice to an immutable slice of unsigned integers with the same width. 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<'a>(&'a self) -> &'a [S]; -} -/// Extension methods for mutable slices containing integers. -#[experimental] -pub trait MutableIntSlice for Sized?: ImmutableIntSlice { /// Converts the slice to a mutable slice of unsigned integers with the same width. 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<'a>(&'a mut self) -> &'a mut [S]; } -macro_rules! impl_immut_int_slice { +macro_rules! impl_int_slice { ($u:ty, $s:ty, $t:ty) => { #[experimental] - impl ImmutableIntSlice<$u, $s> for [$t] { + impl IntSliceExt<$u, $s> for [$t] { #[inline] fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } } #[inline] fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } } - } - } -} -macro_rules! impl_mut_int_slice { - ($u:ty, $s:ty, $t:ty) => { - #[experimental] - impl MutableIntSlice<$u, $s> for [$t] { #[inline] fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } } #[inline] @@ -1538,17 +1550,15 @@ macro_rules! impl_mut_int_slice { } } -macro_rules! impl_int_slice { +macro_rules! impl_int_slices { ($u:ty, $s:ty) => { - 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 } + impl_int_slice! { $u, $s, $u } + impl_int_slice! { $u, $s, $s } } } -impl_int_slice! { u8, i8 } -impl_int_slice! { u16, i16 } -impl_int_slice! { u32, i32 } -impl_int_slice! { u64, i64 } -impl_int_slice! { uint, int } +impl_int_slices! { u8, i8 } +impl_int_slices! { u16, i16 } +impl_int_slices! { u32, i32 } +impl_int_slices! { u64, i64 } +impl_int_slices! { uint, int } diff --git a/src/rust-installer b/src/rust-installer index 3a37981744a..aed73472416 160000 --- a/src/rust-installer +++ b/src/rust-installer @@ -1 +1 @@ -Subproject commit 3a37981744a5af2433fed551f742465c78c9af7f +Subproject commit aed73472416064642911af790b25d57c9390b6c7