use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::marker::Copy;
use crate::mem;
+use crate::num::NonZeroUsize;
use crate::ops::{FnMut, Range, RangeBounds};
use crate::option::Option;
use crate::option::Option::{None, Some};
mod ascii;
mod cmp;
-mod index;
+pub(crate) mod index;
mod iter;
mod raw;
mod rotate;
#[unstable(feature = "array_windows", issue = "75027")]
pub use iter::ArrayWindows;
-#[unstable(feature = "split_inclusive", issue = "72360")]
+#[unstable(feature = "slice_group_by", issue = "80552")]
+pub use iter::{GroupBy, GroupByMut};
+
+#[stable(feature = "split_inclusive", since = "1.51.0")]
pub use iter::{SplitInclusive, SplitInclusiveMut};
#[stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "slice_get_slice", since = "1.28.0")]
pub use index::SliceIndex;
-#[unstable(feature = "slice_check_range", issue = "76393")]
-pub use index::check_range;
-
#[lang = "slice"]
#[cfg(not(test))]
impl<T> [T] {
/// let a = [1, 2, 3];
/// assert_eq!(a.len(), 3);
/// ```
+ #[doc(alias = "length")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")]
#[inline]
// SAFETY: const sound because we transmute out the length field as a usize (which it must be)
- #[allow_internal_unstable(const_fn_union)]
+ #[rustc_allow_const_fn_unstable(const_fn_union)]
pub const fn len(&self) -> usize {
// SAFETY: this is safe because `&[T]` and `FatPtr<T>` have the same layout.
// Only `std` can make this guarantee.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn swap(&mut self, a: usize, b: usize) {
- // Can't take two mutable loans from one vector, so instead just cast
- // them to their raw pointers to do the swap.
- let pa: *mut T = &mut self[a];
- let pb: *mut T = &mut self[b];
+ // Can't take two mutable loans from one vector, so instead use raw pointers.
+ let pa = ptr::addr_of_mut!(self[a]);
+ let pb = ptr::addr_of_mut!(self[b]);
// SAFETY: `pa` and `pb` have been created from safe mutable references and refer
// to elements in the slice and therefore are guaranteed to be valid and aligned.
// Note that accessing the elements behind `a` and `b` is checked and will
// many bytes away from the end of `self`.
// - Any initialized memory is valid `usize`.
unsafe {
- let pa: *mut T = self.get_unchecked_mut(i);
- let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
+ let ptr = self.as_mut_ptr();
+ let pa = ptr.add(i);
+ let pb = ptr.add(ln - i - chunk);
let va = ptr::read_unaligned(pa as *mut usize);
let vb = ptr::read_unaligned(pb as *mut usize);
ptr::write_unaligned(pa as *mut usize, vb.swap_bytes());
// always respected, ensuring the `pb` pointer can be used
// safely.
unsafe {
- let pa: *mut T = self.get_unchecked_mut(i);
- let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
+ let ptr = self.as_mut_ptr();
+ let pa = ptr.add(i);
+ let pb = ptr.add(ln - i - chunk);
let va = ptr::read_unaligned(pa as *mut u32);
let vb = ptr::read_unaligned(pb as *mut u32);
ptr::write_unaligned(pa as *mut u32, vb.rotate_left(16));
// aligned, and can be read from and written to.
unsafe {
// Unsafe swap to avoid the bounds check in safe swap.
- let pa: *mut T = self.get_unchecked_mut(i);
- let pb: *mut T = self.get_unchecked_mut(ln - i - 1);
+ let ptr = self.as_mut_ptr();
+ let pa = ptr.add(i);
+ let pb = ptr.add(ln - i - 1);
ptr::swap(pa, pb);
}
i += 1;
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn windows(&self, size: usize) -> Windows<'_, T> {
- assert_ne!(size, 0);
+ let size = NonZeroUsize::new(size).expect("size is zero");
Windows::new(self, size)
}
ChunksExactMut::new(self, chunk_size)
}
+ /// Splits the slice into a slice of `N`-element arrays,
+ /// assuming that there's no remainder.
+ ///
+ /// # Safety
+ ///
+ /// This may only be called when
+ /// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).
+ /// - `N != 0`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_as_chunks)]
+ /// let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+ /// let chunks: &[[char; 1]] =
+ /// // SAFETY: 1-element chunks never have remainder
+ /// unsafe { slice.as_chunks_unchecked() };
+ /// assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+ /// let chunks: &[[char; 3]] =
+ /// // SAFETY: The slice length (6) is a multiple of 3
+ /// unsafe { slice.as_chunks_unchecked() };
+ /// assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+ ///
+ /// // These would be unsound:
+ /// // let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+ /// // let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+ /// ```
+ #[unstable(feature = "slice_as_chunks", issue = "74985")]
+ #[inline]
+ pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] {
+ debug_assert_ne!(N, 0);
+ debug_assert_eq!(self.len() % N, 0);
+ let new_len =
+ // SAFETY: Our precondition is exactly what's needed to call this
+ unsafe { crate::intrinsics::exact_div(self.len(), N) };
+ // SAFETY: We cast a slice of `new_len * N` elements into
+ // a slice of `new_len` many `N` elements chunks.
+ unsafe { from_raw_parts(self.as_ptr().cast(), new_len) }
+ }
+
+ /// Splits the slice into a slice of `N`-element arrays,
+ /// starting at the beginning of the slice,
+ /// and a remainder slice with length strictly less than `N`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
+ /// error before this method gets stabilized.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_as_chunks)]
+ /// let slice = ['l', 'o', 'r', 'e', 'm'];
+ /// let (chunks, remainder) = slice.as_chunks();
+ /// assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+ /// assert_eq!(remainder, &['m']);
+ /// ```
+ #[unstable(feature = "slice_as_chunks", issue = "74985")]
+ #[inline]
+ pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T]) {
+ assert_ne!(N, 0);
+ let len = self.len() / N;
+ let (multiple_of_n, remainder) = self.split_at(len * N);
+ // SAFETY: We already panicked for zero, and ensured by construction
+ // that the length of the subslice is a multiple of N.
+ let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };
+ (array_slice, remainder)
+ }
+
+ /// Splits the slice into a slice of `N`-element arrays,
+ /// starting at the end of the slice,
+ /// and a remainder slice with length strictly less than `N`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
+ /// error before this method gets stabilized.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_as_chunks)]
+ /// let slice = ['l', 'o', 'r', 'e', 'm'];
+ /// let (remainder, chunks) = slice.as_rchunks();
+ /// assert_eq!(remainder, &['l']);
+ /// assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+ /// ```
+ #[unstable(feature = "slice_as_chunks", issue = "74985")]
+ #[inline]
+ pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]]) {
+ assert_ne!(N, 0);
+ let len = self.len() / N;
+ let (remainder, multiple_of_n) = self.split_at(self.len() - len * N);
+ // SAFETY: We already panicked for zero, and ensured by construction
+ // that the length of the subslice is a multiple of N.
+ let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };
+ (remainder, array_slice)
+ }
+
/// Returns an iterator over `N` elements of the slice at a time, starting at the
/// beginning of the slice.
///
ArrayChunks::new(self)
}
+ /// Splits the slice into a slice of `N`-element arrays,
+ /// assuming that there's no remainder.
+ ///
+ /// # Safety
+ ///
+ /// This may only be called when
+ /// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).
+ /// - `N != 0`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_as_chunks)]
+ /// let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+ /// let chunks: &mut [[char; 1]] =
+ /// // SAFETY: 1-element chunks never have remainder
+ /// unsafe { slice.as_chunks_unchecked_mut() };
+ /// chunks[0] = ['L'];
+ /// assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+ /// let chunks: &mut [[char; 3]] =
+ /// // SAFETY: The slice length (6) is a multiple of 3
+ /// unsafe { slice.as_chunks_unchecked_mut() };
+ /// chunks[1] = ['a', 'x', '?'];
+ /// assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+ ///
+ /// // These would be unsound:
+ /// // let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+ /// // let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+ /// ```
+ #[unstable(feature = "slice_as_chunks", issue = "74985")]
+ #[inline]
+ pub unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] {
+ debug_assert_ne!(N, 0);
+ debug_assert_eq!(self.len() % N, 0);
+ let new_len =
+ // SAFETY: Our precondition is exactly what's needed to call this
+ unsafe { crate::intrinsics::exact_div(self.len(), N) };
+ // SAFETY: We cast a slice of `new_len * N` elements into
+ // a slice of `new_len` many `N` elements chunks.
+ unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), new_len) }
+ }
+
+ /// Splits the slice into a slice of `N`-element arrays,
+ /// starting at the beginning of the slice,
+ /// and a remainder slice with length strictly less than `N`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
+ /// error before this method gets stabilized.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_as_chunks)]
+ /// let v = &mut [0, 0, 0, 0, 0];
+ /// let mut count = 1;
+ ///
+ /// let (chunks, remainder) = v.as_chunks_mut();
+ /// remainder[0] = 9;
+ /// for chunk in chunks {
+ /// *chunk = [count; 2];
+ /// count += 1;
+ /// }
+ /// assert_eq!(v, &[1, 1, 2, 2, 9]);
+ /// ```
+ #[unstable(feature = "slice_as_chunks", issue = "74985")]
+ #[inline]
+ pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T]) {
+ assert_ne!(N, 0);
+ let len = self.len() / N;
+ let (multiple_of_n, remainder) = self.split_at_mut(len * N);
+ // SAFETY: We already panicked for zero, and ensured by construction
+ // that the length of the subslice is a multiple of N.
+ let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };
+ (array_slice, remainder)
+ }
+
+ /// Splits the slice into a slice of `N`-element arrays,
+ /// starting at the end of the slice,
+ /// and a remainder slice with length strictly less than `N`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `N` is 0. This check will most probably get changed to a compile time
+ /// error before this method gets stabilized.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_as_chunks)]
+ /// let v = &mut [0, 0, 0, 0, 0];
+ /// let mut count = 1;
+ ///
+ /// let (remainder, chunks) = v.as_rchunks_mut();
+ /// remainder[0] = 9;
+ /// for chunk in chunks {
+ /// *chunk = [count; 2];
+ /// count += 1;
+ /// }
+ /// assert_eq!(v, &[9, 1, 1, 2, 2]);
+ /// ```
+ #[unstable(feature = "slice_as_chunks", issue = "74985")]
+ #[inline]
+ pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]]) {
+ assert_ne!(N, 0);
+ let len = self.len() / N;
+ let (remainder, multiple_of_n) = self.split_at_mut(self.len() - len * N);
+ // SAFETY: We already panicked for zero, and ensured by construction
+ // that the length of the subslice is a multiple of N.
+ let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };
+ (remainder, array_slice)
+ }
+
/// Returns an iterator over `N` elements of the slice at a time, starting at the
/// beginning of the slice.
///
RChunksExactMut::new(self, chunk_size)
}
+ /// Returns an iterator over the slice producing non-overlapping runs
+ /// of elements using the predicate to separate them.
+ ///
+ /// The predicate is called on two elements following themselves,
+ /// it means the predicate is called on `slice[0]` and `slice[1]`
+ /// then on `slice[1]` and `slice[2]` and so on.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_group_by)]
+ ///
+ /// let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+ ///
+ /// let mut iter = slice.group_by(|a, b| a == b);
+ ///
+ /// assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+ /// assert_eq!(iter.next(), Some(&[3, 3][..]));
+ /// assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+ /// assert_eq!(iter.next(), None);
+ /// ```
+ ///
+ /// This method can be used to extract the sorted subslices:
+ ///
+ /// ```
+ /// #![feature(slice_group_by)]
+ ///
+ /// let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+ ///
+ /// let mut iter = slice.group_by(|a, b| a <= b);
+ ///
+ /// assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+ /// assert_eq!(iter.next(), Some(&[2, 3][..]));
+ /// assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+ /// assert_eq!(iter.next(), None);
+ /// ```
+ #[unstable(feature = "slice_group_by", issue = "80552")]
+ #[inline]
+ pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>
+ where
+ F: FnMut(&T, &T) -> bool,
+ {
+ GroupBy::new(self, pred)
+ }
+
+ /// Returns an iterator over the slice producing non-overlapping mutable
+ /// runs of elements using the predicate to separate them.
+ ///
+ /// The predicate is called on two elements following themselves,
+ /// it means the predicate is called on `slice[0]` and `slice[1]`
+ /// then on `slice[1]` and `slice[2]` and so on.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_group_by)]
+ ///
+ /// let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+ ///
+ /// let mut iter = slice.group_by_mut(|a, b| a == b);
+ ///
+ /// assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+ /// assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+ /// assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+ /// assert_eq!(iter.next(), None);
+ /// ```
+ ///
+ /// This method can be used to extract the sorted subslices:
+ ///
+ /// ```
+ /// #![feature(slice_group_by)]
+ ///
+ /// let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+ ///
+ /// let mut iter = slice.group_by_mut(|a, b| a <= b);
+ ///
+ /// assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+ /// assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+ /// assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+ /// assert_eq!(iter.next(), None);
+ /// ```
+ #[unstable(feature = "slice_group_by", issue = "80552")]
+ #[inline]
+ pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>
+ where
+ F: FnMut(&T, &T) -> bool,
+ {
+ GroupByMut::new(self, pred)
+ }
+
/// Divides one slice into two at an index.
///
/// The first will contain all indices from `[0, mid)` (excluding
///
/// ```
/// let mut v = [1, 0, 3, 0, 5, 6];
- /// // scoped to restrict the lifetime of the borrows
- /// {
- /// let (left, right) = v.split_at_mut(2);
- /// assert_eq!(left, [1, 0]);
- /// assert_eq!(right, [3, 0, 5, 6]);
- /// left[1] = 2;
- /// right[1] = 4;
- /// }
+ /// let (left, right) = v.split_at_mut(2);
+ /// assert_eq!(left, [1, 0]);
+ /// assert_eq!(right, [3, 0, 5, 6]);
+ /// left[1] = 2;
+ /// right[1] = 4;
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
/// # Examples
///
/// ```
- /// #![feature(split_inclusive)]
/// let slice = [10, 40, 33, 20];
/// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
///
/// That slice will be the last item returned by the iterator.
///
/// ```
- /// #![feature(split_inclusive)]
/// let slice = [3, 10, 40, 33];
/// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
///
/// assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
/// assert!(iter.next().is_none());
/// ```
- #[unstable(feature = "split_inclusive", issue = "72360")]
+ #[stable(feature = "split_inclusive", since = "1.51.0")]
#[inline]
pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where
/// # Examples
///
/// ```
- /// #![feature(split_inclusive)]
/// let mut v = [10, 40, 30, 20, 60, 50];
///
/// for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
/// }
/// assert_eq!(v, [10, 40, 1, 20, 1, 1]);
/// ```
- #[unstable(feature = "split_inclusive", issue = "72360")]
+ #[stable(feature = "split_inclusive", since = "1.51.0")]
#[inline]
pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where
/// Returns a subslice with the prefix removed.
///
- /// This method returns [`None`] if slice does not start with `prefix`.
- /// Also it returns the original slice if `prefix` is an empty slice.
+ /// If the slice starts with `prefix`, returns the subslice after the prefix, wrapped in `Some`.
+ /// If `prefix` is empty, simply returns the original slice.
+ ///
+ /// If the slice does not start with `prefix`, returns `None`.
///
/// # Examples
///
/// ```
- /// #![feature(slice_strip)]
/// let v = &[10, 40, 30];
/// assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
/// assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
/// assert_eq!(v.strip_prefix(&[50]), None);
/// assert_eq!(v.strip_prefix(&[10, 50]), None);
+ ///
+ /// let prefix : &str = "he";
+ /// assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+ /// Some(b"llo".as_ref()));
/// ```
#[must_use = "returns the subslice without modifying the original"]
- #[unstable(feature = "slice_strip", issue = "73413")]
- pub fn strip_prefix(&self, prefix: &[T]) -> Option<&[T]>
+ #[stable(feature = "slice_strip", since = "1.51.0")]
+ pub fn strip_prefix<P: SlicePattern<Item = T> + ?Sized>(&self, prefix: &P) -> Option<&[T]>
where
T: PartialEq,
{
+ // This function will need rewriting if and when SlicePattern becomes more sophisticated.
+ let prefix = prefix.as_slice();
let n = prefix.len();
if n <= self.len() {
let (head, tail) = self.split_at(n);
/// Returns a subslice with the suffix removed.
///
- /// This method returns [`None`] if slice does not end with `suffix`.
- /// Also it returns the original slice if `suffix` is an empty slice
+ /// If the slice ends with `suffix`, returns the subslice before the suffix, wrapped in `Some`.
+ /// If `suffix` is empty, simply returns the original slice.
+ ///
+ /// If the slice does not end with `suffix`, returns `None`.
///
/// # Examples
///
/// ```
- /// #![feature(slice_strip)]
/// let v = &[10, 40, 30];
/// assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
/// assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
/// assert_eq!(v.strip_suffix(&[50, 30]), None);
/// ```
#[must_use = "returns the subslice without modifying the original"]
- #[unstable(feature = "slice_strip", issue = "73413")]
- pub fn strip_suffix(&self, suffix: &[T]) -> Option<&[T]>
+ #[stable(feature = "slice_strip", since = "1.51.0")]
+ pub fn strip_suffix<P: SlicePattern<Item = T> + ?Sized>(&self, suffix: &P) -> Option<&[T]>
where
T: PartialEq,
{
+ // This function will need rewriting if and when SlicePattern becomes more sophisticated.
+ let suffix = suffix.as_slice();
let (len, n) = (self.len(), suffix.len());
if n <= len {
let (head, tail) = self.split_at(len - n);
/// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
/// (1, 21), (2, 34), (4, 55)];
///
- /// assert_eq!(s.binary_search_by_key(&13, |&(a,b)| b), Ok(9));
- /// assert_eq!(s.binary_search_by_key(&4, |&(a,b)| b), Err(7));
- /// assert_eq!(s.binary_search_by_key(&100, |&(a,b)| b), Err(13));
- /// let r = s.binary_search_by_key(&1, |&(a,b)| b);
+ /// assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
+ /// assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7));
+ /// assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+ /// let r = s.binary_search_by_key(&1, |&(a, b)| b);
/// assert!(match r { Ok(1..=4) => true, _ => false, });
/// ```
#[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
///
/// The comparator function must define a total ordering for the elements in the slice. If
/// the ordering is not total, the order of the elements is unspecified. An order is a
- /// total order if it is (for all a, b and c):
+ /// total order if it is (for all `a`, `b` and `c`):
///
- /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and
- /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >.
+ /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
+ /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
///
/// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
/// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
sort::quicksort(self, |a, b| f(a).lt(&f(b)));
}
+ /// Reorder the slice such that the element at `index` is at its final sorted position.
+ #[unstable(feature = "slice_partition_at_index", issue = "55300")]
+ #[rustc_deprecated(since = "1.49.0", reason = "use the select_nth_unstable() instead")]
+ #[inline]
+ pub fn partition_at_index(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T])
+ where
+ T: Ord,
+ {
+ self.select_nth_unstable(index)
+ }
+
+ /// Reorder the slice with a comparator function such that the element at `index` is at its
+ /// final sorted position.
+ #[unstable(feature = "slice_partition_at_index", issue = "55300")]
+ #[rustc_deprecated(since = "1.49.0", reason = "use select_nth_unstable_by() instead")]
+ #[inline]
+ pub fn partition_at_index_by<F>(
+ &mut self,
+ index: usize,
+ compare: F,
+ ) -> (&mut [T], &mut T, &mut [T])
+ where
+ F: FnMut(&T, &T) -> Ordering,
+ {
+ self.select_nth_unstable_by(index, compare)
+ }
+
+ /// Reorder the slice with a key extraction function such that the element at `index` is at its
+ /// final sorted position.
+ #[unstable(feature = "slice_partition_at_index", issue = "55300")]
+ #[rustc_deprecated(since = "1.49.0", reason = "use the select_nth_unstable_by_key() instead")]
+ #[inline]
+ pub fn partition_at_index_by_key<K, F>(
+ &mut self,
+ index: usize,
+ f: F,
+ ) -> (&mut [T], &mut T, &mut [T])
+ where
+ F: FnMut(&T) -> K,
+ K: Ord,
+ {
+ self.select_nth_unstable_by_key(index, f)
+ }
+
/// Reorder the slice such that the element at `index` is at its final sorted position.
///
/// This reordering has the additional property that any value at position `i < index` will be
/// # Examples
///
/// ```
- /// #![feature(slice_partition_at_index)]
- ///
/// let mut v = [-5i32, 4, 1, -3, 2];
///
/// // Find the median
- /// v.partition_at_index(2);
+ /// v.select_nth_unstable(2);
///
/// // We are only guaranteed the slice will be one of the following, based on the way we sort
/// // about the specified index.
/// v == [-3, -5, 1, 4, 2] ||
/// v == [-5, -3, 1, 4, 2]);
/// ```
- #[unstable(feature = "slice_partition_at_index", issue = "55300")]
+ #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
#[inline]
- pub fn partition_at_index(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T])
+ pub fn select_nth_unstable(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T])
where
T: Ord,
{
/// # Examples
///
/// ```
- /// #![feature(slice_partition_at_index)]
- ///
/// let mut v = [-5i32, 4, 1, -3, 2];
///
/// // Find the median as if the slice were sorted in descending order.
- /// v.partition_at_index_by(2, |a, b| b.cmp(a));
+ /// v.select_nth_unstable_by(2, |a, b| b.cmp(a));
///
/// // We are only guaranteed the slice will be one of the following, based on the way we sort
/// // about the specified index.
/// v == [4, 2, 1, -5, -3] ||
/// v == [4, 2, 1, -3, -5]);
/// ```
- #[unstable(feature = "slice_partition_at_index", issue = "55300")]
+ #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
#[inline]
- pub fn partition_at_index_by<F>(
+ pub fn select_nth_unstable_by<F>(
&mut self,
index: usize,
mut compare: F,
/// # Examples
///
/// ```
- /// #![feature(slice_partition_at_index)]
- ///
/// let mut v = [-5i32, 4, 1, -3, 2];
///
/// // Return the median as if the array were sorted according to absolute value.
- /// v.partition_at_index_by_key(2, |a| a.abs());
+ /// v.select_nth_unstable_by_key(2, |a| a.abs());
///
/// // We are only guaranteed the slice will be one of the following, based on the way we sort
/// // about the specified index.
/// v == [2, 1, -3, 4, -5] ||
/// v == [2, 1, -3, -5, 4]);
/// ```
- #[unstable(feature = "slice_partition_at_index", issue = "55300")]
+ #[stable(feature = "slice_select_nth_unstable", since = "1.49.0")]
#[inline]
- pub fn partition_at_index_by_key<K, F>(
+ pub fn select_nth_unstable_by_key<K, F>(
&mut self,
index: usize,
mut f: F,
/// # Examples
///
/// ```
- /// #![feature(slice_fill)]
- ///
/// let mut buf = vec![0; 10];
/// buf.fill(1);
/// assert_eq!(buf, vec![1; 10]);
/// ```
- #[unstable(feature = "slice_fill", issue = "70758")]
+ #[doc(alias = "memset")]
+ #[stable(feature = "slice_fill", since = "1.50.0")]
pub fn fill(&mut self, value: T)
where
T: Clone,
}
}
+ /// Fills `self` with elements returned by calling a closure repeatedly.
+ ///
+ /// This method uses a closure to create new values. If you'd rather
+ /// [`Clone`] a given value, use [`fill`]. If you want to use the [`Default`]
+ /// trait to generate values, you can pass [`Default::default`] as the
+ /// argument.
+ ///
+ /// [`fill`]: #method.fill
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut buf = vec![1; 10];
+ /// buf.fill_with(Default::default);
+ /// assert_eq!(buf, vec![0; 10]);
+ /// ```
+ #[doc(alias = "memset")]
+ #[stable(feature = "slice_fill_with", since = "1.51.0")]
+ pub fn fill_with<F>(&mut self, mut f: F)
+ where
+ F: FnMut() -> T,
+ {
+ for el in self {
+ *el = f();
+ }
+ }
+
/// Copies the elements from `src` into `self`.
///
/// The length of `src` must be the same as `self`.
///
/// [`clone_from_slice`]: #method.clone_from_slice
/// [`split_at_mut`]: #method.split_at_mut
+ #[doc(alias = "memcpy")]
#[stable(feature = "copy_from_slice", since = "1.9.0")]
pub fn copy_from_slice(&mut self, src: &[T])
where
where
T: Copy,
{
- let Range { start: src_start, end: src_end } = check_range(self.len(), src);
+ let Range { start: src_start, end: src_end } = src.assert_len(self.len());
let count = src_end - src_start;
assert!(dest <= self.len() - count, "dest is out of bounds");
// SAFETY: the conditions for `ptr::copy` have all been checked above,
&mut []
}
}
+
+#[unstable(feature = "slice_pattern", reason = "stopgap trait for slice patterns", issue = "56345")]
+/// Patterns in slices - currently, only used by `strip_prefix` and `strip_suffix`. At a future
+/// point, we hope to generalise `core::str::Pattern` (which at the time of writing is limited to
+/// `str`) to slices, and then this trait will be replaced or abolished.
+pub trait SlicePattern {
+ /// The element type of the slice being matched on.
+ type Item;
+
+ /// Currently, the consumers of `SlicePattern` need a slice.
+ fn as_slice(&self) -> &[Self::Item];
+}
+
+#[stable(feature = "slice_strip", since = "1.51.0")]
+impl<T> SlicePattern for [T] {
+ type Item = T;
+
+ #[inline]
+ fn as_slice(&self) -> &[Self::Item] {
+ self
+ }
+}
+
+#[stable(feature = "slice_strip", since = "1.51.0")]
+impl<T, const N: usize> SlicePattern for [T; N] {
+ type Item = T;
+
+ #[inline]
+ fn as_slice(&self) -> &[Self::Item] {
+ self
+ }
+}