diff options
| author | Aaron Turon <aturon@mozilla.com> | 2014-11-02 17:04:32 -0800 |
|---|---|---|
| committer | Aaron Turon <aturon@mozilla.com> | 2014-11-06 08:03:18 -0800 |
| commit | cfafc1b7377d34d8c60db7cd386836d39b80af41 (patch) | |
| tree | fc5490eb766f91db85f6fa6061a48efd23f0457e /src/libcore | |
| parent | e84e7a00ddec76570bbaa9afea385d544f616814 (diff) | |
| download | rust-cfafc1b7377d34d8c60db7cd386836d39b80af41.tar.gz rust-cfafc1b7377d34d8c60db7cd386836d39b80af41.zip | |
Prelude: rename and consolidate extension traits
This commit renames a number of extension traits for slices and string slices, now that they have been refactored for DST. In many cases, multiple extension traits could now be consolidated. Further consolidation will be possible with generalized where clauses. The renamings are consistent with the [new `-Prelude` suffix](https://github.com/rust-lang/rfcs/pull/344). There are probably a few more candidates for being renamed this way, but that is left for API stabilization of the relevant modules. Because this renames traits, it is a: [breaking-change] However, I do not expect any code that currently uses the standard library to actually break. Closes #17917
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/char.rs | 2 | ||||
| -rw-r--r-- | src/libcore/fmt/float.rs | 4 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/fmt/num.rs | 2 | ||||
| -rw-r--r-- | src/libcore/prelude.rs | 6 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 529 | ||||
| -rw-r--r-- | src/libcore/str.rs | 13 |
7 files changed, 325 insertions, 235 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 0fab0e96fe6..f769eea377a 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -18,7 +18,7 @@ use mem::transmute; use option::{None, Option, Some}; use iter::range_step; -use slice::ImmutableSlice; +use slice::SlicePrelude; // UTF-8 ranges and tags for encoding characters static TAG_CONT: u8 = 0b1000_0000u8; diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index f51d3948757..a6e5b0cff55 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -16,8 +16,8 @@ use iter::{range, DoubleEndedIterator}; use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive}; use num::{Zero, One, cast}; use result::Ok; -use slice::{mod, ImmutableSlice, MutableSlice}; -use str::StrSlice; +use slice::{mod, SlicePrelude}; +use str::StrPrelude; /// A flag that specifies whether to use exponential (scientific) notation. pub enum ExponentFormat { diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 013ed999b03..081f373b831 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -21,9 +21,9 @@ use option::{Option, Some, None}; use ops::Deref; use result::{Ok, Err}; use result; -use slice::{AsSlice, ImmutableSlice}; +use slice::{AsSlice, SlicePrelude}; use slice; -use str::StrSlice; +use str::StrPrelude; use str; pub use self::num::radix; diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 190e1ecea59..e4a6c1a9758 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -17,7 +17,7 @@ use fmt; use iter::DoubleEndedIterator; use num::{Int, cast, zero}; -use slice::{ImmutableSlice, MutableSlice}; +use slice::SlicePrelude; /// A type that represents a specific radix #[doc(hidden)] diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index 4b08d4f3391..996f2e56ad3 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -57,9 +57,9 @@ pub use num::{Primitive, Int, ToPrimitive, FromPrimitive}; pub use option::{Option, Some, None}; pub use ptr::RawPtr; pub use result::{Result, Ok, Err}; -pub use str::{Str, StrSlice}; +pub use str::{Str, StrPrelude}; pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; -pub use slice::{ImmutablePartialEqSlice, ImmutableOrdSlice}; -pub use slice::{AsSlice, ImmutableSlice, MutableSlice}; +pub use slice::{PartialEqSlicePrelude, OrdSlicePrelude}; +pub use slice::{AsSlice, SlicePrelude}; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 3cc904162a1..eaa52c99c4a 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -57,9 +57,9 @@ use raw::Slice as RawSlice; // Extension traits // -/// Extension methods for immutable slices. -#[unstable = "may merge with other traits; region parameter may disappear"] -pub trait ImmutableSlice<T> for Sized? { +/// Extension methods for slices. +#[unstable = "may merge with other traits"] +pub trait SlicePrelude<T> for Sized? { /// Returns a subslice spanning the interval [`start`, `end`). /// /// Fails when the end of the new slice lies beyond the end of the @@ -256,216 +256,12 @@ pub trait ImmutableSlice<T> for Sized? { #[inline] #[experimental = "not triaged yet"] fn is_empty(&self) -> bool { self.len() == 0 } -} - -#[unstable] -impl<T> ImmutableSlice<T> for [T] { - #[inline] - fn slice(&self, start: uint, end: uint) -> &[T] { - assert!(start <= end); - assert!(end <= self.len()); - unsafe { - transmute(RawSlice { - data: self.as_ptr().offset(start as int), - len: (end - start) - }) - } - } - - #[inline] - fn slice_from(&self, start: uint) -> &[T] { - self.slice(start, self.len()) - } - - #[inline] - fn slice_to(&self, end: uint) -> &[T] { - self.slice(0, end) - } - - #[inline] - fn split_at(&self, mid: uint) -> (&[T], &[T]) { - (self[..mid], self[mid..]) - } - - #[inline] - fn iter<'a>(&'a self) -> Items<'a, T> { - unsafe { - let p = self.as_ptr(); - if mem::size_of::<T>() == 0 { - Items{ptr: p, - end: (p as uint + self.len()) as *const T, - marker: marker::ContravariantLifetime::<'a>} - } else { - Items{ptr: p, - end: p.offset(self.len() as int), - marker: marker::ContravariantLifetime::<'a>} - } - } - } - - #[inline] - fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T> { - Splits { - v: self, - pred: pred, - finished: false - } - } - #[inline] - fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> { - SplitsN { - iter: self.split(pred), - count: n, - invert: false - } - } - - #[inline] - fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> { - SplitsN { - iter: self.split(pred), - count: n, - invert: true - } - } - - #[inline] - fn windows(&self, size: uint) -> Windows<T> { - assert!(size != 0); - Windows { v: self, size: size } - } - - #[inline] - fn chunks(&self, size: uint) -> Chunks<T> { - assert!(size != 0); - Chunks { v: self, size: size } - } - - #[inline] - fn get(&self, index: uint) -> Option<&T> { - if index < self.len() { Some(&self[index]) } else { None } - } - - #[inline] - fn head(&self) -> Option<&T> { - if self.len() == 0 { None } else { Some(&self[0]) } - } - - #[inline] - fn tail(&self) -> &[T] { self[1..] } - - #[inline] - fn init(&self) -> &[T] { - self[..self.len() - 1] - } - - #[inline] - fn last(&self) -> Option<&T> { - if self.len() == 0 { None } else { Some(&self[self.len() - 1]) } - } - - #[inline] - unsafe fn unsafe_get(&self, index: uint) -> &T { - transmute(self.repr().data.offset(index as int)) - } - - #[inline] - fn as_ptr(&self) -> *const T { - self.repr().data - } - - #[unstable] - fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult { - 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 Found(ix), - Less => { - base = ix + 1; - lim -= 1; - } - Greater => () - } - lim >>= 1; - } - return NotFound(base); - } - - #[inline] - fn len(&self) -> uint { self.repr().len } -} - - - -impl<T> ops::Slice<uint, [T]> 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<T> ops::SliceMut<uint, [T]> 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 such that their elements are -/// mutable. -#[experimental = "may merge with other traits; may lose region param; needs review"] -pub trait MutableSlice<T> for Sized? { /// Returns a mutable reference to the element at the given index, /// or `None` if the index is out of bounds #[unstable = "waiting on final error conventions"] fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>; + /// Work with `self` as a mut slice. /// Primarily intended for getting a &mut [T] from a [T, ..N]. fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T]; @@ -626,8 +422,146 @@ pub trait MutableSlice<T> for Sized? { fn as_mut_ptr(&mut self) -> *mut T; } -#[experimental = "trait is experimental"] -impl<T> MutableSlice<T> for [T] { +#[unstable] +impl<T> SlicePrelude<T> for [T] { + #[inline] + fn slice(&self, start: uint, end: uint) -> &[T] { + assert!(start <= end); + assert!(end <= self.len()); + unsafe { + transmute(RawSlice { + data: self.as_ptr().offset(start as int), + len: (end - start) + }) + } + } + + #[inline] + fn slice_from(&self, start: uint) -> &[T] { + self.slice(start, self.len()) + } + + #[inline] + fn slice_to(&self, end: uint) -> &[T] { + self.slice(0, end) + } + + #[inline] + fn split_at(&self, mid: uint) -> (&[T], &[T]) { + (self[..mid], self[mid..]) + } + + #[inline] + fn iter<'a>(&'a self) -> Items<'a, T> { + unsafe { + let p = self.as_ptr(); + if mem::size_of::<T>() == 0 { + Items{ptr: p, + end: (p as uint + self.len()) as *const T, + marker: marker::ContravariantLifetime::<'a>} + } else { + Items{ptr: p, + end: p.offset(self.len() as int), + marker: marker::ContravariantLifetime::<'a>} + } + } + } + + #[inline] + fn split<'a>(&'a self, pred: |&T|: 'a -> bool) -> Splits<'a, T> { + Splits { + v: self, + pred: pred, + finished: false + } + } + + #[inline] + fn splitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> { + SplitsN { + iter: self.split(pred), + count: n, + invert: false + } + } + + #[inline] + fn rsplitn<'a>(&'a self, n: uint, pred: |&T|: 'a -> bool) -> SplitsN<Splits<'a, T>> { + SplitsN { + iter: self.split(pred), + count: n, + invert: true + } + } + + #[inline] + fn windows(&self, size: uint) -> Windows<T> { + assert!(size != 0); + Windows { v: self, size: size } + } + + #[inline] + fn chunks(&self, size: uint) -> Chunks<T> { + assert!(size != 0); + Chunks { v: self, size: size } + } + + #[inline] + fn get(&self, index: uint) -> Option<&T> { + if index < self.len() { Some(&self[index]) } else { None } + } + + #[inline] + fn head(&self) -> Option<&T> { + if self.len() == 0 { None } else { Some(&self[0]) } + } + + #[inline] + fn tail(&self) -> &[T] { self[1..] } + + #[inline] + fn init(&self) -> &[T] { + self[..self.len() - 1] + } + + #[inline] + fn last(&self) -> Option<&T> { + if self.len() == 0 { None } else { Some(&self[self.len() - 1]) } + } + + #[inline] + unsafe fn unsafe_get(&self, index: uint) -> &T { + transmute(self.repr().data.offset(index as int)) + } + + #[inline] + fn as_ptr(&self) -> *const T { + self.repr().data + } + + #[unstable] + fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult { + 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 Found(ix), + Less => { + base = ix + 1; + lim -= 1; + } + Greater => () + } + lim >>= 1; + } + return NotFound(base); + } + + #[inline] + fn len(&self) -> uint { self.repr().len } + #[inline] fn get_mut(&mut self, index: uint) -> Option<&mut T> { if index < self.len() { Some(&mut self[index]) } else { None } @@ -764,9 +698,66 @@ impl<T> MutableSlice<T> for [T] { } } +impl<T> ops::Slice<uint, [T]> 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<T> ops::SliceMut<uint, [T]> 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 other traits"] -pub trait ImmutablePartialEqSlice<T: PartialEq> for Sized? { +pub trait PartialEqSlicePrelude<T: PartialEq> for Sized? { /// Find the first index containing a matching value. fn position_elem(&self, t: &T) -> Option<uint>; @@ -784,7 +775,7 @@ pub trait ImmutablePartialEqSlice<T: PartialEq> for Sized? { } #[unstable = "trait is unstable"] -impl<T: PartialEq> ImmutablePartialEqSlice<T> for [T] { +impl<T: PartialEq> PartialEqSlicePrelude<T> for [T] { #[inline] fn position_elem(&self, x: &T) -> Option<uint> { self.iter().position(|y| *x == *y) @@ -815,7 +806,7 @@ impl<T: PartialEq> ImmutablePartialEqSlice<T> for [T] { /// Extension methods for slices containing `Ord` elements. #[unstable = "may merge with other traits"] -pub trait ImmutableOrdSlice<T: Ord> for Sized? { +pub trait OrdSlicePrelude<T: Ord> for Sized? { /// Binary search a sorted slice for a given element. /// /// If the value is found then `Found` is returned, containing the @@ -842,19 +833,119 @@ pub trait ImmutableOrdSlice<T: Ord> for Sized? { /// ``` #[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; } #[unstable = "trait is unstable"] -impl<T: Ord> ImmutableOrdSlice<T> for [T] { +impl<T: Ord> OrdSlicePrelude<T> for [T] { #[unstable] fn binary_search_elem(&self, x: &T) -> BinarySearchResult { self.binary_search(|p| p.cmp(x)) } + + #[experimental] + fn next_permutation(&mut self) -> bool { + // These cases only have 1 permutation each, so we can't do anything. + if self.len() < 2 { return false; } + + // Step 1: Identify the longest, rightmost weakly decreasing part of the vector + let mut i = self.len() - 1; + while i > 0 && self[i-1] >= self[i] { + i -= 1; + } + + // If that is the entire vector, this is the last-ordered permutation. + if i == 0 { + return false; + } + + // Step 2: Find the rightmost element larger than the pivot (i-1) + let mut j = self.len() - 1; + while j >= i && self[j] <= self[i-1] { + j -= 1; + } + + // Step 3: Swap that element with the pivot + self.swap(j, i-1); + + // Step 4: Reverse the (previously) weakly decreasing part + self[mut i..].reverse(); + + true + } + + #[experimental] + fn prev_permutation(&mut self) -> bool { + // These cases only have 1 permutation each, so we can't do anything. + if self.len() < 2 { return false; } + + // Step 1: Identify the longest, rightmost weakly increasing part of the vector + let mut i = self.len() - 1; + while i > 0 && self[i-1] <= self[i] { + i -= 1; + } + + // If that is the entire vector, this is the first-ordered permutation. + if i == 0 { + return false; + } + + // Step 2: Reverse the weakly increasing part + self[mut i..].reverse(); + + // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1) + let mut j = self.len() - 1; + while j >= i && self[j-1] < self[i-1] { + j -= 1; + } + + // Step 4: Swap that element with the pivot + self.swap(i-1, j); + + true + } } -/// Trait for &[T] where T is Cloneable +/// Extension methods for slices on Clone elements #[unstable = "may merge with other traits"] -pub trait MutableCloneableSlice<T> for Sized? { +pub trait CloneSlicePrelude<T> for Sized? { /// Copies as many elements from `src` as it can into `self` (the /// shorter of `self.len()` and `src.len()`). Returns the number /// of elements copied. @@ -862,7 +953,7 @@ pub trait MutableCloneableSlice<T> for Sized? { /// # Example /// /// ```rust - /// use std::slice::MutableCloneableSlice; + /// use std::slice::CloneSlicePrelude; /// /// let mut dst = [0i, 0, 0]; /// let src = [1i, 2]; @@ -878,7 +969,7 @@ pub trait MutableCloneableSlice<T> for Sized? { } #[unstable = "trait is unstable"] -impl<T: Clone> MutableCloneableSlice<T> for [T] { +impl<T: Clone> CloneSlicePrelude<T> for [T] { #[inline] fn clone_from_slice(&mut self, src: &[T]) -> uint { let min = cmp::min(self.len(), src.len()); @@ -1517,7 +1608,7 @@ pub mod raw { pub mod bytes { use kinds::Sized; use ptr; - use slice::{ImmutableSlice, MutableSlice}; + use slice::SlicePrelude; /// A trait for operations on mutable `[u8]`s. pub trait MutableByteVector for Sized? { diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 175f9f3f577..4c1bfb61709 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -28,8 +28,7 @@ use kinds::Sized; use num::{CheckedMul, Saturating}; use option::{Option, None, Some}; use raw::Repr; -use slice::ImmutableSlice; -use slice; +use slice::{mod, SlicePrelude}; use uint; /* @@ -1056,8 +1055,8 @@ pub mod raw { use mem; use ptr::RawPtr; use raw::Slice; - use slice::{ImmutableSlice}; - use str::{is_utf8, StrSlice}; + use slice::SlicePrelude; + use str::{is_utf8, StrPrelude}; /// Converts a slice of bytes to a string slice without checking /// that the string contains valid UTF-8. @@ -1120,7 +1119,7 @@ pub mod traits { use iter::Iterator; use option::{Option, Some}; use ops; - use str::{Str, StrSlice, eq_slice}; + use str::{Str, StrPrelude, eq_slice}; // NOTE(stage0): remove impl after a snapshot #[cfg(stage0)] @@ -1240,7 +1239,7 @@ impl<'a> Str for &'a str { } /// Methods for string slices -pub trait StrSlice for Sized? { +pub trait StrPrelude for Sized? { /// Returns true if one string contains another /// /// # Arguments @@ -1891,7 +1890,7 @@ fn slice_error_fail(s: &str, begin: uint, end: uint) -> ! { begin, end, s); } -impl StrSlice for str { +impl StrPrelude for str { #[inline] fn contains(&self, needle: &str) -> bool { self.find_str(needle).is_some() |
