diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index c0da6331b2211..7ff28019de844 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -221,208 +221,110 @@ mod hack { #[cfg(not(test))] #[stable(feature = "rust1", since = "1.0.0")] impl [T] { - /// 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 + /// Returns the number of elements in the slice. /// - /// ```rust - /// let mut v = [5, 4, 1, 3, 2]; - /// v.sort_by(|a, b| a.cmp(b)); - /// assert!(v == [1, 2, 3, 4, 5]); + /// # Example /// - /// // reverse sorting - /// v.sort_by(|a, b| b.cmp(a)); - /// assert!(v == [5, 4, 3, 2, 1]); + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.len(), 3); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { - merge_sort(self, compare) + pub fn len(&self) -> usize { + core_slice::SliceExt::len(self) } - /// 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 + /// Returns true if the slice has a length of 0 /// - /// # Examples + /// # Example /// - /// ```rust - /// # #![feature(collections)] - /// let mut a = [1, 2, 3, 4, 5]; - /// let b = vec![6, 7, 8]; - /// let num_moved = a.move_from(b, 0, 3); - /// assert_eq!(num_moved, 3); - /// assert!(a == [6, 7, 8, 4, 5]); /// ``` - #[unstable(feature = "collections", - reason = "uncertain about this API approach")] + /// let a = [1, 2, 3]; + /// assert!(!a.is_empty()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn move_from(&mut self, mut src: Vec, start: usize, end: usize) -> usize { - for (a, b) in self.iter_mut().zip(src[start .. end].iter_mut()) { - mem::swap(a, b); - } - cmp::min(self.len(), end-start) + pub fn is_empty(&self) -> bool { + core_slice::SliceExt::is_empty(self) } - /// 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`. + /// Returns the first element of a slice, or `None` if it is empty. /// /// # Examples /// /// ``` - /// let v = [10, 40, 30, 20, 50]; - /// let (v1, v2) = v.split_at(2); - /// assert_eq!([10, 40], v1); - /// assert_eq!([30, 20, 50], v2); + /// let v = [10, 40, 30]; + /// assert_eq!(Some(&10), v.first()); + /// + /// let w: &[i32] = &[]; + /// assert_eq!(None, w.first()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn split_at(&self, mid: usize) -> (&[T], &[T]) { - core_slice::SliceExt::split_at(self, mid) + pub fn first(&self) -> Option<&T> { + core_slice::SliceExt::first(self) } - /// Returns an iterator over the slice. + /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn iter(&self) -> Iter { - core_slice::SliceExt::iter(self) + pub fn first_mut(&mut self) -> Option<&mut T> { + core_slice::SliceExt::first_mut(self) } - /// Returns an iterator over subslices separated by elements that match - /// `pred`. The matched element is not contained in the subslices. - /// - /// # Examples - /// - /// Print the slice split by numbers divisible by 3 (i.e. `[10, 40]`, - /// `[20]`, `[50]`): - /// - /// ``` - /// let v = [10, 40, 30, 20, 60, 50]; - /// for group in v.split(|num| *num % 3 == 0) { - /// println!("{:?}", group); - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] + /// Returns all but the first element of a slice. + #[unstable(feature = "collections", reason = "likely to be renamed")] #[inline] - pub fn split(&self, pred: F) -> Split where F: FnMut(&T) -> bool { - core_slice::SliceExt::split(self, pred) + pub fn tail(&self) -> &[T] { + core_slice::SliceExt::tail(self) } - /// Returns an iterator over subslices separated by elements that match - /// `pred`, limited to returning at most `n` items. The matched element is - /// not contained in the subslices. - /// - /// The last element returned, if any, will contain the remainder of the - /// slice. - /// - /// # Examples - /// - /// Print the slice split once by numbers divisible by 3 (i.e. `[10, 40]`, - /// `[20, 60, 50]`): - /// - /// ``` - /// let v = [10, 40, 30, 20, 60, 50]; - /// for group in v.splitn(2, |num| *num % 3 == 0) { - /// println!("{:?}", group); - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] + /// Returns all but the first element of a mutable slice + #[unstable(feature = "collections", + reason = "likely to be renamed or removed")] #[inline] - pub fn splitn(&self, n: usize, pred: F) -> SplitN where F: FnMut(&T) -> bool { - core_slice::SliceExt::splitn(self, n, pred) + pub fn tail_mut(&mut self) -> &mut [T] { + core_slice::SliceExt::tail_mut(self) } - /// Returns an iterator over subslices separated by elements that match - /// `pred` limited to returning at most `n` items. This starts at the end of - /// the slice and works backwards. The matched element is not contained in - /// the subslices. - /// - /// The last element returned, if any, will contain the remainder of the - /// slice. - /// - /// # Examples - /// - /// Print the slice split once, starting from the end, by numbers divisible - /// by 3 (i.e. `[50]`, `[10, 40, 30, 20]`): - /// - /// ``` - /// let v = [10, 40, 30, 20, 60, 50]; - /// for group in v.rsplitn(2, |num| *num % 3 == 0) { - /// println!("{:?}", group); - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] + /// Returns all but the last element of a slice. + #[unstable(feature = "collections", reason = "likely to be renamed")] #[inline] - pub fn rsplitn(&self, n: usize, pred: F) -> RSplitN where F: FnMut(&T) -> bool { - core_slice::SliceExt::rsplitn(self, n, pred) + pub fn init(&self) -> &[T] { + core_slice::SliceExt::init(self) } - /// 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. + /// Returns all but the last element of a mutable slice + #[unstable(feature = "collections", + reason = "likely to be renamed or removed")] + #[inline] + pub fn init_mut(&mut self) -> &mut [T] { + core_slice::SliceExt::init_mut(self) + } + + /// Returns the last element of a slice, or `None` if it is empty. /// - /// # Example + /// # Examples /// - /// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`, - /// `[3,4]`): + /// ``` + /// let v = [10, 40, 30]; + /// assert_eq!(Some(&30), v.last()); /// - /// ```rust - /// let v = &[1, 2, 3, 4]; - /// for win in v.windows(2) { - /// println!("{:?}", win); - /// } + /// let w: &[i32] = &[]; + /// assert_eq!(None, w.last()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn windows(&self, size: usize) -> Windows { - core_slice::SliceExt::windows(self, size) + pub fn last(&self) -> Option<&T> { + core_slice::SliceExt::last(self) } - /// 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 = &[1, 2, 3, 4, 5]; - /// for win in v.chunks(2) { - /// println!("{:?}", win); - /// } - /// ``` + /// Returns a mutable pointer to the last item in the slice. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn chunks(&self, size: usize) -> Chunks { - core_slice::SliceExt::chunks(self, size) + pub fn last_mut(&mut self) -> Option<&mut T> { + core_slice::SliceExt::last_mut(self) } /// Returns the element of a slice at the given index, or `None` if the @@ -441,63 +343,43 @@ impl [T] { core_slice::SliceExt::get(self, index) } - /// Returns the first element of a slice, or `None` if it is empty. - /// - /// # Examples - /// - /// ``` - /// let v = [10, 40, 30]; - /// assert_eq!(Some(&10), v.first()); - /// - /// let w: &[i32] = &[]; - /// assert_eq!(None, w.first()); - /// ``` + /// Returns a mutable reference to the element at the given index, + /// or `None` if the index is out of bounds #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn first(&self) -> Option<&T> { - core_slice::SliceExt::first(self) + pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { + core_slice::SliceExt::get_mut(self, index) } - /// Returns all but the first element of a slice. - #[unstable(feature = "collections", reason = "likely to be renamed")] + /// Returns a pointer to the element at the given index, without doing + /// bounds checking. + #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn tail(&self) -> &[T] { - core_slice::SliceExt::tail(self) + pub unsafe fn get_unchecked(&self, index: usize) -> &T { + core_slice::SliceExt::get_unchecked(self, index) } - /// Returns all but the last element of a slice. - #[unstable(feature = "collections", reason = "likely to be renamed")] + /// Returns an unsafe mutable pointer to the element in index + #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn init(&self) -> &[T] { - core_slice::SliceExt::init(self) + pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { + core_slice::SliceExt::get_unchecked_mut(self, index) } - /// Returns the last element of a slice, or `None` if it is empty. + /// Returns an unsafe pointer to the slice's buffer /// - /// # Examples + /// The caller must ensure that the slice outlives the pointer this + /// function returns, or else it will end up pointing to garbage. /// - /// ``` - /// let v = [10, 40, 30]; - /// assert_eq!(Some(&30), v.last()); - /// - /// let w: &[i32] = &[]; - /// assert_eq!(None, w.last()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn last(&self) -> Option<&T> { - core_slice::SliceExt::last(self) - } - - /// Returns a pointer to the element at the given index, without doing - /// bounds checking. + /// Modifying the slice may cause its buffer to be reallocated, which + /// would also make any pointers to it invalid. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub unsafe fn get_unchecked(&self, index: usize) -> &T { - core_slice::SliceExt::get_unchecked(self, index) + pub fn as_ptr(&self) -> *const T { + core_slice::SliceExt::as_ptr(self) } - /// Returns an unsafe pointer to the slice's buffer + /// Returns 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. @@ -506,118 +388,208 @@ impl [T] { /// would also make any pointers to it invalid. #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn as_ptr(&self) -> *const T { - core_slice::SliceExt::as_ptr(self) + pub fn as_mut_ptr(&mut self) -> *mut T { + core_slice::SliceExt::as_mut_ptr(self) } - /// Binary search a sorted slice with a comparator function. + /// Swaps two elements in a slice. /// - /// 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. + /// # Arguments /// - /// 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. + /// * a - The index of the first element + /// * b - The index of the second element /// - /// # Example + /// # Panics /// - /// 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]`. + /// Panics if `a` or `b` are out of bounds. /// - /// ```rust - /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; + /// # Example /// - /// 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, }); + /// ```rust + /// let mut v = ["a", "b", "c", "d"]; + /// v.swap(1, 3); + /// assert!(v == ["a", "d", "c", "b"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn binary_search_by(&self, f: F) -> Result where F: FnMut(&T) -> Ordering { - core_slice::SliceExt::binary_search_by(self, f) + pub fn swap(&mut self, a: usize, b: usize) { + core_slice::SliceExt::swap(self, a, b) } - /// Returns the number of elements in the slice. + /// Reverse the order of elements in a slice, in place. /// /// # Example /// - /// ``` - /// let a = [1, 2, 3]; - /// assert_eq!(a.len(), 3); + /// ```rust + /// let mut v = [1, 2, 3]; + /// v.reverse(); + /// assert!(v == [3, 2, 1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn len(&self) -> usize { - core_slice::SliceExt::len(self) + pub fn reverse(&mut self) { + core_slice::SliceExt::reverse(self) } - /// Returns true if the slice has a length of 0 + /// Returns an iterator over the slice. + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn iter(&self) -> Iter { + core_slice::SliceExt::iter(self) + } + + /// Returns an iterator that allows modifying each value + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn iter_mut(&mut self) -> IterMut { + core_slice::SliceExt::iter_mut(self) + } + + /// 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 /// - /// ``` - /// let a = [1, 2, 3]; - /// assert!(!a.is_empty()); + /// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`, + /// `[3,4]`): + /// + /// ```rust + /// let v = &[1, 2, 3, 4]; + /// for win in v.windows(2) { + /// println!("{:?}", win); + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn is_empty(&self) -> bool { - core_slice::SliceExt::is_empty(self) + pub fn windows(&self, size: usize) -> Windows { + core_slice::SliceExt::windows(self, size) } - /// Returns a mutable reference to the element at the given index, - /// or `None` if the index is out of bounds + /// 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 = &[1, 2, 3, 4, 5]; + /// for win in v.chunks(2) { + /// println!("{:?}", win); + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { - core_slice::SliceExt::get_mut(self, index) + pub fn chunks(&self, size: usize) -> Chunks { + core_slice::SliceExt::chunks(self, size) } - /// Returns an iterator that allows modifying each value + /// 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(feature = "rust1", since = "1.0.0")] #[inline] - pub fn iter_mut(&mut self) -> IterMut { - core_slice::SliceExt::iter_mut(self) + pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut { + core_slice::SliceExt::chunks_mut(self, chunk_size) } - /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty + /// 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`. + /// + /// # Examples + /// + /// ``` + /// let v = [10, 40, 30, 20, 50]; + /// let (v1, v2) = v.split_at(2); + /// assert_eq!([10, 40], v1); + /// assert_eq!([30, 20, 50], v2); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn first_mut(&mut self) -> Option<&mut T> { - core_slice::SliceExt::first_mut(self) - } - - /// Returns all but the first element of a mutable slice - #[unstable(feature = "collections", - reason = "likely to be renamed or removed")] - #[inline] - pub fn tail_mut(&mut self) -> &mut [T] { - core_slice::SliceExt::tail_mut(self) + pub fn split_at(&self, mid: usize) -> (&[T], &[T]) { + core_slice::SliceExt::split_at(self, mid) } - /// Returns all but the last element of a mutable slice - #[unstable(feature = "collections", - reason = "likely to be renamed or removed")] + /// 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 = [1, 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 == [1, 2, 3, 4, 5, 6]); + /// } + /// + /// { + /// let (left, right) = v.split_at_mut(2); + /// assert!(left == [1, 2]); + /// assert!(right == [3, 4, 5, 6]); + /// } + /// + /// { + /// let (left, right) = v.split_at_mut(6); + /// assert!(left == [1, 2, 3, 4, 5, 6]); + /// assert!(right == []); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn init_mut(&mut self) -> &mut [T] { - core_slice::SliceExt::init_mut(self) + pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { + core_slice::SliceExt::split_at_mut(self, mid) } - /// Returns a mutable pointer to the last item in the slice. + /// Returns an iterator over subslices separated by elements that match + /// `pred`. The matched element is not contained in the subslices. + /// + /// # Examples + /// + /// Print the slice split by numbers divisible by 3 (i.e. `[10, 40]`, + /// `[20]`, `[50]`): + /// + /// ``` + /// let v = [10, 40, 30, 20, 60, 50]; + /// for group in v.split(|num| *num % 3 == 0) { + /// println!("{:?}", group); + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn last_mut(&mut self) -> Option<&mut T> { - core_slice::SliceExt::last_mut(self) + pub fn split(&self, pred: F) -> Split where F: FnMut(&T) -> bool { + core_slice::SliceExt::split(self, pred) } /// Returns an iterator over mutable subslices separated by elements that @@ -628,6 +600,30 @@ impl [T] { core_slice::SliceExt::split_mut(self, pred) } + /// Returns an iterator over subslices separated by elements that match + /// `pred`, limited to returning at most `n` items. The matched element is + /// not contained in the subslices. + /// + /// The last element returned, if any, will contain the remainder of the + /// slice. + /// + /// # Examples + /// + /// Print the slice split once by numbers divisible by 3 (i.e. `[10, 40]`, + /// `[20, 60, 50]`): + /// + /// ``` + /// let v = [10, 40, 30, 20, 60, 50]; + /// for group in v.splitn(2, |num| *num % 3 == 0) { + /// println!("{:?}", group); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn splitn(&self, n: usize, pred: F) -> SplitN where F: FnMut(&T) -> bool { + core_slice::SliceExt::splitn(self, n, pred) + } + /// Returns an iterator over subslices separated by elements that match /// `pred`, limited to returning at most `n` items. The matched element is /// not contained in the subslices. @@ -641,6 +637,31 @@ impl [T] { core_slice::SliceExt::splitn_mut(self, n, pred) } + /// Returns an iterator over subslices separated by elements that match + /// `pred` limited to returning at most `n` items. This starts at the end of + /// the slice and works backwards. The matched element is not contained in + /// the subslices. + /// + /// The last element returned, if any, will contain the remainder of the + /// slice. + /// + /// # Examples + /// + /// Print the slice split once, starting from the end, by numbers divisible + /// by 3 (i.e. `[50]`, `[10, 40, 30, 20]`): + /// + /// ``` + /// let v = [10, 40, 30, 20, 60, 50]; + /// for group in v.rsplitn(2, |num| *num % 3 == 0) { + /// println!("{:?}", group); + /// } + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn rsplitn(&self, n: usize, pred: F) -> RSplitN where F: FnMut(&T) -> bool { + core_slice::SliceExt::rsplitn(self, n, pred) + } + /// Returns an iterator over subslices separated by elements that match /// `pred` limited to returning at most `n` items. This starts at the end of /// the slice and works backwards. The matched element is not contained in @@ -655,125 +676,167 @@ impl [T] { core_slice::SliceExt::rsplitn_mut(self, n, pred) } - /// 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`. + /// Returns true if the slice contains an element with the given value. /// - /// # Panics + /// # Examples /// - /// Panics if `chunk_size` is 0. + /// ``` + /// let v = [10, 40, 30]; + /// assert!(v.contains(&30)); + /// assert!(!v.contains(&50)); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut { - core_slice::SliceExt::chunks_mut(self, chunk_size) + pub fn contains(&self, x: &T) -> bool where T: PartialEq { + core_slice::SliceExt::contains(self, x) } - /// Swaps two elements in a slice. + /// Returns true if `needle` is a prefix of the slice. /// - /// # Arguments + /// # Examples /// - /// * a - The index of the first element - /// * b - The index of the second element + /// ``` + /// let v = [10, 40, 30]; + /// assert!(v.starts_with(&[10])); + /// assert!(v.starts_with(&[10, 40])); + /// assert!(!v.starts_with(&[50])); + /// assert!(!v.starts_with(&[10, 50])); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { + core_slice::SliceExt::starts_with(self, needle) + } + + /// Returns true if `needle` is a suffix of the slice. /// - /// # Panics + /// # Examples /// - /// Panics if `a` or `b` are out of bounds. + /// ``` + /// let v = [10, 40, 30]; + /// assert!(v.ends_with(&[30])); + /// assert!(v.ends_with(&[40, 30])); + /// assert!(!v.ends_with(&[50])); + /// assert!(!v.ends_with(&[50, 30])); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { + core_slice::SliceExt::ends_with(self, needle) + } + + /// Find the first index containing a matching value. + #[unstable(feature = "collections")] + pub fn position_elem(&self, t: &T) -> Option where T: PartialEq { + core_slice::SliceExt::position_elem(self, t) + } + + /// Find the last index containing a matching value. + #[unstable(feature = "collections")] + pub fn rposition_elem(&self, t: &T) -> Option where T: PartialEq { + core_slice::SliceExt::rposition_elem(self, t) + } + + /// 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 mut v = ["a", "b", "c", "d"]; - /// v.swap(1, 3); - /// assert!(v == ["a", "d", "c", "b"]); + /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; + /// + /// 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(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn swap(&mut self, a: usize, b: usize) { - core_slice::SliceExt::swap(self, a, b) + pub fn binary_search(&self, x: &T) -> Result where T: Ord { + core_slice::SliceExt::binary_search(self, x) } - /// 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). + /// Binary search a sorted slice with a comparator function. /// - /// # Panics + /// 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. /// - /// Panics if `mid > len`. + /// 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 /// - /// ```rust - /// let mut v = [1, 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 == [1, 2, 3, 4, 5, 6]); - /// } + /// 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]`. /// - /// { - /// let (left, right) = v.split_at_mut(2); - /// assert!(left == [1, 2]); - /// assert!(right == [3, 4, 5, 6]); - /// } + /// ```rust + /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; /// - /// { - /// let (left, right) = v.split_at_mut(6); - /// assert!(left == [1, 2, 3, 4, 5, 6]); - /// assert!(right == []); - /// } + /// 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(feature = "rust1", since = "1.0.0")] #[inline] - pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { - core_slice::SliceExt::split_at_mut(self, mid) + pub fn binary_search_by(&self, f: F) -> Result where F: FnMut(&T) -> Ordering { + core_slice::SliceExt::binary_search_by(self, f) } - /// Reverse the order of elements in a slice, in place. + /// Sorts the slice, in place. /// - /// # Example + /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. + /// + /// # Examples /// /// ```rust - /// let mut v = [1, 2, 3]; - /// v.reverse(); - /// assert!(v == [3, 2, 1]); + /// let mut v = [-5, 4, 1, -3, 2]; + /// + /// v.sort(); + /// assert!(v == [-5, -3, 1, 2, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn reverse(&mut self) { - core_slice::SliceExt::reverse(self) - } - - /// Returns an unsafe mutable pointer to the element in index - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { - core_slice::SliceExt::get_unchecked_mut(self, index) + pub fn sort(&mut self) where T: Ord { + self.sort_by(|a, b| a.cmp(b)) } - /// Returns an unsafe mutable pointer to the slice's buffer. + /// Sorts the slice, in place, using `compare` to compare + /// elements. /// - /// The caller must ensure that the slice outlives the pointer this - /// function returns, or else it will end up pointing to garbage. + /// This sort is `O(n log n)` worst-case and stable, but allocates + /// approximately `2 * n`, where `n` is the length of `self`. /// - /// Modifying the slice may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut T { - core_slice::SliceExt::as_mut_ptr(self) - } - - /// Copies `self` into a new `Vec`. + /// # Examples + /// + /// ```rust + /// let mut v = [5, 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(feature = "rust1", since = "1.0.0")] #[inline] - pub fn to_vec(&self) -> Vec where T: Clone { - // NB see hack module in this file - hack::to_vec(self) + pub fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { + merge_sort(self, compare) } /// Creates an iterator that yields every possible permutation of the @@ -809,74 +872,6 @@ impl [T] { hack::permutations(self) } - /// 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 - /// # #![feature(collections)] - /// let mut dst = [0, 0, 0]; - /// let src = [1, 2]; - /// - /// assert!(dst.clone_from_slice(&src) == 2); - /// assert!(dst == [1, 2, 0]); - /// - /// let src2 = [3, 4, 5, 6]; - /// assert!(dst.clone_from_slice(&src2) == 3); - /// assert!(dst == [3, 4, 5]); - /// ``` - #[unstable(feature = "collections")] - pub fn clone_from_slice(&mut self, src: &[T]) -> usize where T: Clone { - core_slice::SliceExt::clone_from_slice(self, src) - } - - /// Sorts the slice, in place. - /// - /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. - /// - /// # Examples - /// - /// ```rust - /// let mut v = [-5, 4, 1, -3, 2]; - /// - /// v.sort(); - /// assert!(v == [-5, -3, 1, 2, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn sort(&mut self) where T: Ord { - self.sort_by(|a, b| a.cmp(b)) - } - - /// 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 = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; - /// - /// 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(feature = "rust1", since = "1.0.0")] - pub fn binary_search(&self, x: &T) -> Result where T: Ord { - core_slice::SliceExt::binary_search(self, x) - } - /// Mutates the slice to the next lexicographic permutation. /// /// Returns `true` if successful and `false` if the slice is at the @@ -923,62 +918,67 @@ impl [T] { core_slice::SliceExt::prev_permutation(self) } - /// Find the first index containing a matching value. - #[unstable(feature = "collections")] - pub fn position_elem(&self, t: &T) -> Option where T: PartialEq { - core_slice::SliceExt::position_elem(self, t) - } - - /// Find the last index containing a matching value. - #[unstable(feature = "collections")] - pub fn rposition_elem(&self, t: &T) -> Option where T: PartialEq { - core_slice::SliceExt::rposition_elem(self, t) - } - - /// Returns true if the slice contains an element with the given value. + /// 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. /// - /// # Examples + /// # Example /// - /// ``` - /// let v = [10, 40, 30]; - /// assert!(v.contains(&30)); - /// assert!(!v.contains(&50)); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn contains(&self, x: &T) -> bool where T: PartialEq { - core_slice::SliceExt::contains(self, x) - } - - /// Returns true if `needle` is a prefix of the slice. + /// ```rust + /// # #![feature(collections)] + /// let mut dst = [0, 0, 0]; + /// let src = [1, 2]; /// - /// # Examples + /// assert!(dst.clone_from_slice(&src) == 2); + /// assert!(dst == [1, 2, 0]); /// + /// let src2 = [3, 4, 5, 6]; + /// assert!(dst.clone_from_slice(&src2) == 3); + /// assert!(dst == [3, 4, 5]); /// ``` - /// let v = [10, 40, 30]; - /// assert!(v.starts_with(&[10])); - /// assert!(v.starts_with(&[10, 40])); - /// assert!(!v.starts_with(&[50])); - /// assert!(!v.starts_with(&[10, 50])); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { - core_slice::SliceExt::starts_with(self, needle) + #[unstable(feature = "collections")] + pub fn clone_from_slice(&mut self, src: &[T]) -> usize where T: Clone { + core_slice::SliceExt::clone_from_slice(self, src) } - /// Returns true if `needle` is a suffix of the slice. + /// 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 + /// # #![feature(collections)] + /// let mut a = [1, 2, 3, 4, 5]; + /// let b = vec![6, 7, 8]; + /// let num_moved = a.move_from(b, 0, 3); + /// assert_eq!(num_moved, 3); + /// assert!(a == [6, 7, 8, 4, 5]); /// ``` - /// let v = [10, 40, 30]; - /// assert!(v.ends_with(&[30])); - /// assert!(v.ends_with(&[40, 30])); - /// assert!(!v.ends_with(&[50])); - /// assert!(!v.ends_with(&[50, 30])); - /// ``` + #[unstable(feature = "collections", + reason = "uncertain about this API approach")] + #[inline] + pub fn move_from(&mut self, mut src: Vec, start: usize, end: usize) -> usize { + for (a, b) in self.iter_mut().zip(src[start .. end].iter_mut()) { + mem::swap(a, b); + } + cmp::min(self.len(), end-start) + } + + /// Copies `self` into a new `Vec`. #[stable(feature = "rust1", since = "1.0.0")] - pub fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { - core_slice::SliceExt::ends_with(self, needle) + #[inline] + pub fn to_vec(&self) -> Vec where T: Clone { + // NB see hack module in this file + hack::to_vec(self) } /// Converts `self` into a vector without clones or allocation.