//
/// Extension methods for slices.
-#[allow(missing_docs)] // docs in libcollections
-#[doc(hidden)]
#[unstable(feature = "core_slice_ext",
reason = "stable interface provided by `impl [T]` in later crates",
issue = "27701")]
+#[allow(missing_docs)] // documented elsewhere
pub trait SliceExt {
type Item;
+ #[stable(feature = "core", since = "1.6.0")]
fn split_at(&self, mid: usize) -> (&[Self::Item], &[Self::Item]);
+ #[stable(feature = "core", since = "1.6.0")]
fn iter(&self) -> Iter<Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
fn split<P>(&self, pred: P) -> Split<Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
+ #[stable(feature = "core", since = "1.6.0")]
fn splitn<P>(&self, n: usize, pred: P) -> SplitN<Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
+ #[stable(feature = "core", since = "1.6.0")]
fn rsplitn<P>(&self, n: usize, pred: P) -> RSplitN<Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
+ #[stable(feature = "core", since = "1.6.0")]
fn windows(&self, size: usize) -> Windows<Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
fn chunks(&self, size: usize) -> Chunks<Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
fn get(&self, index: usize) -> Option<&Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
fn first(&self) -> Option<&Self::Item>;
- fn tail(&self) -> &[Self::Item];
- fn init(&self) -> &[Self::Item];
+ #[stable(feature = "core", since = "1.6.0")]
fn split_first(&self) -> Option<(&Self::Item, &[Self::Item])>;
+ #[stable(feature = "core", since = "1.6.0")]
fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])>;
+ #[stable(feature = "core", since = "1.6.0")]
fn last(&self) -> Option<&Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
unsafe fn get_unchecked(&self, index: usize) -> &Self::Item;
+ #[stable(feature = "core", since = "1.6.0")]
fn as_ptr(&self) -> *const Self::Item;
- fn binary_search_by<F>(&self, f: F) -> Result<usize, usize> where
- F: FnMut(&Self::Item) -> Ordering;
+ #[stable(feature = "core", since = "1.6.0")]
+ fn binary_search(&self, x: &Self::Item) -> Result<usize, usize>
+ where Self::Item: Ord;
+ #[stable(feature = "core", since = "1.6.0")]
+ fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
+ where F: FnMut(&Self::Item) -> Ordering;
+ #[stable(feature = "core", since = "1.6.0")]
fn len(&self) -> usize;
+ #[stable(feature = "core", since = "1.6.0")]
fn is_empty(&self) -> bool { self.len() == 0 }
+ #[stable(feature = "core", since = "1.6.0")]
fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
fn iter_mut(&mut self) -> IterMut<Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
fn first_mut(&mut self) -> Option<&mut Self::Item>;
- fn tail_mut(&mut self) -> &mut [Self::Item];
- fn init_mut(&mut self) -> &mut [Self::Item];
+ #[stable(feature = "core", since = "1.6.0")]
fn split_first_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
+ #[stable(feature = "core", since = "1.6.0")]
fn split_last_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
+ #[stable(feature = "core", since = "1.6.0")]
fn last_mut(&mut self) -> Option<&mut Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
fn split_mut<P>(&mut self, pred: P) -> SplitMut<Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
+ #[stable(feature = "core", since = "1.6.0")]
fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
+ #[stable(feature = "core", since = "1.6.0")]
fn rsplitn_mut<P>(&mut self, n: usize, pred: P) -> RSplitNMut<Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
+ #[stable(feature = "core", since = "1.6.0")]
fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>;
+ #[stable(feature = "core", since = "1.6.0")]
fn swap(&mut self, a: usize, b: usize);
+ #[stable(feature = "core", since = "1.6.0")]
fn split_at_mut(&mut self, mid: usize) -> (&mut [Self::Item], &mut [Self::Item]);
+ #[stable(feature = "core", since = "1.6.0")]
fn reverse(&mut self);
+ #[stable(feature = "core", since = "1.6.0")]
unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut Self::Item;
+ #[stable(feature = "core", since = "1.6.0")]
fn as_mut_ptr(&mut self) -> *mut Self::Item;
- fn position_elem(&self, t: &Self::Item) -> Option<usize> where Self::Item: PartialEq;
-
- fn rposition_elem(&self, t: &Self::Item) -> Option<usize> where Self::Item: PartialEq;
-
+ #[stable(feature = "core", since = "1.6.0")]
fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
+ #[stable(feature = "core", since = "1.6.0")]
fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
+ #[stable(feature = "core", since = "1.6.0")]
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
- fn binary_search(&self, x: &Self::Item) -> Result<usize, usize> where Self::Item: Ord;
- fn next_permutation(&mut self) -> bool where Self::Item: Ord;
- fn prev_permutation(&mut self) -> bool where Self::Item: Ord;
-
+ #[unstable(feature = "clone_from_slice", issue= "27750")]
fn clone_from_slice(&mut self, &[Self::Item]) -> usize where Self::Item: Clone;
}
}};
}
+#[unstable(feature = "core_slice_ext",
+ reason = "stable interface provided by `impl [T]` in later crates",
+ issue = "27701")]
impl<T> SliceExt for [T] {
type Item = T;
if self.is_empty() { None } else { Some(&self[0]) }
}
- #[inline]
- fn tail(&self) -> &[T] { &self[1..] }
-
#[inline]
fn split_first(&self) -> Option<(&T, &[T])> {
if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
}
- #[inline]
- fn init(&self) -> &[T] { &self[..self.len() - 1] }
-
#[inline]
fn split_last(&self) -> Option<(&T, &[T])> {
let len = self.len();
if self.is_empty() { None } else { Some(&mut self[0]) }
}
- #[inline]
- fn tail_mut(&mut self) -> &mut [T] { &mut self[1 ..] }
-
#[inline]
fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
if self.is_empty() { None } else {
}
}
- #[inline]
- fn init_mut(&mut self) -> &mut [T] {
- let len = self.len();
- &mut self[.. (len - 1)]
- }
-
#[inline]
fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
let len = self.len();
self.repr().data as *mut T
}
- #[inline]
- fn position_elem(&self, x: &T) -> Option<usize> where T: PartialEq {
- self.iter().position(|y| *x == *y)
- }
-
- #[inline]
- fn rposition_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
- self.iter().rposition(|x| *x == *t)
- }
-
#[inline]
fn contains(&self, x: &T) -> bool where T: PartialEq {
self.iter().any(|elt| *x == *elt)
self.binary_search_by(|p| p.cmp(x))
}
- fn next_permutation(&mut self) -> bool where T: Ord {
- // These cases only have 1 permutation each, so we can't do anything.
- if self.len() < 2 { return false; }
-
- // Step 1: Identify the longest, rightmost weakly decreasing part of the vector
- let mut i = self.len() - 1;
- while i > 0 && self[i-1] >= self[i] {
- i -= 1;
- }
-
- // If that is the entire vector, this is the last-ordered permutation.
- if i == 0 {
- return false;
- }
-
- // Step 2: Find the rightmost element larger than the pivot (i-1)
- let mut j = self.len() - 1;
- while j >= i && self[j] <= self[i-1] {
- j -= 1;
- }
-
- // Step 3: Swap that element with the pivot
- self.swap(j, i-1);
-
- // Step 4: Reverse the (previously) weakly decreasing part
- self[i..].reverse();
-
- true
- }
-
- fn prev_permutation(&mut self) -> bool where T: Ord {
- // These cases only have 1 permutation each, so we can't do anything.
- if self.len() < 2 { return false; }
-
- // Step 1: Identify the longest, rightmost weakly increasing part of the vector
- let mut i = self.len() - 1;
- while i > 0 && self[i-1] <= self[i] {
- i -= 1;
- }
-
- // If that is the entire vector, this is the first-ordered permutation.
- if i == 0 {
- return false;
- }
-
- // Step 2: Reverse the weakly increasing part
- self[i..].reverse();
-
- // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
- let mut j = self.len() - 1;
- while j >= i && self[j-1] < self[i-1] {
- j -= 1;
- }
-
- // Step 4: Swap that element with the pivot
- self.swap(i-1, j);
-
- true
- }
-
#[inline]
fn clone_from_slice(&mut self, src: &[T]) -> usize where T: Clone {
let min = cmp::min(self.len(), src.len());
}
}
+#[inline(never)]
+#[cold]
+fn slice_index_len_fail(index: usize, len: usize) -> ! {
+ panic!("index {} out of range for slice of length {}", index, len);
+}
+
+#[inline(never)]
+#[cold]
+fn slice_index_order_fail(index: usize, end: usize) -> ! {
+ panic!("slice index starts at {} but ends at {}", index, end);
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<ops::Range<usize>> for [T] {
type Output = [T];
#[inline]
fn index(&self, index: ops::Range<usize>) -> &[T] {
- assert!(index.start <= index.end);
- assert!(index.end <= self.len());
+ if index.start > index.end {
+ slice_index_order_fail(index.start, index.end);
+ } else if index.end > self.len() {
+ slice_index_len_fail(index.end, self.len());
+ }
unsafe {
from_raw_parts (
self.as_ptr().offset(index.start as isize),
impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
#[inline]
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
- assert!(index.start <= index.end);
- assert!(index.end <= self.len());
+ if index.start > index.end {
+ slice_index_order_fail(index.start, index.end);
+ } else if index.end > self.len() {
+ slice_index_len_fail(index.end, self.len());
+ }
unsafe {
from_raw_parts_mut(
self.as_mut_ptr().offset(index.start as isize),
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Default for &'a [T] {
- #[stable(feature = "rust1", since = "1.0.0")]
fn default() -> &'a [T] { &[] }
}
_marker: marker::PhantomData<&'a T>,
}
+#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {}
+#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
impl<'a, T> Iter<'a, T> {
_marker: marker::PhantomData<&'a mut T>,
}
+#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {}
+#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
impl<'a, T> IterMut<'a, T> {
/// Converts a reference to A into a slice of length 1 (without copying).
#[unstable(feature = "ref_slice", issue = "27774")]
-#[deprecated(since = "1.5.0", reason = "unclear whether belongs in libstd")]
+#[rustc_deprecated(since = "1.5.0", reason = "unclear whether belongs in libstd")]
pub fn ref_slice<A>(s: &A) -> &[A] {
unsafe {
from_raw_parts(s, 1)
/// Converts a reference to A into a slice of length 1 (without copying).
#[unstable(feature = "ref_slice", issue = "27774")]
-#[deprecated(since = "1.5.0", reason = "unclear whether belongs in libstd")]
+#[rustc_deprecated(since = "1.5.0", reason = "unclear whether belongs in libstd")]
pub fn mut_ref_slice<A>(s: &mut A) -> &mut [A] {
unsafe {
from_raw_parts_mut(s, 1)
/// Operations on `[u8]`.
#[unstable(feature = "slice_bytes", reason = "needs review",
issue = "27740")]
+#[rustc_deprecated(reason = "unidiomatic functions not pulling their weight",
+ since = "1.6.0")]
+#[allow(deprecated)]
pub mod bytes {
use ptr;
use slice::SliceExt;