From cc5ecaf76589a83e40136e31d211246204767465 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 2 Jan 2015 09:12:27 -0500 Subject: [PATCH] merge `*SliceExt` traits, use assoc types in `SliceExt`, `Raw[Mut]Ptr` --- src/libcollections/lib.rs | 4 +- src/libcollections/slice.rs | 499 +++++++++++++++++---------------- src/libcollections/string.rs | 3 +- src/libcollections/vec.rs | 4 +- src/libcore/prelude.rs | 1 - src/libcore/ptr.rs | 24 +- src/libcore/slice.rs | 319 ++++++++++----------- src/libstd/c_str.rs | 2 +- src/libstd/io/comm_adapters.rs | 2 +- src/libstd/io/mem.rs | 2 +- src/libstd/io/mod.rs | 2 +- src/libstd/io/net/ip.rs | 2 +- src/libstd/lib.rs | 1 + src/libstd/macros.rs | 3 +- src/libstd/num/strconv.rs | 2 +- src/libstd/os.rs | 1 - src/libstd/path/mod.rs | 3 +- src/libstd/path/posix.rs | 5 +- src/libstd/path/windows.rs | 2 +- src/libstd/prelude.rs | 4 +- 20 files changed, 440 insertions(+), 445 deletions(-) diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index cbd8d4955b2..09cff4bc5ad 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -25,6 +25,7 @@ #![feature(macro_rules, default_type_params, phase, globs)] #![feature(unsafe_destructor, slicing_syntax)] #![feature(unboxed_closures)] +#![feature(associated_types)] #![no_std] #[phase(plugin, link)] extern crate core; @@ -120,7 +121,6 @@ mod prelude { pub use core::result::Result::{Ok, Err}; // in core and collections (may differ). - pub use slice::{PartialEqSliceExt, OrdSliceExt}; pub use slice::{AsSlice, SliceExt}; pub use str::{from_str, Str, StrExt}; @@ -129,7 +129,7 @@ mod prelude { pub use unicode::char::UnicodeChar; // from collections. - pub use slice::{CloneSliceExt, SliceConcatExt}; + pub use slice::SliceConcatExt; pub use str::IntoMaybeOwned; pub use string::{String, ToString}; pub use vec::Vec; diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 61111d96bd0..ac271e75ea1 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -96,7 +96,7 @@ use core::mem; use core::ops::{FnMut,SliceMut}; use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option}; -use core::prelude::{Ord, Ordering, PtrExt, Some, range, IteratorCloneExt, Result}; +use core::prelude::{Ord, Ordering, PartialEq, PtrExt, Some, range, IteratorCloneExt, Result}; use core::ptr; use core::slice as core_slice; use self::Direction::*; @@ -104,7 +104,7 @@ use vec::Vec; pub use core::slice::{Chunks, AsSlice, Windows}; -pub use core::slice::{Iter, IterMut, PartialEqSliceExt}; +pub use core::slice::{Iter, IterMut}; pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split}; pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut}; pub use core::slice::{bytes, mut_ref_slice, ref_slice}; @@ -122,7 +122,9 @@ /// Allocating extension methods for slices. #[unstable = "needs associated types, may merge with other traits"] -pub trait SliceExt for Sized? { +pub trait SliceExt for Sized? { + type Item; + /// Sorts the slice, in place, using `compare` to compare /// elements. /// @@ -141,7 +143,7 @@ pub trait SliceExt for Sized? { /// assert!(v == [5, 4, 3, 2, 1]); /// ``` #[stable] - fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering; + fn sort_by(&mut self, compare: F) where F: FnMut(&Self::Item, &Self::Item) -> Ordering; /// Consumes `src` and moves as many elements as it can into `self` /// from the range [start,end). @@ -165,7 +167,7 @@ pub trait SliceExt for Sized? { /// 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; + fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; /// Returns a subslice spanning the interval [`start`, `end`). /// @@ -174,7 +176,7 @@ pub trait SliceExt for Sized? { /// /// Slicing with `start` equal to `end` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice(&self, start: uint, end: uint) -> &[T]; + fn slice(&self, start: uint, end: uint) -> &[Self::Item]; /// Returns a subslice from `start` to the end of the slice. /// @@ -182,7 +184,7 @@ pub trait SliceExt for Sized? { /// /// Slicing from `self.len()` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_from(&self, start: uint) -> &[T]; + fn slice_from(&self, start: uint) -> &[Self::Item]; /// Returns a subslice from the start of the slice to `end`. /// @@ -190,7 +192,7 @@ pub trait SliceExt for Sized? { /// /// Slicing to `0` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_to(&self, end: uint) -> &[T]; + fn slice_to(&self, end: uint) -> &[Self::Item]; /// Divides one slice into two at an index. /// @@ -200,32 +202,32 @@ pub trait SliceExt for Sized? { /// /// Panics if `mid > len`. #[stable] - fn split_at(&self, mid: uint) -> (&[T], &[T]); + fn split_at(&self, mid: uint) -> (&[Self::Item], &[Self::Item]); /// Returns an iterator over the slice #[stable] - fn iter(&self) -> Iter; + 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; + fn split(&self, pred: F) -> Split + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over subslices separated by elements that match /// `pred`, limited to splitting at most `n` times. The matched element is /// not contained in the subslices. #[stable] - fn splitn(&self, n: uint, pred: F) -> SplitN - where F: FnMut(&T) -> bool; + fn splitn(&self, n: uint, pred: F) -> SplitN + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over subslices separated by elements that match /// `pred` limited to splitting at most `n` times. This starts at the end of /// the slice and works backwards. The matched element is not contained in /// the subslices. #[stable] - fn rsplitn(&self, n: uint, pred: F) -> RSplitN - where F: FnMut(&T) -> bool; + fn rsplitn(&self, n: uint, pred: F) -> RSplitN + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over all contiguous windows of length /// `size`. The windows overlap. If the slice is shorter than @@ -247,7 +249,7 @@ fn rsplitn(&self, n: uint, pred: F) -> RSplitN /// } /// ``` #[stable] - fn windows(&self, size: uint) -> Windows; + 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 @@ -270,41 +272,41 @@ fn rsplitn(&self, n: uint, pred: F) -> RSplitN /// } /// ``` #[stable] - fn chunks(&self, size: uint) -> Chunks; + 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>; + fn get(&self, index: uint) -> Option<&Self::Item>; /// Returns the first element of a slice, or `None` if it is empty. #[stable] - fn first(&self) -> Option<&T>; + fn first(&self) -> Option<&Self::Item>; /// Deprecated: renamed to `first`. #[deprecated = "renamed to `first`"] - fn head(&self) -> Option<&T> { self.first() } + fn head(&self) -> Option<&Self::Item> { self.first() } /// Returns all but the first element of a slice. #[experimental = "likely to be renamed"] - fn tail(&self) -> &[T]; + fn tail(&self) -> &[Self::Item]; /// Returns all but the last element of a slice. #[experimental = "likely to be renamed"] - fn init(&self) -> &[T]; + fn init(&self) -> &[Self::Item]; /// Returns the last element of a slice, or `None` if it is empty. #[stable] - fn last(&self) -> Option<&T>; + fn last(&self) -> Option<&Self::Item>; /// Returns a pointer to the element at the given index, without doing /// bounds checking. #[stable] - unsafe fn get_unchecked(&self, index: uint) -> &T; + unsafe fn get_unchecked(&self, index: uint) -> &Self::Item; /// Deprecated: renamed to `get_unchecked`. #[deprecated = "renamed to get_unchecked"] - unsafe fn unsafe_get(&self, index: uint) -> &T { + unsafe fn unsafe_get(&self, index: uint) -> &Self::Item { self.get_unchecked(index) } @@ -316,7 +318,7 @@ unsafe fn unsafe_get(&self, index: uint) -> &T { /// Modifying the slice may cause its buffer to be reallocated, which /// would also make any pointers to it invalid. #[stable] - fn as_ptr(&self) -> *const T; + fn as_ptr(&self) -> *const Self::Item; /// Binary search a sorted slice with a comparator function. /// @@ -352,7 +354,7 @@ unsafe fn unsafe_get(&self, index: uint) -> &T { /// ``` #[stable] fn binary_search_by(&self, f: F) -> Result where - F: FnMut(&T) -> Ordering; + F: FnMut(&Self::Item) -> Ordering; /// Return the number of elements in the slice /// @@ -379,12 +381,12 @@ 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>; + fn get_mut(&mut self, index: uint) -> Option<&mut Self::Item>; /// Work with `self` as a mut slice. /// Primarily intended for getting a &mut [T] from a [T; N]. #[stable] - fn as_mut_slice(&mut self) -> &mut [T]; + fn as_mut_slice(&mut self) -> &mut [Self::Item]; /// Returns a mutable subslice spanning the interval [`start`, `end`). /// @@ -393,7 +395,7 @@ fn is_empty(&self) -> bool { self.len() == 0 } /// /// Slicing with `start` equal to `end` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T]; + fn slice_mut(&mut self, start: uint, end: uint) -> &mut [Self::Item]; /// Returns a mutable subslice from `start` to the end of the slice. /// @@ -401,7 +403,7 @@ fn is_empty(&self) -> bool { self.len() == 0 } /// /// Slicing from `self.len()` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_from_mut(&mut self, start: uint) -> &mut [T]; + fn slice_from_mut(&mut self, start: uint) -> &mut [Self::Item]; /// Returns a mutable subslice from the start of the slice to `end`. /// @@ -409,54 +411,54 @@ fn is_empty(&self) -> bool { self.len() == 0 } /// /// Slicing to `0` yields an empty slice. #[experimental = "will be replaced by slice syntax"] - fn slice_to_mut(&mut self, end: uint) -> &mut [T]; + fn slice_to_mut(&mut self, end: uint) -> &mut [Self::Item]; /// Returns an iterator that allows modifying each value #[stable] - fn iter_mut(&mut self) -> IterMut; + 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>; + fn first_mut(&mut self) -> Option<&mut Self::Item>; /// Depreated: renamed to `first_mut`. #[deprecated = "renamed to first_mut"] - fn head_mut(&mut self) -> Option<&mut T> { + fn head_mut(&mut self) -> Option<&mut Self::Item> { self.first_mut() } /// Returns all but the first element of a mutable slice #[experimental = "likely to be renamed or removed"] - fn tail_mut(&mut self) -> &mut [T]; + fn tail_mut(&mut self) -> &mut [Self::Item]; /// Returns all but the last element of a mutable slice #[experimental = "likely to be renamed or removed"] - fn init_mut(&mut self) -> &mut [T]; + fn init_mut(&mut self) -> &mut [Self::Item]; /// Returns a mutable pointer to the last item in the slice. #[stable] - fn last_mut(&mut self) -> Option<&mut T>; + fn last_mut(&mut self) -> Option<&mut Self::Item>; /// Returns an iterator over mutable subslices separated by elements that /// match `pred`. The matched element is not contained in the subslices. #[stable] - fn split_mut(&mut self, pred: F) -> SplitMut - where F: FnMut(&T) -> bool; + fn split_mut(&mut self, pred: F) -> SplitMut + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over subslices separated by elements that match /// `pred`, limited to splitting at most `n` times. The matched element is /// not contained in the subslices. #[stable] - fn splitn_mut(&mut self, n: uint, pred: F) -> SplitNMut - where F: FnMut(&T) -> bool; + fn splitn_mut(&mut self, n: uint, pred: F) -> SplitNMut + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over subslices separated by elements that match /// `pred` limited to splitting at most `n` times. This starts at the end of /// the slice and works backwards. The matched element is not contained in /// the subslices. #[stable] - fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut - where F: FnMut(&T) -> bool; + fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut + where F: FnMut(&Self::Item) -> bool; /// Returns an iterator over `chunk_size` elements of the slice at a time. /// The chunks are mutable and do not overlap. If `chunk_size` does @@ -467,7 +469,7 @@ fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut /// /// Panics if `chunk_size` is 0. #[stable] - fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut; + fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut; /// Swaps two elements in a slice. /// @@ -525,7 +527,7 @@ fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut /// } /// ``` #[stable] - fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]); + fn split_at_mut(&mut self, mid: uint) -> (&mut [Self::Item], &mut [Self::Item]); /// Reverse the order of elements in a slice, in place. /// @@ -541,11 +543,11 @@ fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut /// Returns an unsafe mutable pointer to the element in index #[stable] - unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T; + unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut Self::Item; /// Deprecated: renamed to `get_unchecked_mut`. #[deprecated = "renamed to get_unchecked_mut"] - unsafe fn unchecked_mut(&mut self, index: uint) -> &mut T { + unsafe fn unchecked_mut(&mut self, index: uint) -> &mut Self::Item { self.get_unchecked_mut(index) } @@ -558,11 +560,179 @@ unsafe fn unchecked_mut(&mut self, index: uint) -> &mut T { /// would also make any pointers to it invalid. #[inline] #[stable] - fn as_mut_ptr(&mut self) -> *mut T; + fn as_mut_ptr(&mut self) -> *mut Self::Item; + + /// Copies `self` into a new `Vec`. + #[stable] + fn to_vec(&self) -> Vec where Self::Item: Clone; + + /// Deprecated: use `iter().cloned().partition(f)` instead. + #[deprecated = "use iter().cloned().partition(f) instead"] + fn partitioned(&self, f: F) -> (Vec, Vec) where + Self::Item: Clone, + F: FnMut(&Self::Item) -> bool; + + /// Creates an iterator that yields every possible permutation of the + /// vector in succession. + /// + /// # Examples + /// + /// ```rust + /// let v = [1i, 2, 3]; + /// let mut perms = v.permutations(); + /// + /// for p in perms { + /// println!("{}", p); + /// } + /// ``` + /// + /// Iterating through permutations one by one. + /// + /// ```rust + /// let v = [1i, 2, 3]; + /// let mut perms = v.permutations(); + /// + /// assert_eq!(Some(vec![1i, 2, 3]), perms.next()); + /// assert_eq!(Some(vec![1i, 3, 2]), perms.next()); + /// assert_eq!(Some(vec![3i, 1, 2]), perms.next()); + /// ``` + #[unstable] + fn permutations(&self) -> Permutations where Self::Item: Clone; + + /// Copies as many elements from `src` as it can into `self` (the + /// shorter of `self.len()` and `src.len()`). Returns the number + /// of elements copied. + /// + /// # Example + /// + /// ```rust + /// let mut dst = [0i, 0, 0]; + /// let src = [1i, 2]; + /// + /// assert!(dst.clone_from_slice(&src) == 2); + /// assert!(dst == [1, 2, 0]); + /// + /// let src2 = [3i, 4, 5, 6]; + /// assert!(dst.clone_from_slice(&src2) == 3); + /// assert!(dst == [3i, 4, 5]); + /// ``` + #[experimental] + fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone; + + /// Sorts the slice, in place. + /// + /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. + /// + /// # Examples + /// + /// ```rust + /// let mut v = [-5i, 4, 1, -3, 2]; + /// + /// v.sort(); + /// assert!(v == [-5i, -3, 1, 2, 4]); + /// ``` + #[stable] + fn sort(&mut self) where Self::Item: Ord; + + /// Binary search a sorted slice for a given element. + /// + /// If the value is found then `Ok` is returned, containing the + /// index of the matching element; if the value is not found then + /// `Err` is returned, containing the index where a matching + /// element could be inserted while maintaining sorted order. + /// + /// # Example + /// + /// Looks up a series of four elements. The first is found, with a + /// uniquely determined position; the second and third are not + /// found; the fourth could match any position in `[1,4]`. + /// + /// ```rust + /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; + /// let s = s.as_slice(); + /// + /// assert_eq!(s.binary_search(&13), Ok(9)); + /// assert_eq!(s.binary_search(&4), Err(7)); + /// assert_eq!(s.binary_search(&100), Err(13)); + /// let r = s.binary_search(&1); + /// assert!(match r { Ok(1...4) => true, _ => false, }); + /// ``` + #[stable] + fn binary_search(&self, x: &Self::Item) -> Result where Self::Item: Ord; + + /// Deprecated: use `binary_search` instead. + #[deprecated = "use binary_search instead"] + fn binary_search_elem(&self, x: &Self::Item) -> Result where Self::Item: Ord { + self.binary_search(x) + } + + /// Mutates the slice to the next lexicographic permutation. + /// + /// Returns `true` if successful and `false` if the slice is at the + /// last-ordered permutation. + /// + /// # Example + /// + /// ```rust + /// let v: &mut [_] = &mut [0i, 1, 2]; + /// v.next_permutation(); + /// let b: &mut [_] = &mut [0i, 2, 1]; + /// assert!(v == b); + /// v.next_permutation(); + /// let b: &mut [_] = &mut [1i, 0, 2]; + /// assert!(v == b); + /// ``` + #[unstable = "uncertain if this merits inclusion in std"] + fn next_permutation(&mut self) -> bool where Self::Item: Ord; + + /// Mutates the slice to the previous lexicographic permutation. + /// + /// Returns `true` if successful and `false` if the slice is at the + /// first-ordered permutation. + /// + /// # Example + /// + /// ```rust + /// let v: &mut [_] = &mut [1i, 0, 2]; + /// v.prev_permutation(); + /// let b: &mut [_] = &mut [0i, 2, 1]; + /// assert!(v == b); + /// v.prev_permutation(); + /// let b: &mut [_] = &mut [0i, 1, 2]; + /// assert!(v == b); + /// ``` + #[unstable = "uncertain if this merits inclusion in std"] + fn prev_permutation(&mut self) -> bool where Self::Item: Ord; + + /// Find the first index containing a matching value. + #[experimental] + fn position_elem(&self, t: &Self::Item) -> Option where Self::Item: PartialEq; + + /// Find the last index containing a matching value. + #[experimental] + fn rposition_elem(&self, t: &Self::Item) -> Option where Self::Item: PartialEq; + + /// Return true if the slice contains an element with the given value. + #[stable] + fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq; + + /// Returns true if `needle` is a prefix of the slice. + #[stable] + fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + /// Returns true if `needle` is a suffix of the slice. + #[stable] + fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + /// Convert `self` into a vector without clones or allocation. + #[experimental] + fn into_vec(self: Box) -> Vec; } #[unstable = "trait is unstable"] -impl SliceExt for [T] { +impl SliceExt for [T] { + type Item = T; + #[inline] fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { merge_sort(self, compare) @@ -777,96 +947,10 @@ unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T { fn as_mut_ptr(&mut self) -> *mut T { core_slice::SliceExt::as_mut_ptr(self) } -} - -//////////////////////////////////////////////////////////////////////////////// -// Extension traits for slices over specifc kinds of data -//////////////////////////////////////////////////////////////////////////////// - -/// 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()); - /// ``` - #[unstable] - 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 { + fn to_vec(&self) -> Vec where T: Clone { let mut vector = Vec::with_capacity(self.len()); vector.push_all(self); vector @@ -874,132 +958,71 @@ fn to_vec(&self) -> Vec { #[inline] - fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { + fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool, T: Clone { self.iter().cloned().partition(f) } /// Returns an iterator over all permutations of a vector. - fn permutations(&self) -> Permutations { + fn permutations(&self) -> Permutations where T: Clone { 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) + fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone { + core_slice::SliceExt::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); + #[inline] + 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 = [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; + fn binary_search(&self, x: &T) -> Result where T: Ord { + core_slice::SliceExt::binary_search(self, x) + } - /// Deprecated: use `binary_search` instead. - #[deprecated = "use binary_search instead"] - fn binary_search_elem(&self, x: &T) -> Result { - self.binary_search(x) + fn next_permutation(&mut self) -> bool where T: Ord { + core_slice::SliceExt::next_permutation(self) } - /// Mutates the slice to the next lexicographic permutation. - /// - /// Returns `true` if successful and `false` if the slice is at the - /// last-ordered permutation. - /// - /// # Example - /// - /// ```rust - /// let v: &mut [_] = &mut [0i, 1, 2]; - /// v.next_permutation(); - /// let b: &mut [_] = &mut [0i, 2, 1]; - /// assert!(v == b); - /// v.next_permutation(); - /// let b: &mut [_] = &mut [1i, 0, 2]; - /// assert!(v == b); - /// ``` - #[unstable = "uncertain if this merits inclusion in std"] - fn next_permutation(&mut self) -> bool; + fn prev_permutation(&mut self) -> bool where T: Ord { + core_slice::SliceExt::prev_permutation(self) + } - /// Mutates the slice to the previous lexicographic permutation. - /// - /// Returns `true` if successful and `false` if the slice is at the - /// first-ordered permutation. - /// - /// # Example - /// - /// ```rust - /// let v: &mut [_] = &mut [1i, 0, 2]; - /// v.prev_permutation(); - /// let b: &mut [_] = &mut [0i, 2, 1]; - /// assert!(v == b); - /// v.prev_permutation(); - /// let b: &mut [_] = &mut [0i, 1, 2]; - /// assert!(v == b); - /// ``` - #[unstable = "uncertain if this merits inclusion in std"] - fn prev_permutation(&mut self) -> bool; -} + fn position_elem(&self, t: &T) -> Option where T: PartialEq { + core_slice::SliceExt::position_elem(self, t) + } -#[unstable = "trait is unstable"] -impl OrdSliceExt for [T] { - #[inline] - fn sort(&mut self) { - self.sort_by(|a, b| a.cmp(b)) + fn rposition_elem(&self, t: &T) -> Option where T: PartialEq { + core_slice::SliceExt::rposition_elem(self, t) } - fn binary_search(&self, x: &T) -> Result { - core_slice::OrdSliceExt::binary_search(self, x) + fn contains(&self, x: &T) -> bool where T: PartialEq { + core_slice::SliceExt::contains(self, x) } - fn next_permutation(&mut self) -> bool { - core_slice::OrdSliceExt::next_permutation(self) + fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { + core_slice::SliceExt::starts_with(self, needle) } - fn prev_permutation(&mut self) -> bool { - core_slice::OrdSliceExt::prev_permutation(self) + fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { + core_slice::SliceExt::ends_with(self, needle) + } + + fn into_vec(mut self: Box) -> Vec { + unsafe { + let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len()); + mem::forget(self); + xs + } } } +//////////////////////////////////////////////////////////////////////////////// +// Extension traits for slices over specifc kinds of data +//////////////////////////////////////////////////////////////////////////////// #[unstable = "U should be an associated type"] /// An extension trait for concatenating slices pub trait SliceConcatExt for Sized? { @@ -1419,7 +1442,7 @@ mod tests { use std::boxed::Box; use prelude::{Some, None, range, Vec, ToString, Clone, Greater, Less, Equal}; use prelude::{SliceExt, Iterator, IteratorExt, DoubleEndedIteratorExt}; - use prelude::{OrdSliceExt, CloneSliceExt, PartialEqSliceExt, AsSlice}; + use prelude::AsSlice; use prelude::{RandomAccessIterator, Ord, SliceConcatExt}; use core::cell::Cell; use core::default::Default; diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 37a6e690f5d..b69db8b00b5 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -27,7 +27,6 @@ use unicode::str as unicode_str; use unicode::str::Utf16Item; -use slice::CloneSliceExt; use str::{mod, CharRange, FromStr, Utf8Error}; use vec::{DerefVec, Vec, as_vec}; @@ -94,7 +93,7 @@ pub fn with_capacity(capacity: uint) -> String { #[inline] #[experimental = "needs investigation to see if to_string() can match perf"] pub fn from_str(string: &str) -> String { - String { vec: string.as_bytes().to_vec() } + String { vec: ::slice::SliceExt::to_vec(string.as_bytes()) } } /// Returns the vector as a string buffer, if possible, taking care not to diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a1952352bad..ce0519a2395 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -63,8 +63,6 @@ use core::raw::Slice as RawSlice; use core::uint; -use slice::CloneSliceExt; - /// A growable list type, written `Vec` but pronounced 'vector.' /// /// # Examples @@ -1218,7 +1216,7 @@ unsafe fn dealloc(ptr: *mut T, len: uint) { #[unstable] impl Clone for Vec { - fn clone(&self) -> Vec { self.as_slice().to_vec() } + fn clone(&self) -> Vec { ::slice::SliceExt::to_vec(self.as_slice()) } fn clone_from(&mut self, other: &Vec) { // drop anything in self that will not be overwritten diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index cecb4938153..19301cc2d9e 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -64,5 +64,4 @@ pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; -pub use slice::{PartialEqSliceExt, OrdSliceExt}; pub use slice::{AsSlice, SliceExt}; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index faf1d781465..09c78d4bc2a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -243,7 +243,9 @@ pub unsafe fn write(dst: *mut T, src: T) { /// Methods on raw pointers #[stable] -pub trait PtrExt { +pub trait PtrExt { + type Target; + /// Returns the null pointer. #[deprecated = "call ptr::null instead"] fn null() -> Self; @@ -271,7 +273,7 @@ fn is_not_null(self) -> bool { !self.is_null() } /// memory. #[unstable = "Option is not clearly the right return type, and we may want \ to tie the return lifetime to a borrow of the raw pointer"] - unsafe fn as_ref<'a>(&self) -> Option<&'a T>; + unsafe fn as_ref<'a>(&self) -> Option<&'a Self::Target>; /// Calculates the offset from a pointer. `count` is in units of T; e.g. a /// `count` of 3 represents a pointer offset of `3 * sizeof::()` bytes. @@ -287,7 +289,9 @@ fn is_not_null(self) -> bool { !self.is_null() } /// Methods on mutable raw pointers #[stable] -pub trait MutPtrExt{ +pub trait MutPtrExt { + type Target; + /// Returns `None` if the pointer is null, or else returns a mutable /// reference to the value wrapped in `Some`. /// @@ -297,11 +301,13 @@ pub trait MutPtrExt{ /// of the returned pointer. #[unstable = "Option is not clearly the right return type, and we may want \ to tie the return lifetime to a borrow of the raw pointer"] - unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>; + unsafe fn as_mut<'a>(&self) -> Option<&'a mut Self::Target>; } #[stable] -impl PtrExt for *const T { +impl PtrExt for *const T { + type Target = T; + #[inline] #[deprecated = "call ptr::null instead"] fn null() -> *const T { null() } @@ -333,7 +339,9 @@ unsafe fn as_ref<'a>(&self) -> Option<&'a T> { } #[stable] -impl PtrExt for *mut T { +impl PtrExt for *mut T { + type Target = T; + #[inline] #[deprecated = "call ptr::null instead"] fn null() -> *mut T { null_mut() } @@ -365,7 +373,9 @@ unsafe fn as_ref<'a>(&self) -> Option<&'a T> { } #[stable] -impl MutPtrExt for *mut T { +impl MutPtrExt for *mut T { + type Target = T; + #[inline] #[unstable = "return value does not necessarily convey all possible \ information"] diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 7d894ac697b..07addf7a569 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -64,57 +64,77 @@ /// Extension methods for slices. #[allow(missing_docs)] // docs in libcollections -pub trait SliceExt for Sized? { - fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T]; - fn slice_from<'a>(&'a self, start: uint) -> &'a [T]; - fn slice_to<'a>(&'a self, end: uint) -> &'a [T]; - fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]); - fn iter<'a>(&'a self) -> Iter<'a, T>; - fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P> - where P: FnMut(&T) -> bool; - fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P> - where P: FnMut(&T) -> bool; - fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, T, P> - where P: FnMut(&T) -> bool; - fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>; - fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>; - fn get<'a>(&'a self, index: uint) -> Option<&'a T>; - fn first<'a>(&'a self) -> Option<&'a T>; - fn tail<'a>(&'a self) -> &'a [T]; - fn init<'a>(&'a self) -> &'a [T]; - fn last<'a>(&'a self) -> Option<&'a T>; - unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T; - fn as_ptr(&self) -> *const T; +pub trait SliceExt for Sized? { + type Item; + + fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [Self::Item]; + fn slice_from<'a>(&'a self, start: uint) -> &'a [Self::Item]; + fn slice_to<'a>(&'a self, end: uint) -> &'a [Self::Item]; + fn split_at<'a>(&'a self, mid: uint) -> (&'a [Self::Item], &'a [Self::Item]); + fn iter<'a>(&'a self) -> Iter<'a, Self::Item>; + fn split<'a, P>(&'a self, pred: P) -> Split<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn windows<'a>(&'a self, size: uint) -> Windows<'a, Self::Item>; + fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, Self::Item>; + fn get<'a>(&'a self, index: uint) -> Option<&'a Self::Item>; + fn first<'a>(&'a self) -> Option<&'a Self::Item>; + fn tail<'a>(&'a self) -> &'a [Self::Item]; + fn init<'a>(&'a self) -> &'a [Self::Item]; + fn last<'a>(&'a self) -> Option<&'a Self::Item>; + unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a Self::Item; + fn as_ptr(&self) -> *const Self::Item; fn binary_search_by(&self, f: F) -> Result where - F: FnMut(&T) -> Ordering; + F: FnMut(&Self::Item) -> Ordering; fn len(&self) -> uint; fn is_empty(&self) -> bool { self.len() == 0 } - fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>; - fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T]; - fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T]; - fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T]; - fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T]; - fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T>; - fn first_mut<'a>(&'a mut self) -> Option<&'a mut T>; - fn tail_mut<'a>(&'a mut self) -> &'a mut [T]; - fn init_mut<'a>(&'a mut self) -> &'a mut [T]; - fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>; - fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> - where P: FnMut(&T) -> bool; - fn splitn_mut

(&mut self, n: uint, pred: P) -> SplitNMut - where P: FnMut(&T) -> bool; - 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) -> ChunksMut<'a, T>; + fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut Self::Item>; + fn as_mut_slice<'a>(&'a mut self) -> &'a mut [Self::Item]; + fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [Self::Item]; + fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [Self::Item]; + fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [Self::Item]; + fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>; + fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>; + fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item]; + fn init_mut<'a>(&'a mut self) -> &'a mut [Self::Item]; + fn last_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>; + fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, Self::Item, P> + where P: FnMut(&Self::Item) -> bool; + fn splitn_mut

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

(&mut self, n: uint, pred: P) -> RSplitNMut + where P: FnMut(&Self::Item) -> bool; + fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, Self::Item>; fn swap(&mut self, a: uint, b: uint); - fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]); + fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [Self::Item], &'a mut [Self::Item]); fn reverse(&mut self); - unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T; - fn as_mut_ptr(&mut self) -> *mut T; + unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut Self::Item; + fn as_mut_ptr(&mut self) -> *mut Self::Item; + + fn position_elem(&self, t: &Self::Item) -> Option where Self::Item: PartialEq; + + fn rposition_elem(&self, t: &Self::Item) -> Option where Self::Item: PartialEq; + + fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq; + + fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; + + fn binary_search(&self, x: &Self::Item) -> Result where Self::Item: Ord; + fn next_permutation(&mut self) -> bool where Self::Item: Ord; + fn prev_permutation(&mut self) -> bool where Self::Item: Ord; + + fn clone_from_slice(&mut self, &[Self::Item]) -> uint where Self::Item: Clone; } #[unstable] -impl SliceExt for [T] { +impl SliceExt for [T] { + type Item = T; + #[inline] fn slice(&self, start: uint, end: uint) -> &[T] { assert!(start <= end); @@ -404,153 +424,41 @@ unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T { fn as_mut_ptr(&mut self) -> *mut T { self.repr().data as *mut T } -} - -impl ops::Index for [T] { - fn index(&self, &index: &uint) -> &T { - assert!(index < self.len()); - - unsafe { mem::transmute(self.repr().data.offset(index as int)) } - } -} - -impl ops::IndexMut for [T] { - fn index_mut(&mut self, &index: &uint) -> &mut T { - assert!(index < self.len()); - - unsafe { mem::transmute(self.repr().data.offset(index as int)) } - } -} - -impl ops::Slice for [T] { - #[inline] - fn as_slice_<'a>(&'a self) -> &'a [T] { - self - } - - #[inline] - fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { - self.slice_or_fail(start, &self.len()) - } - - #[inline] - fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { - self.slice_or_fail(&0, end) - } - #[inline] - fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { - assert!(*start <= *end); - assert!(*end <= self.len()); - unsafe { - transmute(RawSlice { - data: self.as_ptr().offset(*start as int), - len: (*end - *start) - }) - } - } -} - -impl ops::SliceMut for [T] { - #[inline] - fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { - self - } - - #[inline] - fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { - let len = &self.len(); - self.slice_or_fail_mut(start, len) - } - - #[inline] - fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { - self.slice_or_fail_mut(&0, end) - } - #[inline] - fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { - assert!(*start <= *end); - assert!(*end <= self.len()); - unsafe { - transmute(RawSlice { - data: self.as_ptr().offset(*start as int), - len: (*end - *start) - }) - } - } -} - -/// Extension methods for slices containing `PartialEq` elements. -#[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; -} -#[unstable = "trait is unstable"] -impl PartialEqSliceExt for [T] { #[inline] - fn position_elem(&self, x: &T) -> Option { + fn position_elem(&self, x: &T) -> Option where T: PartialEq { self.iter().position(|y| *x == *y) } #[inline] - fn rposition_elem(&self, t: &T) -> Option { + fn rposition_elem(&self, t: &T) -> Option where T: PartialEq { self.iter().rposition(|x| *x == *t) } #[inline] - fn contains(&self, x: &T) -> bool { + fn contains(&self, x: &T) -> bool where T: PartialEq { self.iter().any(|elt| *x == *elt) } #[inline] - fn starts_with(&self, needle: &[T]) -> bool { + fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { let n = needle.len(); self.len() >= n && needle == self[..n] } #[inline] - fn ends_with(&self, needle: &[T]) -> bool { + fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { let (m, n) = (self.len(), needle.len()); m >= n && needle == self[m-n..] } -} -/// Extension methods for slices containing `Ord` elements. -#[unstable = "may merge with other traits"] -#[allow(missing_docs)] // docs in libcollections -pub trait OrdSliceExt for Sized? { - fn binary_search(&self, x: &T) -> Result; - fn next_permutation(&mut self) -> bool; - fn prev_permutation(&mut self) -> bool; -} - -#[unstable = "trait is unstable"] -impl OrdSliceExt for [T] { #[unstable] - fn binary_search(&self, x: &T) -> Result { + fn binary_search(&self, x: &T) -> Result where T: Ord { self.binary_search_by(|p| p.cmp(x)) } #[experimental] - fn next_permutation(&mut self) -> bool { + fn next_permutation(&mut self) -> bool where T: Ord { // These cases only have 1 permutation each, so we can't do anything. if self.len() < 2 { return false; } @@ -581,7 +489,7 @@ fn next_permutation(&mut self) -> bool { } #[experimental] - fn prev_permutation(&mut self) -> bool { + fn prev_permutation(&mut self) -> bool where T: Ord { // These cases only have 1 permutation each, so we can't do anything. if self.len() < 2 { return false; } @@ -610,19 +518,9 @@ fn prev_permutation(&mut self) -> bool { true } -} -/// Extension methods for slices on Clone elements -#[unstable = "may merge with other traits"] -#[allow(missing_docs)] // docs in libcollections -pub trait CloneSliceExt for Sized? { - fn clone_from_slice(&mut self, &[T]) -> uint; -} - -#[unstable = "trait is unstable"] -impl CloneSliceExt for [T] { #[inline] - fn clone_from_slice(&mut self, src: &[T]) -> uint { + fn clone_from_slice(&mut self, src: &[T]) -> uint where T: Clone { let min = cmp::min(self.len(), src.len()); let dst = self.slice_to_mut(min); let src = src.slice_to(min); @@ -633,6 +531,79 @@ fn clone_from_slice(&mut self, src: &[T]) -> uint { } } +impl ops::Index for [T] { + fn index(&self, &index: &uint) -> &T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as int)) } + } +} + +impl ops::IndexMut for [T] { + fn index_mut(&mut self, &index: &uint) -> &mut T { + assert!(index < self.len()); + + unsafe { mem::transmute(self.repr().data.offset(index as int)) } + } +} + +impl ops::Slice for [T] { + #[inline] + fn as_slice_<'a>(&'a self) -> &'a [T] { + self + } + + #[inline] + fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { + self.slice_or_fail(start, &self.len()) + } + + #[inline] + fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { + self.slice_or_fail(&0, end) + } + #[inline] + fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { + assert!(*start <= *end); + assert!(*end <= self.len()); + unsafe { + transmute(RawSlice { + data: self.as_ptr().offset(*start as int), + len: (*end - *start) + }) + } + } +} + +impl ops::SliceMut for [T] { + #[inline] + fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { + self + } + + #[inline] + fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { + let len = &self.len(); + self.slice_or_fail_mut(start, len) + } + + #[inline] + fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { + self.slice_or_fail_mut(&0, end) + } + #[inline] + fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { + assert!(*start <= *end); + assert!(*end <= self.len()); + unsafe { + transmute(RawSlice { + data: self.as_ptr().offset(*start as int), + len: (*end - *start) + }) + } + } +} + //////////////////////////////////////////////////////////////////////////////// // Common traits //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs index 46498610e56..a11a4408019 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -539,7 +539,7 @@ pub unsafe fn from_c_multistring(buf: *const libc::c_char, #[cfg(test)] mod tests { use super::*; - use prelude::{spawn, Some, None, Option, FnOnce, ToString, CloneSliceExt}; + use prelude::{spawn, Some, None, Option, FnOnce, ToString}; use prelude::{Clone, PtrExt, Iterator, SliceExt, StrExt}; use ptr; use thread::Thread; diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index 077f75e2edd..dda37765b4a 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -14,7 +14,7 @@ use io; use option::Option::{None, Some}; use result::Result::{Ok, Err}; -use slice::{bytes, CloneSliceExt, SliceExt}; +use slice::{bytes, SliceExt}; use super::{Buffer, Reader, Writer, IoResult}; use vec::Vec; diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index f8ea373f8f4..af5d1630ca6 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -401,7 +401,7 @@ mod test { extern crate "test" as test_crate; use super::*; use io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek}; - use prelude::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt, IteratorExt, CloneSliceExt}; + use prelude::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt, IteratorExt}; use io; use self::test_crate::Bencher; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index e8b852ee492..d01840b6da0 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1919,7 +1919,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { mod tests { use self::BadReaderBehavior::*; use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput, Writer}; - use prelude::{Ok, Vec, Buffer, CloneSliceExt}; + use prelude::{Ok, Vec, Buffer, SliceExt}; use uint; #[deriving(Clone, PartialEq, Show)] diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index 49ab9ddb924..78d8ac307c2 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -25,7 +25,7 @@ use option::Option; use option::Option::{None, Some}; use result::Result::{Ok, Err}; -use slice::{CloneSliceExt, SliceExt}; +use slice::SliceExt; use str::{FromStr, StrExt}; use vec::Vec; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 74c387c5eea..654096ce49d 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -107,6 +107,7 @@ #![feature(macro_rules, globs, linkage, thread_local, asm)] #![feature(default_type_params, phase, lang_items, unsafe_destructor)] #![feature(slicing_syntax, unboxed_closures)] +#![feature(associated_types)] // Don't link to std. We are std. #![no_std] diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index ebb64bc2f2d..34693be39b3 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -317,9 +317,8 @@ macro_rules! try { #[macro_export] macro_rules! vec { ($($x:expr),*) => ({ - use std::slice::BoxedSliceExt; let xs: ::std::boxed::Box<[_]> = box [$($x),*]; - xs.into_vec() + ::std::slice::SliceExt::into_vec(xs) }); ($($x:expr,)*) => (vec![$($x),*]) } diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index febdf5f6118..6c64251091a 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -20,7 +20,7 @@ use num::{mod, Int, Float, ToPrimitive}; use num::FpCategory as Fp; use ops::FnMut; -use slice::{SliceExt, CloneSliceExt}; +use slice::SliceExt; use str::StrExt; use string::String; use vec::Vec; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index df50b7f81af..7aea83a069a 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -52,7 +52,6 @@ use result::Result; use result::Result::{Err, Ok}; use slice::{AsSlice, SliceExt}; -use slice::CloneSliceExt; use str::{Str, StrExt}; use string::{String, ToString}; use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 30f3f56bc1c..fae90e8d393 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -71,8 +71,7 @@ use str; use str::{CowString, MaybeOwned, Str, StrExt}; use string::String; -use slice::{AsSlice, CloneSliceExt}; -use slice::{PartialEqSliceExt, SliceExt}; +use slice::{AsSlice, SliceExt}; use vec::Vec; /// Typedef for POSIX file paths. diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index bd4031e6230..8718d509f00 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -22,8 +22,7 @@ use kinds::Sized; use str::{FromStr, Str}; use str; -use slice::{CloneSliceExt, Split, AsSlice, SliceConcatExt, - PartialEqSliceExt, SliceExt}; +use slice::{Split, AsSlice, SliceConcatExt, SliceExt}; use vec::Vec; use super::{BytesContainer, GenericPath, GenericPathUnsafe}; @@ -449,7 +448,7 @@ fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option> { mod tests { use super::*; use prelude::Option::{mod, Some, None}; - use prelude::{Vec, Clone, AsSlice, SliceExt, CloneSliceExt, IteratorExt}; + use prelude::{Vec, Clone, AsSlice, SliceExt, IteratorExt}; use prelude::{DoubleEndedIteratorExt, Str, StrExt, ToString, GenericPath}; use str; diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 751ed4b70fb..10f4adbfe56 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -1121,7 +1121,7 @@ fn prefix_len(p: Option) -> uint { mod tests { use super::*; use prelude::Option::{mod, Some, None}; - use prelude::{Vec, Clone, AsSlice, SliceExt, CloneSliceExt, IteratorExt}; + use prelude::{Vec, Clone, AsSlice, SliceExt, IteratorExt}; use prelude::{DoubleEndedIteratorExt, Str, ToString, GenericPath}; use super::PathPrefix::*; use super::parse_prefix; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index f016683e3d0..95b82959562 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -82,9 +82,7 @@ #[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12}; #[doc(no_inline)] pub use str::{Str, StrExt}; #[doc(no_inline)] pub use slice::AsSlice; -#[doc(no_inline)] pub use slice::{SliceConcatExt, PartialEqSliceExt}; -#[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt}; -#[doc(no_inline)] pub use slice::{BoxedSliceExt}; +#[doc(no_inline)] pub use slice::{SliceConcatExt, SliceExt}; #[doc(no_inline)] pub use string::{IntoString, String, ToString}; #[doc(no_inline)] pub use vec::Vec; -- 2.44.0