1//! Slice management and manipulation.2//!3//! For more details see [`std::slice`].4//!5//! [`std::slice`]: ../../std/slice/index.html67#![stable(feature = "rust1", since = "1.0.0")]89use crate::clone::TrivialClone;10use crate::cmp::Ordering::{self, Equal, Greater, Less};11use crate::intrinsics::{exact_div, unchecked_sub};12use crate::marker::Destruct;13use crate::mem::{self, MaybeUninit, SizedTypeProperties};14use crate::num::NonZero;15use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive};16use crate::panic::const_panic;17use crate::simd::{self, Simd};18use crate::ub_checks::assert_unsafe_precondition;19use crate::{fmt, hint, ptr, range, slice};2021#[unstable(22 feature = "slice_internals",23 issue = "none",24 reason = "exposed from core to be reused in std; use the memchr crate"25)]26#[doc(hidden)]27/// Pure Rust memchr implementation, taken from rust-memchr28pub mod memchr;2930#[unstable(31 feature = "slice_internals",32 issue = "none",33 reason = "exposed from core to be reused in std;"34)]35#[doc(hidden)]36pub mod sort;3738mod ascii;39mod cmp;40pub(crate) mod index;41mod iter;42mod raw;43mod rotate;44mod specialize;4546#[stable(feature = "inherent_ascii_escape", since = "1.60.0")]47pub use ascii::EscapeAscii;48#[unstable(feature = "str_internals", issue = "none")]49#[doc(hidden)]50pub use ascii::is_ascii_simple;51#[stable(feature = "slice_get_slice", since = "1.28.0")]52pub use index::SliceIndex;53#[unstable(feature = "slice_range", issue = "76393")]54pub use index::{range, try_range};55#[stable(feature = "array_windows", since = "1.94.0")]56pub use iter::ArrayWindows;57#[stable(feature = "slice_group_by", since = "1.77.0")]58pub use iter::{ChunkBy, ChunkByMut};59#[stable(feature = "rust1", since = "1.0.0")]60pub use iter::{Chunks, ChunksMut, Windows};61#[stable(feature = "chunks_exact", since = "1.31.0")]62pub use iter::{ChunksExact, ChunksExactMut};63#[stable(feature = "rust1", since = "1.0.0")]64pub use iter::{Iter, IterMut};65#[stable(feature = "rchunks", since = "1.31.0")]66pub use iter::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};67#[stable(feature = "slice_rsplit", since = "1.27.0")]68pub use iter::{RSplit, RSplitMut};69#[stable(feature = "rust1", since = "1.0.0")]70pub use iter::{RSplitN, RSplitNMut, Split, SplitMut, SplitN, SplitNMut};71#[stable(feature = "split_inclusive", since = "1.51.0")]72pub use iter::{SplitInclusive, SplitInclusiveMut};73#[stable(feature = "from_ref", since = "1.28.0")]74pub use raw::{from_mut, from_ref};75#[unstable(feature = "slice_from_ptr_range", issue = "89792")]76pub use raw::{from_mut_ptr_range, from_ptr_range};77#[stable(feature = "rust1", since = "1.0.0")]78pub use raw::{from_raw_parts, from_raw_parts_mut};7980/// Calculates the direction and split point of a one-sided range.81///82/// This is a helper function for `split_off` and `split_off_mut` that returns83/// the direction of the split (front or back) as well as the index at84/// which to split. Returns `None` if the split index would overflow.85#[inline]86fn split_point_of(range: impl OneSidedRange<usize>) -> Option<(Direction, usize)> {87 use OneSidedRangeBound::{End, EndInclusive, StartInclusive};8889 Some(match range.bound() {90 (StartInclusive, i) => (Direction::Back, i),91 (End, i) => (Direction::Front, i),92 (EndInclusive, i) => (Direction::Front, i.checked_add(1)?),93 })94}9596enum Direction {97 Front,98 Back,99}100101impl<T> [T] {102 /// Returns the number of elements in the slice.103 ///104 /// # Examples105 ///106 /// ```107 /// let a = [1, 2, 3];108 /// assert_eq!(a.len(), 3);109 /// ```110 #[lang = "slice_len_fn"]111 #[stable(feature = "rust1", since = "1.0.0")]112 #[rustc_const_stable(feature = "const_slice_len", since = "1.39.0")]113 #[rustc_no_implicit_autorefs]114 #[inline]115 #[must_use]116 pub const fn len(&self) -> usize {117 ptr::metadata(self)118 }119120 /// Returns `true` if the slice has a length of 0.121 ///122 /// # Examples123 ///124 /// ```125 /// let a = [1, 2, 3];126 /// assert!(!a.is_empty());127 ///128 /// let b: &[i32] = &[];129 /// assert!(b.is_empty());130 /// ```131 #[stable(feature = "rust1", since = "1.0.0")]132 #[rustc_const_stable(feature = "const_slice_is_empty", since = "1.39.0")]133 #[rustc_no_implicit_autorefs]134 #[inline]135 #[must_use]136 pub const fn is_empty(&self) -> bool {137 self.len() == 0138 }139140 /// Returns the first element of the slice, or `None` if it is empty.141 ///142 /// # Examples143 ///144 /// ```145 /// let v = [10, 40, 30];146 /// assert_eq!(Some(&10), v.first());147 ///148 /// let w: &[i32] = &[];149 /// assert_eq!(None, w.first());150 /// ```151 #[stable(feature = "rust1", since = "1.0.0")]152 #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]153 #[inline]154 #[must_use]155 pub const fn first(&self) -> Option<&T> {156 if let [first, ..] = self { Some(first) } else { None }157 }158159 /// Returns a mutable reference to the first element of the slice, or `None` if it is empty.160 ///161 /// # Examples162 ///163 /// ```164 /// let x = &mut [0, 1, 2];165 ///166 /// if let Some(first) = x.first_mut() {167 /// *first = 5;168 /// }169 /// assert_eq!(x, &[5, 1, 2]);170 ///171 /// let y: &mut [i32] = &mut [];172 /// assert_eq!(None, y.first_mut());173 /// ```174 #[stable(feature = "rust1", since = "1.0.0")]175 #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")]176 #[inline]177 #[must_use]178 pub const fn first_mut(&mut self) -> Option<&mut T> {179 if let [first, ..] = self { Some(first) } else { None }180 }181182 /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.183 ///184 /// # Examples185 ///186 /// ```187 /// let x = &[0, 1, 2];188 ///189 /// if let Some((first, elements)) = x.split_first() {190 /// assert_eq!(first, &0);191 /// assert_eq!(elements, &[1, 2]);192 /// }193 /// ```194 #[stable(feature = "slice_splits", since = "1.5.0")]195 #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]196 #[inline]197 #[must_use]198 pub const fn split_first(&self) -> Option<(&T, &[T])> {199 if let [first, tail @ ..] = self { Some((first, tail)) } else { None }200 }201202 /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.203 ///204 /// # Examples205 ///206 /// ```207 /// let x = &mut [0, 1, 2];208 ///209 /// if let Some((first, elements)) = x.split_first_mut() {210 /// *first = 3;211 /// elements[0] = 4;212 /// elements[1] = 5;213 /// }214 /// assert_eq!(x, &[3, 4, 5]);215 /// ```216 #[stable(feature = "slice_splits", since = "1.5.0")]217 #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")]218 #[inline]219 #[must_use]220 pub const fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {221 if let [first, tail @ ..] = self { Some((first, tail)) } else { None }222 }223224 /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.225 ///226 /// # Examples227 ///228 /// ```229 /// let x = &[0, 1, 2];230 ///231 /// if let Some((last, elements)) = x.split_last() {232 /// assert_eq!(last, &2);233 /// assert_eq!(elements, &[0, 1]);234 /// }235 /// ```236 #[stable(feature = "slice_splits", since = "1.5.0")]237 #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]238 #[inline]239 #[must_use]240 pub const fn split_last(&self) -> Option<(&T, &[T])> {241 if let [init @ .., last] = self { Some((last, init)) } else { None }242 }243244 /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.245 ///246 /// # Examples247 ///248 /// ```249 /// let x = &mut [0, 1, 2];250 ///251 /// if let Some((last, elements)) = x.split_last_mut() {252 /// *last = 3;253 /// elements[0] = 4;254 /// elements[1] = 5;255 /// }256 /// assert_eq!(x, &[4, 5, 3]);257 /// ```258 #[stable(feature = "slice_splits", since = "1.5.0")]259 #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")]260 #[inline]261 #[must_use]262 pub const fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {263 if let [init @ .., last] = self { Some((last, init)) } else { None }264 }265266 /// Returns the last element of the slice, or `None` if it is empty.267 ///268 /// # Examples269 ///270 /// ```271 /// let v = [10, 40, 30];272 /// assert_eq!(Some(&30), v.last());273 ///274 /// let w: &[i32] = &[];275 /// assert_eq!(None, w.last());276 /// ```277 #[stable(feature = "rust1", since = "1.0.0")]278 #[rustc_const_stable(feature = "const_slice_first_last_not_mut", since = "1.56.0")]279 #[inline]280 #[must_use]281 pub const fn last(&self) -> Option<&T> {282 if let [.., last] = self { Some(last) } else { None }283 }284285 /// Returns a mutable reference to the last item in the slice, or `None` if it is empty.286 ///287 /// # Examples288 ///289 /// ```290 /// let x = &mut [0, 1, 2];291 ///292 /// if let Some(last) = x.last_mut() {293 /// *last = 10;294 /// }295 /// assert_eq!(x, &[0, 1, 10]);296 ///297 /// let y: &mut [i32] = &mut [];298 /// assert_eq!(None, y.last_mut());299 /// ```300 #[stable(feature = "rust1", since = "1.0.0")]301 #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")]302 #[inline]303 #[must_use]304 pub const fn last_mut(&mut self) -> Option<&mut T> {305 if let [.., last] = self { Some(last) } else { None }306 }307308 /// Returns an array reference to the first `N` items in the slice.309 ///310 /// If the slice is not at least `N` in length, this will return `None`.311 ///312 /// # Examples313 ///314 /// ```315 /// let u = [10, 40, 30];316 /// assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());317 ///318 /// let v: &[i32] = &[10];319 /// assert_eq!(None, v.first_chunk::<2>());320 ///321 /// let w: &[i32] = &[];322 /// assert_eq!(Some(&[]), w.first_chunk::<0>());323 /// ```324 #[inline]325 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]326 #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]327 pub const fn first_chunk<const N: usize>(&self) -> Option<&[T; N]> {328 if self.len() < N {329 None330 } else {331 // SAFETY: We explicitly check for the correct number of elements,332 // and do not let the reference outlive the slice.333 Some(unsafe { &*(self.as_ptr().cast_array()) })334 }335 }336337 /// Returns a mutable array reference to the first `N` items in the slice.338 ///339 /// If the slice is not at least `N` in length, this will return `None`.340 ///341 /// # Examples342 ///343 /// ```344 /// let x = &mut [0, 1, 2];345 ///346 /// if let Some(first) = x.first_chunk_mut::<2>() {347 /// first[0] = 5;348 /// first[1] = 4;349 /// }350 /// assert_eq!(x, &[5, 4, 2]);351 ///352 /// assert_eq!(None, x.first_chunk_mut::<4>());353 /// ```354 #[inline]355 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]356 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]357 pub const fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {358 if self.len() < N {359 None360 } else {361 // SAFETY: We explicitly check for the correct number of elements,362 // do not let the reference outlive the slice,363 // and require exclusive access to the entire slice to mutate the chunk.364 Some(unsafe { &mut *(self.as_mut_ptr().cast_array()) })365 }366 }367368 /// Returns an array reference to the first `N` items in the slice and the remaining slice.369 ///370 /// If the slice is not at least `N` in length, this will return `None`.371 ///372 /// # Examples373 ///374 /// ```375 /// let x = &[0, 1, 2];376 ///377 /// if let Some((first, elements)) = x.split_first_chunk::<2>() {378 /// assert_eq!(first, &[0, 1]);379 /// assert_eq!(elements, &[2]);380 /// }381 ///382 /// assert_eq!(None, x.split_first_chunk::<4>());383 /// ```384 #[inline]385 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]386 #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]387 pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> {388 let Some((first, tail)) = self.split_at_checked(N) else { return None };389390 // SAFETY: We explicitly check for the correct number of elements,391 // and do not let the references outlive the slice.392 Some((unsafe { &*(first.as_ptr().cast_array()) }, tail))393 }394395 /// Returns a mutable array reference to the first `N` items in the slice and the remaining396 /// slice.397 ///398 /// If the slice is not at least `N` in length, this will return `None`.399 ///400 /// # Examples401 ///402 /// ```403 /// let x = &mut [0, 1, 2];404 ///405 /// if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {406 /// first[0] = 3;407 /// first[1] = 4;408 /// elements[0] = 5;409 /// }410 /// assert_eq!(x, &[3, 4, 5]);411 ///412 /// assert_eq!(None, x.split_first_chunk_mut::<4>());413 /// ```414 #[inline]415 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]416 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]417 pub const fn split_first_chunk_mut<const N: usize>(418 &mut self,419 ) -> Option<(&mut [T; N], &mut [T])> {420 let Some((first, tail)) = self.split_at_mut_checked(N) else { return None };421422 // SAFETY: We explicitly check for the correct number of elements,423 // do not let the reference outlive the slice,424 // and enforce exclusive mutability of the chunk by the split.425 Some((unsafe { &mut *(first.as_mut_ptr().cast_array()) }, tail))426 }427428 /// Returns an array reference to the last `N` items in the slice and the remaining slice.429 ///430 /// If the slice is not at least `N` in length, this will return `None`.431 ///432 /// # Examples433 ///434 /// ```435 /// let x = &[0, 1, 2];436 ///437 /// if let Some((elements, last)) = x.split_last_chunk::<2>() {438 /// assert_eq!(elements, &[0]);439 /// assert_eq!(last, &[1, 2]);440 /// }441 ///442 /// assert_eq!(None, x.split_last_chunk::<4>());443 /// ```444 #[inline]445 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]446 #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]447 pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])> {448 let Some(index) = self.len().checked_sub(N) else { return None };449 let (init, last) = self.split_at(index);450451 // SAFETY: We explicitly check for the correct number of elements,452 // and do not let the references outlive the slice.453 Some((init, unsafe { &*(last.as_ptr().cast_array()) }))454 }455456 /// Returns a mutable array reference to the last `N` items in the slice and the remaining457 /// slice.458 ///459 /// If the slice is not at least `N` in length, this will return `None`.460 ///461 /// # Examples462 ///463 /// ```464 /// let x = &mut [0, 1, 2];465 ///466 /// if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {467 /// last[0] = 3;468 /// last[1] = 4;469 /// elements[0] = 5;470 /// }471 /// assert_eq!(x, &[5, 3, 4]);472 ///473 /// assert_eq!(None, x.split_last_chunk_mut::<4>());474 /// ```475 #[inline]476 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]477 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]478 pub const fn split_last_chunk_mut<const N: usize>(479 &mut self,480 ) -> Option<(&mut [T], &mut [T; N])> {481 let Some(index) = self.len().checked_sub(N) else { return None };482 let (init, last) = self.split_at_mut(index);483484 // SAFETY: We explicitly check for the correct number of elements,485 // do not let the reference outlive the slice,486 // and enforce exclusive mutability of the chunk by the split.487 Some((init, unsafe { &mut *(last.as_mut_ptr().cast_array()) }))488 }489490 /// Returns an array reference to the last `N` items in the slice.491 ///492 /// If the slice is not at least `N` in length, this will return `None`.493 ///494 /// # Examples495 ///496 /// ```497 /// let u = [10, 40, 30];498 /// assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());499 ///500 /// let v: &[i32] = &[10];501 /// assert_eq!(None, v.last_chunk::<2>());502 ///503 /// let w: &[i32] = &[];504 /// assert_eq!(Some(&[]), w.last_chunk::<0>());505 /// ```506 #[inline]507 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]508 #[rustc_const_stable(feature = "const_slice_last_chunk", since = "1.80.0")]509 pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]> {510 // FIXME(const-hack): Without const traits, we need this instead of `get`.511 let Some(index) = self.len().checked_sub(N) else { return None };512 let (_, last) = self.split_at(index);513514 // SAFETY: We explicitly check for the correct number of elements,515 // and do not let the references outlive the slice.516 Some(unsafe { &*(last.as_ptr().cast_array()) })517 }518519 /// Returns a mutable array reference to the last `N` items in the slice.520 ///521 /// If the slice is not at least `N` in length, this will return `None`.522 ///523 /// # Examples524 ///525 /// ```526 /// let x = &mut [0, 1, 2];527 ///528 /// if let Some(last) = x.last_chunk_mut::<2>() {529 /// last[0] = 10;530 /// last[1] = 20;531 /// }532 /// assert_eq!(x, &[0, 10, 20]);533 ///534 /// assert_eq!(None, x.last_chunk_mut::<4>());535 /// ```536 #[inline]537 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]538 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]539 pub const fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {540 // FIXME(const-hack): Without const traits, we need this instead of `get`.541 let Some(index) = self.len().checked_sub(N) else { return None };542 let (_, last) = self.split_at_mut(index);543544 // SAFETY: We explicitly check for the correct number of elements,545 // do not let the reference outlive the slice,546 // and require exclusive access to the entire slice to mutate the chunk.547 Some(unsafe { &mut *(last.as_mut_ptr().cast_array()) })548 }549550 /// Returns a reference to an element or subslice depending on the type of551 /// index.552 ///553 /// - If given a position, returns a reference to the element at that554 /// position or `None` if out of bounds.555 /// - If given a range, returns the subslice corresponding to that range,556 /// or `None` if out of bounds.557 ///558 /// # Examples559 ///560 /// ```561 /// let v = [10, 40, 30];562 /// assert_eq!(Some(&40), v.get(1));563 /// assert_eq!(Some(&[10, 40][..]), v.get(0..2));564 /// assert_eq!(None, v.get(3));565 /// assert_eq!(None, v.get(0..4));566 /// ```567 #[stable(feature = "rust1", since = "1.0.0")]568 #[rustc_no_implicit_autorefs]569 #[inline]570 #[must_use]571 #[rustc_const_unstable(feature = "const_index", issue = "143775")]572 pub const fn get<I>(&self, index: I) -> Option<&I::Output>573 where574 I: [const] SliceIndex<Self>,575 {576 index.get(self)577 }578579 /// Returns a mutable reference to an element or subslice depending on the580 /// type of index (see [`get`]) or `None` if the index is out of bounds.581 ///582 /// [`get`]: slice::get583 ///584 /// # Examples585 ///586 /// ```587 /// let x = &mut [0, 1, 2];588 ///589 /// if let Some(elem) = x.get_mut(1) {590 /// *elem = 42;591 /// }592 /// assert_eq!(x, &[0, 42, 2]);593 /// ```594 #[stable(feature = "rust1", since = "1.0.0")]595 #[rustc_no_implicit_autorefs]596 #[inline]597 #[must_use]598 #[rustc_const_unstable(feature = "const_index", issue = "143775")]599 pub const fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>600 where601 I: [const] SliceIndex<Self>,602 {603 index.get_mut(self)604 }605606 /// Returns a reference to an element or subslice, without doing bounds607 /// checking.608 ///609 /// For a safe alternative see [`get`].610 ///611 /// # Safety612 ///613 /// Calling this method with an out-of-bounds index is *[undefined behavior]*614 /// even if the resulting reference is not used.615 ///616 /// You can think of this like `.get(index).unwrap_unchecked()`. It's UB617 /// to call `.get_unchecked(len)`, even if you immediately convert to a618 /// pointer. And it's UB to call `.get_unchecked(..len + 1)`,619 /// `.get_unchecked(..=len)`, or similar.620 ///621 /// [`get`]: slice::get622 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html623 ///624 /// # Examples625 ///626 /// ```627 /// let x = &[1, 2, 4];628 ///629 /// unsafe {630 /// assert_eq!(x.get_unchecked(1), &2);631 /// }632 /// ```633 #[stable(feature = "rust1", since = "1.0.0")]634 #[rustc_no_implicit_autorefs]635 #[inline]636 #[must_use]637 #[track_caller]638 #[rustc_const_unstable(feature = "const_index", issue = "143775")]639 pub const unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output640 where641 I: [const] SliceIndex<Self>,642 {643 // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`;644 // the slice is dereferenceable because `self` is a safe reference.645 // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.646 unsafe { &*index.get_unchecked(self) }647 }648649 /// Returns a mutable reference to an element or subslice, without doing650 /// bounds checking.651 ///652 /// For a safe alternative see [`get_mut`].653 ///654 /// # Safety655 ///656 /// Calling this method with an out-of-bounds index is *[undefined behavior]*657 /// even if the resulting reference is not used.658 ///659 /// You can think of this like `.get_mut(index).unwrap_unchecked()`. It's660 /// UB to call `.get_unchecked_mut(len)`, even if you immediately convert661 /// to a pointer. And it's UB to call `.get_unchecked_mut(..len + 1)`,662 /// `.get_unchecked_mut(..=len)`, or similar.663 ///664 /// [`get_mut`]: slice::get_mut665 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html666 ///667 /// # Examples668 ///669 /// ```670 /// let x = &mut [1, 2, 4];671 ///672 /// unsafe {673 /// let elem = x.get_unchecked_mut(1);674 /// *elem = 13;675 /// }676 /// assert_eq!(x, &[1, 13, 4]);677 /// ```678 #[stable(feature = "rust1", since = "1.0.0")]679 #[rustc_no_implicit_autorefs]680 #[inline]681 #[must_use]682 #[track_caller]683 #[rustc_const_unstable(feature = "const_index", issue = "143775")]684 pub const unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output685 where686 I: [const] SliceIndex<Self>,687 {688 // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`;689 // the slice is dereferenceable because `self` is a safe reference.690 // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.691 unsafe { &mut *index.get_unchecked_mut(self) }692 }693694 /// Returns a raw pointer to the slice's buffer.695 ///696 /// The caller must ensure that the slice outlives the pointer this697 /// function returns, or else it will end up dangling.698 ///699 /// The caller must also ensure that the memory the pointer (non-transitively) points to700 /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer701 /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].702 ///703 /// Modifying the container referenced by this slice may cause its buffer704 /// to be reallocated, which would also make any pointers to it invalid.705 ///706 /// # Examples707 ///708 /// ```709 /// let x = &[1, 2, 4];710 /// let x_ptr = x.as_ptr();711 ///712 /// unsafe {713 /// for i in 0..x.len() {714 /// assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));715 /// }716 /// }717 /// ```718 ///719 /// [`as_mut_ptr`]: slice::as_mut_ptr720 #[stable(feature = "rust1", since = "1.0.0")]721 #[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")]722 #[rustc_never_returns_null_ptr]723 #[rustc_as_ptr]724 #[inline(always)]725 #[must_use]726 pub const fn as_ptr(&self) -> *const T {727 self as *const [T] as *const T728 }729730 /// Returns an unsafe mutable pointer to the slice's buffer.731 ///732 /// The caller must ensure that the slice outlives the pointer this733 /// function returns, or else it will end up dangling.734 ///735 /// Modifying the container referenced by this slice may cause its buffer736 /// to be reallocated, which would also make any pointers to it invalid.737 ///738 /// # Examples739 ///740 /// ```741 /// let x = &mut [1, 2, 4];742 /// let x_ptr = x.as_mut_ptr();743 ///744 /// unsafe {745 /// for i in 0..x.len() {746 /// *x_ptr.add(i) += 2;747 /// }748 /// }749 /// assert_eq!(x, &[3, 4, 6]);750 /// ```751 #[stable(feature = "rust1", since = "1.0.0")]752 #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]753 #[rustc_never_returns_null_ptr]754 #[rustc_as_ptr]755 #[inline(always)]756 #[must_use]757 #[rustc_no_writable]758 pub const fn as_mut_ptr(&mut self) -> *mut T {759 self as *mut [T] as *mut T760 }761762 /// Returns the two raw pointers spanning the slice.763 ///764 /// The returned range is half-open, which means that the end pointer765 /// points *one past* the last element of the slice. This way, an empty766 /// slice is represented by two equal pointers, and the difference between767 /// the two pointers represents the size of the slice.768 ///769 /// See [`as_ptr`] for warnings on using these pointers. The end pointer770 /// requires extra caution, as it does not point to a valid element in the771 /// slice.772 ///773 /// This function is useful for interacting with foreign interfaces which774 /// use two pointers to refer to a range of elements in memory, as is775 /// common in C++.776 ///777 /// It can also be useful to check if a pointer to an element refers to an778 /// element of this slice:779 ///780 /// ```781 /// let a = [1, 2, 3];782 /// let x = &a[1] as *const _;783 /// let y = &5 as *const _;784 ///785 /// assert!(a.as_ptr_range().contains(&x));786 /// assert!(!a.as_ptr_range().contains(&y));787 /// ```788 ///789 /// [`as_ptr`]: slice::as_ptr790 #[stable(feature = "slice_ptr_range", since = "1.48.0")]791 #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]792 #[inline]793 #[must_use]794 pub const fn as_ptr_range(&self) -> Range<*const T> {795 let start = self.as_ptr();796 // SAFETY: The `add` here is safe, because:797 //798 // - Both pointers are part of the same object, as pointing directly799 // past the object also counts.800 //801 // - The size of the slice is never larger than `isize::MAX` bytes, as802 // noted here:803 // - https://github.com/rust-lang/unsafe-code-guidelines/issues/102#issuecomment-473340447804 // - https://doc.rust-lang.org/reference/behavior-considered-undefined.html805 // - https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html#safety806 // (This doesn't seem normative yet, but the very same assumption is807 // made in many places, including the Index implementation of slices.)808 //809 // - There is no wrapping around involved, as slices do not wrap past810 // the end of the address space.811 //812 // See the documentation of [`pointer::add`].813 let end = unsafe { start.add(self.len()) };814 start..end815 }816817 /// Returns the two unsafe mutable pointers spanning the slice.818 ///819 /// The returned range is half-open, which means that the end pointer820 /// points *one past* the last element of the slice. This way, an empty821 /// slice is represented by two equal pointers, and the difference between822 /// the two pointers represents the size of the slice.823 ///824 /// See [`as_mut_ptr`] for warnings on using these pointers. The end825 /// pointer requires extra caution, as it does not point to a valid element826 /// in the slice.827 ///828 /// This function is useful for interacting with foreign interfaces which829 /// use two pointers to refer to a range of elements in memory, as is830 /// common in C++.831 ///832 /// [`as_mut_ptr`]: slice::as_mut_ptr833 #[stable(feature = "slice_ptr_range", since = "1.48.0")]834 #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]835 #[inline]836 #[must_use]837 pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {838 let start = self.as_mut_ptr();839 // SAFETY: See as_ptr_range() above for why `add` here is safe.840 let end = unsafe { start.add(self.len()) };841 start..end842 }843844 /// Gets a reference to the underlying array.845 ///846 /// If `N` is not exactly equal to the length of `self`, then this method returns `None`.847 #[stable(feature = "core_slice_as_array", since = "1.93.0")]848 #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")]849 #[inline]850 #[must_use]851 pub const fn as_array<const N: usize>(&self) -> Option<&[T; N]> {852 if self.len() == N {853 let ptr = self.as_ptr().cast_array();854855 // SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length.856 let me = unsafe { &*ptr };857 Some(me)858 } else {859 None860 }861 }862863 /// Gets a mutable reference to the slice's underlying array.864 ///865 /// If `N` is not exactly equal to the length of `self`, then this method returns `None`.866 #[stable(feature = "core_slice_as_array", since = "1.93.0")]867 #[rustc_const_stable(feature = "core_slice_as_array", since = "1.93.0")]868 #[inline]869 #[must_use]870 pub const fn as_mut_array<const N: usize>(&mut self) -> Option<&mut [T; N]> {871 if self.len() == N {872 let ptr = self.as_mut_ptr().cast_array();873874 // SAFETY: The underlying array of a slice can be reinterpreted as an actual array `[T; N]` if `N` is not greater than the slice's length.875 let me = unsafe { &mut *ptr };876 Some(me)877 } else {878 None879 }880 }881882 /// Swaps two elements in the slice.883 ///884 /// If `a` equals to `b`, it's guaranteed that elements won't change value.885 ///886 /// # Arguments887 ///888 /// * a - The index of the first element889 /// * b - The index of the second element890 ///891 /// # Panics892 ///893 /// Panics if `a` or `b` are out of bounds.894 ///895 /// # Examples896 ///897 /// ```898 /// let mut v = ["a", "b", "c", "d", "e"];899 /// v.swap(2, 4);900 /// assert!(v == ["a", "b", "e", "d", "c"]);901 /// ```902 #[stable(feature = "rust1", since = "1.0.0")]903 #[rustc_const_stable(feature = "const_swap", since = "1.85.0")]904 #[inline]905 #[track_caller]906 pub const fn swap(&mut self, a: usize, b: usize) {907 // FIXME: use swap_unchecked here (https://github.com/rust-lang/rust/pull/88540#issuecomment-944344343)908 // Can't take two mutable loans from one vector, so instead use raw pointers.909 let pa = &raw mut self[a];910 let pb = &raw mut self[b];911 // SAFETY: `pa` and `pb` have been created from safe mutable references and refer912 // to elements in the slice and therefore are guaranteed to be valid and aligned.913 // Note that accessing the elements behind `a` and `b` is checked and will914 // panic when out of bounds.915 unsafe {916 ptr::swap(pa, pb);917 }918 }919920 /// Swaps two elements in the slice, without doing bounds checking.921 ///922 /// For a safe alternative see [`swap`].923 ///924 /// # Arguments925 ///926 /// * a - The index of the first element927 /// * b - The index of the second element928 ///929 /// # Safety930 ///931 /// Calling this method with an out-of-bounds index is *[undefined behavior]*.932 /// The caller has to ensure that `a < self.len()` and `b < self.len()`.933 ///934 /// # Examples935 ///936 /// ```937 /// #![feature(slice_swap_unchecked)]938 ///939 /// let mut v = ["a", "b", "c", "d"];940 /// // SAFETY: we know that 1 and 3 are both indices of the slice941 /// unsafe { v.swap_unchecked(1, 3) };942 /// assert!(v == ["a", "d", "c", "b"]);943 /// ```944 ///945 /// [`swap`]: slice::swap946 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html947 #[unstable(feature = "slice_swap_unchecked", issue = "88539")]948 #[track_caller]949 pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) {950 assert_unsafe_precondition!(951 check_library_ub,952 "slice::swap_unchecked requires that the indices are within the slice",953 (954 len: usize = self.len(),955 a: usize = a,956 b: usize = b,957 ) => a < len && b < len,958 );959960 let ptr = self.as_mut_ptr();961 // SAFETY: caller has to guarantee that `a < self.len()` and `b < self.len()`962 unsafe {963 ptr::swap(ptr.add(a), ptr.add(b));964 }965 }966967 /// Reverses the order of elements in the slice, in place.968 ///969 /// # Examples970 ///971 /// ```972 /// let mut v = [1, 2, 3];973 /// v.reverse();974 /// assert!(v == [3, 2, 1]);975 /// ```976 #[stable(feature = "rust1", since = "1.0.0")]977 #[rustc_const_stable(feature = "const_slice_reverse", since = "1.90.0")]978 #[inline]979 pub const fn reverse(&mut self) {980 let half_len = self.len() / 2;981 let Range { start, end } = self.as_mut_ptr_range();982983 // These slices will skip the middle item for an odd length,984 // since that one doesn't need to move.985 let (front_half, back_half) =986 // SAFETY: Both are subparts of the original slice, so the memory987 // range is valid, and they don't overlap because they're each only988 // half (or less) of the original slice.989 unsafe {990 (991 slice::from_raw_parts_mut(start, half_len),992 slice::from_raw_parts_mut(end.sub(half_len), half_len),993 )994 };995996 // Introducing a function boundary here means that the two halves997 // get `noalias` markers, allowing better optimization as LLVM998 // knows that they're disjoint, unlike in the original slice.999 revswap(front_half, back_half, half_len);10001001 #[inline]1002 const fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) {1003 debug_assert!(a.len() == n);1004 debug_assert!(b.len() == n);10051006 // Because this function is first compiled in isolation,1007 // this check tells LLVM that the indexing below is1008 // in-bounds. Then after inlining -- once the actual1009 // lengths of the slices are known -- it's removed.1010 // FIXME(const_trait_impl) replace with let (a, b) = (&mut a[..n], &mut b[..n]);1011 let (a, _) = a.split_at_mut(n);1012 let (b, _) = b.split_at_mut(n);10131014 let mut i = 0;1015 while i < n {1016 mem::swap(&mut a[i], &mut b[n - 1 - i]);1017 i += 1;1018 }1019 }1020 }10211022 /// Returns an iterator over the slice.1023 ///1024 /// The iterator yields all items from start to end.1025 ///1026 /// # Examples1027 ///1028 /// ```1029 /// let x = &[1, 2, 4];1030 /// let mut iterator = x.iter();1031 ///1032 /// assert_eq!(iterator.next(), Some(&1));1033 /// assert_eq!(iterator.next(), Some(&2));1034 /// assert_eq!(iterator.next(), Some(&4));1035 /// assert_eq!(iterator.next(), None);1036 /// ```1037 #[stable(feature = "rust1", since = "1.0.0")]1038 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1039 #[inline]1040 #[rustc_diagnostic_item = "slice_iter"]1041 pub const fn iter(&self) -> Iter<'_, T> {1042 Iter::new(self)1043 }10441045 /// Returns an iterator that allows modifying each value.1046 ///1047 /// The iterator yields all items from start to end.1048 ///1049 /// # Examples1050 ///1051 /// ```1052 /// let x = &mut [1, 2, 4];1053 /// for elem in x.iter_mut() {1054 /// *elem += 2;1055 /// }1056 /// assert_eq!(x, &[3, 4, 6]);1057 /// ```1058 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1059 #[stable(feature = "rust1", since = "1.0.0")]1060 #[inline]1061 pub const fn iter_mut(&mut self) -> IterMut<'_, T> {1062 IterMut::new(self)1063 }10641065 /// Returns an iterator over all contiguous windows of length1066 /// `size`. The windows overlap. If the slice is shorter than1067 /// `size`, the iterator returns no values.1068 ///1069 /// # Panics1070 ///1071 /// Panics if `size` is zero.1072 ///1073 /// # Examples1074 ///1075 /// ```1076 /// let slice = ['l', 'o', 'r', 'e', 'm'];1077 /// let mut iter = slice.windows(3);1078 /// assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);1079 /// assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);1080 /// assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);1081 /// assert!(iter.next().is_none());1082 /// ```1083 ///1084 /// If the slice is shorter than `size`:1085 ///1086 /// ```1087 /// let slice = ['f', 'o', 'o'];1088 /// let mut iter = slice.windows(4);1089 /// assert!(iter.next().is_none());1090 /// ```1091 ///1092 /// Because the [Iterator] trait cannot represent the required lifetimes,1093 /// there is no `windows_mut` analog to `windows`;1094 /// `[0,1,2].windows_mut(2).collect()` would violate [the rules of references]1095 /// (though a [LendingIterator] analog is possible). You can sometimes use1096 /// [`Cell::as_slice_of_cells`](crate::cell::Cell::as_slice_of_cells) in1097 /// conjunction with `windows` instead:1098 ///1099 /// [the rules of references]: https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references1100 /// [LendingIterator]: https://blog.rust-lang.org/2022/10/28/gats-stabilization.html1101 /// ```1102 /// use std::cell::Cell;1103 ///1104 /// let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];1105 /// let slice = &mut array[..];1106 /// let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();1107 /// for w in slice_of_cells.windows(3) {1108 /// Cell::swap(&w[0], &w[2]);1109 /// }1110 /// assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);1111 /// ```1112 #[stable(feature = "rust1", since = "1.0.0")]1113 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1114 #[inline]1115 #[track_caller]1116 pub const fn windows(&self, size: usize) -> Windows<'_, T> {1117 let size = NonZero::new(size).expect("window size must be non-zero");1118 Windows::new(self, size)1119 }11201121 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the1122 /// beginning of the slice.1123 ///1124 /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the1125 /// slice, then the last chunk will not have length `chunk_size`.1126 ///1127 /// See [`chunks_exact`] for a variant of this iterator that returns chunks of always exactly1128 /// `chunk_size` elements, and [`rchunks`] for the same iterator but starting at the end of the1129 /// slice.1130 ///1131 /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will1132 /// give references to arrays of exactly that length, rather than slices.1133 ///1134 /// # Panics1135 ///1136 /// Panics if `chunk_size` is zero.1137 ///1138 /// # Examples1139 ///1140 /// ```1141 /// let slice = ['l', 'o', 'r', 'e', 'm'];1142 /// let mut iter = slice.chunks(2);1143 /// assert_eq!(iter.next().unwrap(), &['l', 'o']);1144 /// assert_eq!(iter.next().unwrap(), &['r', 'e']);1145 /// assert_eq!(iter.next().unwrap(), &['m']);1146 /// assert!(iter.next().is_none());1147 /// ```1148 ///1149 /// [`chunks_exact`]: slice::chunks_exact1150 /// [`rchunks`]: slice::rchunks1151 /// [`as_chunks`]: slice::as_chunks1152 #[stable(feature = "rust1", since = "1.0.0")]1153 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1154 #[inline]1155 #[track_caller]1156 pub const fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {1157 assert!(chunk_size != 0, "chunk size must be non-zero");1158 Chunks::new(self, chunk_size)1159 }11601161 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the1162 /// beginning of the slice.1163 ///1164 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does not divide the1165 /// length of the slice, then the last chunk will not have length `chunk_size`.1166 ///1167 /// See [`chunks_exact_mut`] for a variant of this iterator that returns chunks of always1168 /// exactly `chunk_size` elements, and [`rchunks_mut`] for the same iterator but starting at1169 /// the end of the slice.1170 ///1171 /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will1172 /// give references to arrays of exactly that length, rather than slices.1173 ///1174 /// # Panics1175 ///1176 /// Panics if `chunk_size` is zero.1177 ///1178 /// # Examples1179 ///1180 /// ```1181 /// let v = &mut [0, 0, 0, 0, 0];1182 /// let mut count = 1;1183 ///1184 /// for chunk in v.chunks_mut(2) {1185 /// for elem in chunk.iter_mut() {1186 /// *elem += count;1187 /// }1188 /// count += 1;1189 /// }1190 /// assert_eq!(v, &[1, 1, 2, 2, 3]);1191 /// ```1192 ///1193 /// [`chunks_exact_mut`]: slice::chunks_exact_mut1194 /// [`rchunks_mut`]: slice::rchunks_mut1195 /// [`as_chunks_mut`]: slice::as_chunks_mut1196 #[stable(feature = "rust1", since = "1.0.0")]1197 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1198 #[inline]1199 #[track_caller]1200 pub const fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {1201 assert!(chunk_size != 0, "chunk size must be non-zero");1202 ChunksMut::new(self, chunk_size)1203 }12041205 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the1206 /// beginning of the slice.1207 ///1208 /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the1209 /// slice, then the last up to `chunk_size-1` elements will be omitted and can be retrieved1210 /// from the `remainder` function of the iterator.1211 ///1212 /// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the1213 /// resulting code better than in the case of [`chunks`].1214 ///1215 /// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller1216 /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice.1217 ///1218 /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will1219 /// give references to arrays of exactly that length, rather than slices.1220 ///1221 /// # Panics1222 ///1223 /// Panics if `chunk_size` is zero.1224 ///1225 /// # Examples1226 ///1227 /// ```1228 /// let slice = ['l', 'o', 'r', 'e', 'm'];1229 /// let mut iter = slice.chunks_exact(2);1230 /// assert_eq!(iter.next().unwrap(), &['l', 'o']);1231 /// assert_eq!(iter.next().unwrap(), &['r', 'e']);1232 /// assert!(iter.next().is_none());1233 /// assert_eq!(iter.remainder(), &['m']);1234 /// ```1235 ///1236 /// [`chunks`]: slice::chunks1237 /// [`rchunks_exact`]: slice::rchunks_exact1238 /// [`as_chunks`]: slice::as_chunks1239 #[stable(feature = "chunks_exact", since = "1.31.0")]1240 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1241 #[inline]1242 #[track_caller]1243 pub const fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {1244 assert!(chunk_size != 0, "chunk size must be non-zero");1245 ChunksExact::new(self, chunk_size)1246 }12471248 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the1249 /// beginning of the slice.1250 ///1251 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does not divide the1252 /// length of the slice, then the last up to `chunk_size-1` elements will be omitted and can be1253 /// retrieved from the `into_remainder` function of the iterator.1254 ///1255 /// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the1256 /// resulting code better than in the case of [`chunks_mut`].1257 ///1258 /// See [`chunks_mut`] for a variant of this iterator that also returns the remainder as a1259 /// smaller chunk, and [`rchunks_exact_mut`] for the same iterator but starting at the end of1260 /// the slice.1261 ///1262 /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will1263 /// give references to arrays of exactly that length, rather than slices.1264 ///1265 /// # Panics1266 ///1267 /// Panics if `chunk_size` is zero.1268 ///1269 /// # Examples1270 ///1271 /// ```1272 /// let v = &mut [0, 0, 0, 0, 0];1273 /// let mut count = 1;1274 ///1275 /// for chunk in v.chunks_exact_mut(2) {1276 /// for elem in chunk.iter_mut() {1277 /// *elem += count;1278 /// }1279 /// count += 1;1280 /// }1281 /// assert_eq!(v, &[1, 1, 2, 2, 0]);1282 /// ```1283 ///1284 /// [`chunks_mut`]: slice::chunks_mut1285 /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut1286 /// [`as_chunks_mut`]: slice::as_chunks_mut1287 #[stable(feature = "chunks_exact", since = "1.31.0")]1288 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1289 #[inline]1290 #[track_caller]1291 pub const fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {1292 assert!(chunk_size != 0, "chunk size must be non-zero");1293 ChunksExactMut::new(self, chunk_size)1294 }12951296 /// Splits the slice into a slice of `N`-element arrays,1297 /// assuming that there's no remainder.1298 ///1299 /// This is the inverse operation to [`as_flattened`].1300 ///1301 /// [`as_flattened`]: slice::as_flattened1302 ///1303 /// As this is `unsafe`, consider whether you could use [`as_chunks`] or1304 /// [`as_rchunks`] instead, perhaps via something like1305 /// `if let (chunks, []) = slice.as_chunks()` or1306 /// `let (chunks, []) = slice.as_chunks() else { unreachable!() };`.1307 ///1308 /// [`as_chunks`]: slice::as_chunks1309 /// [`as_rchunks`]: slice::as_rchunks1310 ///1311 /// # Safety1312 ///1313 /// This may only be called when1314 /// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).1315 /// - `N != 0`.1316 ///1317 /// # Examples1318 ///1319 /// ```1320 /// let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];1321 /// let chunks: &[[char; 1]] =1322 /// // SAFETY: 1-element chunks never have remainder1323 /// unsafe { slice.as_chunks_unchecked() };1324 /// assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);1325 /// let chunks: &[[char; 3]] =1326 /// // SAFETY: The slice length (6) is a multiple of 31327 /// unsafe { slice.as_chunks_unchecked() };1328 /// assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);1329 ///1330 /// // These would be unsound:1331 /// // let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 51332 /// // let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed1333 /// ```1334 #[stable(feature = "slice_as_chunks", since = "1.88.0")]1335 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]1336 #[inline]1337 #[must_use]1338 #[track_caller]1339 pub const unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] {1340 assert_unsafe_precondition!(1341 check_language_ub,1342 "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",1343 (n: usize = N, len: usize = self.len()) => n != 0 && len.is_multiple_of(n),1344 );1345 // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length1346 let new_len = unsafe { exact_div(self.len(), N) };1347 // SAFETY: We cast a slice of `new_len * N` elements into1348 // a slice of `new_len` many `N` elements chunks.1349 unsafe { from_raw_parts(self.as_ptr().cast(), new_len) }1350 }13511352 /// Splits the slice into a slice of `N`-element arrays,1353 /// starting at the beginning of the slice,1354 /// and a remainder slice with length strictly less than `N`.1355 ///1356 /// The remainder is meaningful in the division sense. Given1357 /// `let (chunks, remainder) = slice.as_chunks()`, then:1358 /// - `chunks.len()` equals `slice.len() / N`,1359 /// - `remainder.len()` equals `slice.len() % N`, and1360 /// - `slice.len()` equals `chunks.len() * N + remainder.len()`.1361 ///1362 /// You can flatten the chunks back into a slice-of-`T` with [`as_flattened`].1363 ///1364 /// [`as_flattened`]: slice::as_flattened1365 ///1366 /// # Panics1367 ///1368 /// Panics if `N` is zero.1369 ///1370 /// Note that this check is against a const generic parameter, not a runtime1371 /// value, and thus a particular monomorphization will either always panic1372 /// or it will never panic.1373 ///1374 /// # Examples1375 ///1376 /// ```1377 /// let slice = ['l', 'o', 'r', 'e', 'm'];1378 /// let (chunks, remainder) = slice.as_chunks();1379 /// assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);1380 /// assert_eq!(remainder, &['m']);1381 /// ```1382 ///1383 /// If you expect the slice to be an exact multiple, you can combine1384 /// `let`-`else` with an empty slice pattern:1385 /// ```1386 /// let slice = ['R', 'u', 's', 't'];1387 /// let (chunks, []) = slice.as_chunks::<2>() else {1388 /// panic!("slice didn't have even length")1389 /// };1390 /// assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);1391 /// ```1392 #[stable(feature = "slice_as_chunks", since = "1.88.0")]1393 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]1394 #[inline]1395 #[track_caller]1396 #[must_use]1397 pub const fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T]) {1398 assert!(N != 0, "chunk size must be non-zero");1399 let len_rounded_down = self.len() / N * N;1400 // SAFETY: The rounded-down value is always the same or smaller than the1401 // original length, and thus must be in-bounds of the slice.1402 let (multiple_of_n, remainder) = unsafe { self.split_at_unchecked(len_rounded_down) };1403 // SAFETY: We already panicked for zero, and ensured by construction1404 // that the length of the subslice is a multiple of N.1405 let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };1406 (array_slice, remainder)1407 }14081409 /// Splits the slice into a slice of `N`-element arrays,1410 /// starting at the end of the slice,1411 /// and a remainder slice with length strictly less than `N`.1412 ///1413 /// The remainder is meaningful in the division sense. Given1414 /// `let (remainder, chunks) = slice.as_rchunks()`, then:1415 /// - `remainder.len()` equals `slice.len() % N`,1416 /// - `chunks.len()` equals `slice.len() / N`, and1417 /// - `slice.len()` equals `chunks.len() * N + remainder.len()`.1418 ///1419 /// You can flatten the chunks back into a slice-of-`T` with [`as_flattened`].1420 ///1421 /// [`as_flattened`]: slice::as_flattened1422 ///1423 /// # Panics1424 ///1425 /// Panics if `N` is zero.1426 ///1427 /// Note that this check is against a const generic parameter, not a runtime1428 /// value, and thus a particular monomorphization will either always panic1429 /// or it will never panic.1430 ///1431 /// # Examples1432 ///1433 /// ```1434 /// let slice = ['l', 'o', 'r', 'e', 'm'];1435 /// let (remainder, chunks) = slice.as_rchunks();1436 /// assert_eq!(remainder, &['l']);1437 /// assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);1438 /// ```1439 #[stable(feature = "slice_as_chunks", since = "1.88.0")]1440 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]1441 #[inline]1442 #[track_caller]1443 #[must_use]1444 pub const fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]]) {1445 assert!(N != 0, "chunk size must be non-zero");1446 let len = self.len() / N;1447 let (remainder, multiple_of_n) = self.split_at(self.len() - len * N);1448 // SAFETY: We already panicked for zero, and ensured by construction1449 // that the length of the subslice is a multiple of N.1450 let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };1451 (remainder, array_slice)1452 }14531454 /// Splits the slice into a slice of `N`-element arrays,1455 /// assuming that there's no remainder.1456 ///1457 /// This is the inverse operation to [`as_flattened_mut`].1458 ///1459 /// [`as_flattened_mut`]: slice::as_flattened_mut1460 ///1461 /// As this is `unsafe`, consider whether you could use [`as_chunks_mut`] or1462 /// [`as_rchunks_mut`] instead, perhaps via something like1463 /// `if let (chunks, []) = slice.as_chunks_mut()` or1464 /// `let (chunks, []) = slice.as_chunks_mut() else { unreachable!() };`.1465 ///1466 /// [`as_chunks_mut`]: slice::as_chunks_mut1467 /// [`as_rchunks_mut`]: slice::as_rchunks_mut1468 ///1469 /// # Safety1470 ///1471 /// This may only be called when1472 /// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).1473 /// - `N != 0`.1474 ///1475 /// # Examples1476 ///1477 /// ```1478 /// let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];1479 /// let chunks: &mut [[char; 1]] =1480 /// // SAFETY: 1-element chunks never have remainder1481 /// unsafe { slice.as_chunks_unchecked_mut() };1482 /// chunks[0] = ['L'];1483 /// assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);1484 /// let chunks: &mut [[char; 3]] =1485 /// // SAFETY: The slice length (6) is a multiple of 31486 /// unsafe { slice.as_chunks_unchecked_mut() };1487 /// chunks[1] = ['a', 'x', '?'];1488 /// assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);1489 ///1490 /// // These would be unsound:1491 /// // let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 51492 /// // let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed1493 /// ```1494 #[stable(feature = "slice_as_chunks", since = "1.88.0")]1495 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]1496 #[inline]1497 #[must_use]1498 #[track_caller]1499 pub const unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] {1500 assert_unsafe_precondition!(1501 check_language_ub,1502 "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",1503 (n: usize = N, len: usize = self.len()) => n != 0 && len.is_multiple_of(n)1504 );1505 // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length1506 let new_len = unsafe { exact_div(self.len(), N) };1507 // SAFETY: We cast a slice of `new_len * N` elements into1508 // a slice of `new_len` many `N` elements chunks.1509 unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), new_len) }1510 }15111512 /// Splits the slice into a slice of `N`-element arrays,1513 /// starting at the beginning of the slice,1514 /// and a remainder slice with length strictly less than `N`.1515 ///1516 /// The remainder is meaningful in the division sense. Given1517 /// `let (chunks, remainder) = slice.as_chunks_mut()`, then:1518 /// - `chunks.len()` equals `slice.len() / N`,1519 /// - `remainder.len()` equals `slice.len() % N`, and1520 /// - `slice.len()` equals `chunks.len() * N + remainder.len()`.1521 ///1522 /// You can flatten the chunks back into a slice-of-`T` with [`as_flattened_mut`].1523 ///1524 /// [`as_flattened_mut`]: slice::as_flattened_mut1525 ///1526 /// # Panics1527 ///1528 /// Panics if `N` is zero.1529 ///1530 /// Note that this check is against a const generic parameter, not a runtime1531 /// value, and thus a particular monomorphization will either always panic1532 /// or it will never panic.1533 ///1534 /// # Examples1535 ///1536 /// ```1537 /// let v = &mut [0, 0, 0, 0, 0];1538 /// let mut count = 1;1539 ///1540 /// let (chunks, remainder) = v.as_chunks_mut();1541 /// remainder[0] = 9;1542 /// for chunk in chunks {1543 /// *chunk = [count; 2];1544 /// count += 1;1545 /// }1546 /// assert_eq!(v, &[1, 1, 2, 2, 9]);1547 /// ```1548 #[stable(feature = "slice_as_chunks", since = "1.88.0")]1549 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]1550 #[inline]1551 #[track_caller]1552 #[must_use]1553 pub const fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T]) {1554 assert!(N != 0, "chunk size must be non-zero");1555 let len_rounded_down = self.len() / N * N;1556 // SAFETY: The rounded-down value is always the same or smaller than the1557 // original length, and thus must be in-bounds of the slice.1558 let (multiple_of_n, remainder) = unsafe { self.split_at_mut_unchecked(len_rounded_down) };1559 // SAFETY: We already panicked for zero, and ensured by construction1560 // that the length of the subslice is a multiple of N.1561 let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };1562 (array_slice, remainder)1563 }15641565 /// Splits the slice into a slice of `N`-element arrays,1566 /// starting at the end of the slice,1567 /// and a remainder slice with length strictly less than `N`.1568 ///1569 /// The remainder is meaningful in the division sense. Given1570 /// `let (remainder, chunks) = slice.as_rchunks_mut()`, then:1571 /// - `remainder.len()` equals `slice.len() % N`,1572 /// - `chunks.len()` equals `slice.len() / N`, and1573 /// - `slice.len()` equals `chunks.len() * N + remainder.len()`.1574 ///1575 /// You can flatten the chunks back into a slice-of-`T` with [`as_flattened_mut`].1576 ///1577 /// [`as_flattened_mut`]: slice::as_flattened_mut1578 ///1579 /// # Panics1580 ///1581 /// Panics if `N` is zero.1582 ///1583 /// Note that this check is against a const generic parameter, not a runtime1584 /// value, and thus a particular monomorphization will either always panic1585 /// or it will never panic.1586 ///1587 /// # Examples1588 ///1589 /// ```1590 /// let v = &mut [0, 0, 0, 0, 0];1591 /// let mut count = 1;1592 ///1593 /// let (remainder, chunks) = v.as_rchunks_mut();1594 /// remainder[0] = 9;1595 /// for chunk in chunks {1596 /// *chunk = [count; 2];1597 /// count += 1;1598 /// }1599 /// assert_eq!(v, &[9, 1, 1, 2, 2]);1600 /// ```1601 #[stable(feature = "slice_as_chunks", since = "1.88.0")]1602 #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")]1603 #[inline]1604 #[track_caller]1605 #[must_use]1606 pub const fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]]) {1607 assert!(N != 0, "chunk size must be non-zero");1608 let len = self.len() / N;1609 let (remainder, multiple_of_n) = self.split_at_mut(self.len() - len * N);1610 // SAFETY: We already panicked for zero, and ensured by construction1611 // that the length of the subslice is a multiple of N.1612 let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };1613 (remainder, array_slice)1614 }16151616 /// Returns an iterator over overlapping windows of `N` elements of a slice,1617 /// starting at the beginning of the slice.1618 ///1619 /// This is the const generic equivalent of [`windows`].1620 ///1621 /// If `N` is greater than the size of the slice, it will return no windows.1622 ///1623 /// # Panics1624 ///1625 /// Panics if `N` is zero.1626 ///1627 /// Note that this check is against a const generic parameter, not a runtime1628 /// value, and thus a particular monomorphization will either always panic1629 /// or it will never panic.1630 ///1631 /// # Examples1632 ///1633 /// ```1634 /// let slice = [0, 1, 2, 3];1635 /// let mut iter = slice.array_windows();1636 /// assert_eq!(iter.next().unwrap(), &[0, 1]);1637 /// assert_eq!(iter.next().unwrap(), &[1, 2]);1638 /// assert_eq!(iter.next().unwrap(), &[2, 3]);1639 /// assert!(iter.next().is_none());1640 /// ```1641 ///1642 /// [`windows`]: slice::windows1643 #[stable(feature = "array_windows", since = "1.94.0")]1644 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1645 #[inline]1646 #[track_caller]1647 pub const fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {1648 assert!(N != 0, "window size must be non-zero");1649 ArrayWindows::new(self)1650 }16511652 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end1653 /// of the slice.1654 ///1655 /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the1656 /// slice, then the last chunk will not have length `chunk_size`.1657 ///1658 /// See [`rchunks_exact`] for a variant of this iterator that returns chunks of always exactly1659 /// `chunk_size` elements, and [`chunks`] for the same iterator but starting at the beginning1660 /// of the slice.1661 ///1662 /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will1663 /// give references to arrays of exactly that length, rather than slices.1664 ///1665 /// # Panics1666 ///1667 /// Panics if `chunk_size` is zero.1668 ///1669 /// # Examples1670 ///1671 /// ```1672 /// let slice = ['l', 'o', 'r', 'e', 'm'];1673 /// let mut iter = slice.rchunks(2);1674 /// assert_eq!(iter.next().unwrap(), &['e', 'm']);1675 /// assert_eq!(iter.next().unwrap(), &['o', 'r']);1676 /// assert_eq!(iter.next().unwrap(), &['l']);1677 /// assert!(iter.next().is_none());1678 /// ```1679 ///1680 /// [`rchunks_exact`]: slice::rchunks_exact1681 /// [`chunks`]: slice::chunks1682 /// [`as_rchunks`]: slice::as_rchunks1683 #[stable(feature = "rchunks", since = "1.31.0")]1684 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1685 #[inline]1686 #[track_caller]1687 pub const fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {1688 assert!(chunk_size != 0, "chunk size must be non-zero");1689 RChunks::new(self, chunk_size)1690 }16911692 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end1693 /// of the slice.1694 ///1695 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does not divide the1696 /// length of the slice, then the last chunk will not have length `chunk_size`.1697 ///1698 /// See [`rchunks_exact_mut`] for a variant of this iterator that returns chunks of always1699 /// exactly `chunk_size` elements, and [`chunks_mut`] for the same iterator but starting at the1700 /// beginning of the slice.1701 ///1702 /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will1703 /// give references to arrays of exactly that length, rather than slices.1704 ///1705 /// # Panics1706 ///1707 /// Panics if `chunk_size` is zero.1708 ///1709 /// # Examples1710 ///1711 /// ```1712 /// let v = &mut [0, 0, 0, 0, 0];1713 /// let mut count = 1;1714 ///1715 /// for chunk in v.rchunks_mut(2) {1716 /// for elem in chunk.iter_mut() {1717 /// *elem += count;1718 /// }1719 /// count += 1;1720 /// }1721 /// assert_eq!(v, &[3, 2, 2, 1, 1]);1722 /// ```1723 ///1724 /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut1725 /// [`chunks_mut`]: slice::chunks_mut1726 /// [`as_rchunks_mut`]: slice::as_rchunks_mut1727 #[stable(feature = "rchunks", since = "1.31.0")]1728 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1729 #[inline]1730 #[track_caller]1731 pub const fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {1732 assert!(chunk_size != 0, "chunk size must be non-zero");1733 RChunksMut::new(self, chunk_size)1734 }17351736 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the1737 /// end of the slice.1738 ///1739 /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the1740 /// slice, then the last up to `chunk_size-1` elements will be omitted and can be retrieved1741 /// from the `remainder` function of the iterator.1742 ///1743 /// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the1744 /// resulting code better than in the case of [`rchunks`].1745 ///1746 /// See [`rchunks`] for a variant of this iterator that also returns the remainder as a smaller1747 /// chunk, and [`chunks_exact`] for the same iterator but starting at the beginning of the1748 /// slice.1749 ///1750 /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will1751 /// give references to arrays of exactly that length, rather than slices.1752 ///1753 /// # Panics1754 ///1755 /// Panics if `chunk_size` is zero.1756 ///1757 /// # Examples1758 ///1759 /// ```1760 /// let slice = ['l', 'o', 'r', 'e', 'm'];1761 /// let mut iter = slice.rchunks_exact(2);1762 /// assert_eq!(iter.next().unwrap(), &['e', 'm']);1763 /// assert_eq!(iter.next().unwrap(), &['o', 'r']);1764 /// assert!(iter.next().is_none());1765 /// assert_eq!(iter.remainder(), &['l']);1766 /// ```1767 ///1768 /// [`chunks`]: slice::chunks1769 /// [`rchunks`]: slice::rchunks1770 /// [`chunks_exact`]: slice::chunks_exact1771 /// [`as_rchunks`]: slice::as_rchunks1772 #[stable(feature = "rchunks", since = "1.31.0")]1773 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1774 #[inline]1775 #[track_caller]1776 pub const fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {1777 assert!(chunk_size != 0, "chunk size must be non-zero");1778 RChunksExact::new(self, chunk_size)1779 }17801781 /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end1782 /// of the slice.1783 ///1784 /// The chunks are mutable slices, and do not overlap. If `chunk_size` does not divide the1785 /// length of the slice, then the last up to `chunk_size-1` elements will be omitted and can be1786 /// retrieved from the `into_remainder` function of the iterator.1787 ///1788 /// Due to each chunk having exactly `chunk_size` elements, the compiler can often optimize the1789 /// resulting code better than in the case of [`chunks_mut`].1790 ///1791 /// See [`rchunks_mut`] for a variant of this iterator that also returns the remainder as a1792 /// smaller chunk, and [`chunks_exact_mut`] for the same iterator but starting at the beginning1793 /// of the slice.1794 ///1795 /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will1796 /// give references to arrays of exactly that length, rather than slices.1797 ///1798 /// # Panics1799 ///1800 /// Panics if `chunk_size` is zero.1801 ///1802 /// # Examples1803 ///1804 /// ```1805 /// let v = &mut [0, 0, 0, 0, 0];1806 /// let mut count = 1;1807 ///1808 /// for chunk in v.rchunks_exact_mut(2) {1809 /// for elem in chunk.iter_mut() {1810 /// *elem += count;1811 /// }1812 /// count += 1;1813 /// }1814 /// assert_eq!(v, &[0, 2, 2, 1, 1]);1815 /// ```1816 ///1817 /// [`chunks_mut`]: slice::chunks_mut1818 /// [`rchunks_mut`]: slice::rchunks_mut1819 /// [`chunks_exact_mut`]: slice::chunks_exact_mut1820 /// [`as_rchunks_mut`]: slice::as_rchunks_mut1821 #[stable(feature = "rchunks", since = "1.31.0")]1822 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1823 #[inline]1824 #[track_caller]1825 pub const fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {1826 assert!(chunk_size != 0, "chunk size must be non-zero");1827 RChunksExactMut::new(self, chunk_size)1828 }18291830 /// Returns an iterator over the slice producing non-overlapping runs1831 /// of elements using the predicate to separate them.1832 ///1833 /// The predicate is called for every pair of consecutive elements,1834 /// meaning that it is called on `slice[0]` and `slice[1]`,1835 /// followed by `slice[1]` and `slice[2]`, and so on.1836 ///1837 /// # Examples1838 ///1839 /// ```1840 /// let slice = &[1, 1, 1, 3, 3, 2, 2, 2];1841 ///1842 /// let mut iter = slice.chunk_by(|a, b| a == b);1843 ///1844 /// assert_eq!(iter.next(), Some(&[1, 1, 1][..]));1845 /// assert_eq!(iter.next(), Some(&[3, 3][..]));1846 /// assert_eq!(iter.next(), Some(&[2, 2, 2][..]));1847 /// assert_eq!(iter.next(), None);1848 /// ```1849 ///1850 /// This method can be used to extract the sorted subslices:1851 ///1852 /// ```1853 /// let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];1854 ///1855 /// let mut iter = slice.chunk_by(|a, b| a <= b);1856 ///1857 /// assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));1858 /// assert_eq!(iter.next(), Some(&[2, 3][..]));1859 /// assert_eq!(iter.next(), Some(&[2, 3, 4][..]));1860 /// assert_eq!(iter.next(), None);1861 /// ```1862 #[stable(feature = "slice_group_by", since = "1.77.0")]1863 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1864 #[inline]1865 pub const fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>1866 where1867 F: FnMut(&T, &T) -> bool,1868 {1869 ChunkBy::new(self, pred)1870 }18711872 /// Returns an iterator over the slice producing non-overlapping mutable1873 /// runs of elements using the predicate to separate them.1874 ///1875 /// The predicate is called for every pair of consecutive elements,1876 /// meaning that it is called on `slice[0]` and `slice[1]`,1877 /// followed by `slice[1]` and `slice[2]`, and so on.1878 ///1879 /// # Examples1880 ///1881 /// ```1882 /// let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];1883 ///1884 /// let mut iter = slice.chunk_by_mut(|a, b| a == b);1885 ///1886 /// assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));1887 /// assert_eq!(iter.next(), Some(&mut [3, 3][..]));1888 /// assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));1889 /// assert_eq!(iter.next(), None);1890 /// ```1891 ///1892 /// This method can be used to extract the sorted subslices:1893 ///1894 /// ```1895 /// let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];1896 ///1897 /// let mut iter = slice.chunk_by_mut(|a, b| a <= b);1898 ///1899 /// assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));1900 /// assert_eq!(iter.next(), Some(&mut [2, 3][..]));1901 /// assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));1902 /// assert_eq!(iter.next(), None);1903 /// ```1904 #[stable(feature = "slice_group_by", since = "1.77.0")]1905 #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]1906 #[inline]1907 pub const fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>1908 where1909 F: FnMut(&T, &T) -> bool,1910 {1911 ChunkByMut::new(self, pred)1912 }19131914 /// Divides one slice into two at an index.1915 ///1916 /// The first will contain all indices from `[0, mid)` (excluding1917 /// the index `mid` itself) and the second will contain all1918 /// indices from `[mid, len)` (excluding the index `len` itself).1919 ///1920 /// # Panics1921 ///1922 /// Panics if `mid > len`. For a non-panicking alternative see1923 /// [`split_at_checked`](slice::split_at_checked).1924 ///1925 /// # Examples1926 ///1927 /// ```1928 /// let v = ['a', 'b', 'c'];1929 ///1930 /// {1931 /// let (left, right) = v.split_at(0);1932 /// assert_eq!(left, []);1933 /// assert_eq!(right, ['a', 'b', 'c']);1934 /// }1935 ///1936 /// {1937 /// let (left, right) = v.split_at(2);1938 /// assert_eq!(left, ['a', 'b']);1939 /// assert_eq!(right, ['c']);1940 /// }1941 ///1942 /// {1943 /// let (left, right) = v.split_at(3);1944 /// assert_eq!(left, ['a', 'b', 'c']);1945 /// assert_eq!(right, []);1946 /// }1947 /// ```1948 #[stable(feature = "rust1", since = "1.0.0")]1949 #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "1.71.0")]1950 #[inline]1951 #[track_caller]1952 #[must_use]1953 pub const fn split_at(&self, mid: usize) -> (&[T], &[T]) {1954 match self.split_at_checked(mid) {1955 Some(pair) => pair,1956 None => panic!("mid > len"),1957 }1958 }19591960 /// Divides one mutable slice into two at an index.1961 ///1962 /// The first will contain all indices from `[0, mid)` (excluding1963 /// the index `mid` itself) and the second will contain all1964 /// indices from `[mid, len)` (excluding the index `len` itself).1965 ///1966 /// # Panics1967 ///1968 /// Panics if `mid > len`. For a non-panicking alternative see1969 /// [`split_at_mut_checked`](slice::split_at_mut_checked).1970 ///1971 /// # Examples1972 ///1973 /// ```1974 /// let mut v = [1, 0, 3, 0, 5, 6];1975 /// let (left, right) = v.split_at_mut(2);1976 /// assert_eq!(left, [1, 0]);1977 /// assert_eq!(right, [3, 0, 5, 6]);1978 /// left[1] = 2;1979 /// right[1] = 4;1980 /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);1981 /// ```1982 #[stable(feature = "rust1", since = "1.0.0")]1983 #[inline]1984 #[track_caller]1985 #[must_use]1986 #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")]1987 pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {1988 match self.split_at_mut_checked(mid) {1989 Some(pair) => pair,1990 None => panic!("mid > len"),1991 }1992 }19931994 /// Divides one slice into two at an index, without doing bounds checking.1995 ///1996 /// The first will contain all indices from `[0, mid)` (excluding1997 /// the index `mid` itself) and the second will contain all1998 /// indices from `[mid, len)` (excluding the index `len` itself).1999 ///2000 /// For a safe alternative see [`split_at`].
Findings
✓ No findings reported for this file.