library/core/src/slice/mod.rs RUST 5,851 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 5,851.
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.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.