diff options
Diffstat (limited to 'library/core/src/slice/mod.rs')
-rw-r--r-- | library/core/src/slice/mod.rs | 61 |
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, |