summaryrefslogtreecommitdiffstats
path: root/library/core/src/slice/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/core/src/slice/mod.rs61
1 files changed, 47 insertions, 14 deletions
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index d9281a925..d93a3a57e 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -29,13 +29,19 @@ use crate::slice;
/// Pure rust memchr implementation, taken from rust-memchr
pub mod memchr;
+#[unstable(
+ feature = "slice_internals",
+ issue = "none",
+ reason = "exposed from core to be reused in std;"
+)]
+pub mod sort;
+
mod ascii;
mod cmp;
mod index;
mod iter;
mod raw;
mod rotate;
-mod sort;
mod specialize;
#[stable(feature = "rust1", since = "1.0.0")]
@@ -703,7 +709,7 @@ impl<T> [T] {
// Because this function is first compiled in isolation,
// this check tells LLVM that the indexing below is
- // in-bounds. Then after inlining -- once the actual
+ // in-bounds. Then after inlining -- once the actual
// lengths of the slices are known -- it's removed.
let (a, b) = (&mut a[..n], &mut b[..n]);
@@ -781,6 +787,22 @@ impl<T> [T] {
/// let mut iter = slice.windows(4);
/// assert!(iter.next().is_none());
/// ```
+ ///
+ /// There's no `windows_mut`, as that existing would let safe code violate the
+ /// "only one `&mut` at a time to the same thing" rule. However, you can sometimes
+ /// use [`Cell::as_slice_of_cells`](crate::cell::Cell::as_slice_of_cells) in
+ /// conjunction with `windows` to accomplish something similar:
+ /// ```
+ /// use std::cell::Cell;
+ ///
+ /// let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+ /// let slice = &mut array[..];
+ /// let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+ /// for w in slice_of_cells.windows(3) {
+ /// Cell::swap(&w[0], &w[2]);
+ /// }
+ /// assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn windows(&self, size: usize) -> Windows<'_, T> {
@@ -893,7 +915,7 @@ impl<T> [T] {
#[stable(feature = "chunks_exact", since = "1.31.0")]
#[inline]
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
- assert_ne!(chunk_size, 0);
+ assert_ne!(chunk_size, 0, "chunks cannot have a size of zero");
ChunksExact::new(self, chunk_size)
}
@@ -935,7 +957,7 @@ impl<T> [T] {
#[stable(feature = "chunks_exact", since = "1.31.0")]
#[inline]
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
- assert_ne!(chunk_size, 0);
+ assert_ne!(chunk_size, 0, "chunks cannot have a size of zero");
ChunksExactMut::new(self, chunk_size)
}
@@ -1002,11 +1024,22 @@ impl<T> [T] {
/// assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
/// assert_eq!(remainder, &['m']);
/// ```
+ ///
+ /// If you expect the slice to be an exact multiple, you can combine
+ /// `let`-`else` with an empty slice pattern:
+ /// ```
+ /// #![feature(slice_as_chunks)]
+ /// let slice = ['R', 'u', 's', 't'];
+ /// let (chunks, []) = slice.as_chunks::<2>() else {
+ /// panic!("slice didn't have even length")
+ /// };
+ /// assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+ /// ```
#[unstable(feature = "slice_as_chunks", issue = "74985")]
#[inline]
#[must_use]
pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T]) {
- assert_ne!(N, 0);
+ assert_ne!(N, 0, "chunks cannot have a size of zero");
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
@@ -1037,7 +1070,7 @@ impl<T> [T] {
#[inline]
#[must_use]
pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]]) {
- assert_ne!(N, 0);
+ assert_ne!(N, 0, "chunks cannot have a size of zero");
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
@@ -1076,7 +1109,7 @@ impl<T> [T] {
#[unstable(feature = "array_chunks", issue = "74985")]
#[inline]
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
- assert_ne!(N, 0);
+ assert_ne!(N, 0, "chunks cannot have a size of zero");
ArrayChunks::new(self)
}
@@ -1155,7 +1188,7 @@ impl<T> [T] {
#[inline]
#[must_use]
pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T]) {
- assert_ne!(N, 0);
+ assert_ne!(N, 0, "chunks cannot have a size of zero");
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
@@ -1192,7 +1225,7 @@ impl<T> [T] {
#[inline]
#[must_use]
pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]]) {
- assert_ne!(N, 0);
+ assert_ne!(N, 0, "chunks cannot have a size of zero");
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
@@ -1233,11 +1266,11 @@ impl<T> [T] {
#[unstable(feature = "array_chunks", issue = "74985")]
#[inline]
pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
- assert_ne!(N, 0);
+ assert_ne!(N, 0, "chunks cannot have a size of zero");
ArrayChunksMut::new(self)
}
- /// Returns an iterator over overlapping windows of `N` elements of a slice,
+ /// Returns an iterator over overlapping windows of `N` elements of a slice,
/// starting at the beginning of the slice.
///
/// This is the const generic equivalent of [`windows`].
@@ -1265,7 +1298,7 @@ impl<T> [T] {
#[unstable(feature = "array_windows", issue = "75027")]
#[inline]
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
- assert_ne!(N, 0);
+ assert_ne!(N, 0, "windows cannot have a size of zero");
ArrayWindows::new(self)
}
@@ -2465,7 +2498,7 @@ impl<T> [T] {
let mid = left + size / 2;
// SAFETY: the while condition means `size` is strictly positive, so
- // `size/2 < size`. Thus `left + size/2 < left + size`, which
+ // `size/2 < size`. Thus `left + size/2 < left + size`, which
// coupled with the `left + size <= self.len()` invariant means
// we have `left + size/2 < self.len()`, and this is in-bounds.
let cmp = f(unsafe { self.get_unchecked(mid) });
@@ -3795,7 +3828,7 @@ impl<T> [T] {
/// The slice is assumed to be partitioned according to the given predicate.
/// This means that all elements for which the predicate returns true are at the start of the slice
/// and all elements for which the predicate returns false are at the end.
- /// For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0
+ /// For example, `[7, 15, 3, 5, 4, 12, 6]` is partitioned under the predicate `x % 2 != 0`
/// (all odd numbers are at the start, all even at the end).
///
/// If this slice is not partitioned, the returned result is unspecified and meaningless,