core/slice/
iter.rs

1//! Definitions of a bunch of iterators for `[T]`.
2
3#[macro_use] // import iterator! and forward_iterator!
4mod macros;
5
6use super::{from_raw_parts, from_raw_parts_mut};
7use crate::hint::assert_unchecked;
8#[cfg(not(feature = "ferrocene_certified"))]
9use crate::iter::{
10    FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, UncheckedIterator,
11};
12use crate::marker::PhantomData;
13#[cfg(not(feature = "ferrocene_certified"))]
14use crate::mem::{self, SizedTypeProperties};
15use crate::num::NonZero;
16use crate::ptr::{NonNull, without_provenance, without_provenance_mut};
17#[cfg(not(feature = "ferrocene_certified"))]
18use crate::{cmp, fmt};
19
20// Ferrocene addition: imports for certified subset
21#[cfg(feature = "ferrocene_certified")]
22#[rustfmt::skip]
23use crate::{
24    cmp,
25    iter::{TrustedLen, UncheckedIterator},
26    mem,
27    mem::SizedTypeProperties,
28};
29
30#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
31impl<T> !Iterator for [T] {}
32
33#[stable(feature = "rust1", since = "1.0.0")]
34impl<'a, T> IntoIterator for &'a [T] {
35    type Item = &'a T;
36    type IntoIter = Iter<'a, T>;
37
38    fn into_iter(self) -> Iter<'a, T> {
39        self.iter()
40    }
41}
42
43#[stable(feature = "rust1", since = "1.0.0")]
44impl<'a, T> IntoIterator for &'a mut [T] {
45    type Item = &'a mut T;
46    type IntoIter = IterMut<'a, T>;
47
48    fn into_iter(self) -> IterMut<'a, T> {
49        self.iter_mut()
50    }
51}
52
53/// Immutable slice iterator
54///
55/// This struct is created by the [`iter`] method on [slices].
56///
57/// # Examples
58///
59/// Basic usage:
60///
61/// ```
62/// // First, we need a slice to call the `iter` method on:
63/// let slice = &[1, 2, 3];
64///
65/// // Then we call `iter` on the slice to get the `Iter` iterator,
66/// // and iterate over it:
67/// for element in slice.iter() {
68///     println!("{element}");
69/// }
70///
71/// // This for loop actually already works without calling `iter`:
72/// for element in slice {
73///     println!("{element}");
74/// }
75/// ```
76///
77/// [`iter`]: slice::iter
78/// [slices]: slice
79#[stable(feature = "rust1", since = "1.0.0")]
80#[must_use = "iterators are lazy and do nothing unless consumed"]
81#[rustc_diagnostic_item = "SliceIter"]
82pub struct Iter<'a, T: 'a> {
83    /// The pointer to the next element to return, or the past-the-end location
84    /// if the iterator is empty.
85    ///
86    /// This address will be used for all ZST elements, never changed.
87    ptr: NonNull<T>,
88    /// For non-ZSTs, the non-null pointer to the past-the-end element.
89    ///
90    /// For ZSTs, this is `ptr::without_provenance_mut(len)`.
91    end_or_len: *const T,
92    _marker: PhantomData<&'a T>,
93}
94
95#[stable(feature = "core_impl_debug", since = "1.9.0")]
96#[cfg(not(feature = "ferrocene_certified"))]
97impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        f.debug_tuple("Iter").field(&self.as_slice()).finish()
100    }
101}
102
103#[stable(feature = "rust1", since = "1.0.0")]
104unsafe impl<T: Sync> Sync for Iter<'_, T> {}
105#[stable(feature = "rust1", since = "1.0.0")]
106unsafe impl<T: Sync> Send for Iter<'_, T> {}
107
108impl<'a, T> Iter<'a, T> {
109    #[inline]
110    pub(super) const fn new(slice: &'a [T]) -> Self {
111        let len = slice.len();
112        let ptr: NonNull<T> = NonNull::from_ref(slice).cast();
113        // SAFETY: Similar to `IterMut::new`.
114        unsafe {
115            let end_or_len =
116                if T::IS_ZST { without_provenance(len) } else { ptr.as_ptr().add(len) };
117
118            Self { ptr, end_or_len, _marker: PhantomData }
119        }
120    }
121
122    /// Views the underlying data as a subslice of the original data.
123    ///
124    /// # Examples
125    ///
126    /// Basic usage:
127    ///
128    /// ```
129    /// // First, we need a slice to call the `iter` method on:
130    /// let slice = &[1, 2, 3];
131    ///
132    /// // Then we call `iter` on the slice to get the `Iter` iterator:
133    /// let mut iter = slice.iter();
134    /// // Here `as_slice` still returns the whole slice, so this prints "[1, 2, 3]":
135    /// println!("{:?}", iter.as_slice());
136    ///
137    /// // Now, we call the `next` method to remove the first element from the iterator:
138    /// iter.next();
139    /// // Here the iterator does not contain the first element of the slice any more,
140    /// // so `as_slice` only returns the last two elements of the slice,
141    /// // and so this prints "[2, 3]":
142    /// println!("{:?}", iter.as_slice());
143    ///
144    /// // The underlying slice has not been modified and still contains three elements,
145    /// // so this prints "[1, 2, 3]":
146    /// println!("{:?}", slice);
147    /// ```
148    #[must_use]
149    #[stable(feature = "iter_to_slice", since = "1.4.0")]
150    #[inline]
151    pub fn as_slice(&self) -> &'a [T] {
152        self.make_slice()
153    }
154}
155
156iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, as_ref, {
157    #[cfg(not(feature = "ferrocene_certified"))]
158    fn is_sorted_by<F>(self, mut compare: F) -> bool
159    where
160        Self: Sized,
161        F: FnMut(&Self::Item, &Self::Item) -> bool,
162    {
163        self.as_slice().is_sorted_by(|a, b| compare(&a, &b))
164    }
165}}
166
167#[stable(feature = "rust1", since = "1.0.0")]
168#[cfg(not(feature = "ferrocene_certified"))]
169impl<T> Clone for Iter<'_, T> {
170    #[inline]
171    fn clone(&self) -> Self {
172        Iter { ptr: self.ptr, end_or_len: self.end_or_len, _marker: self._marker }
173    }
174}
175
176#[stable(feature = "slice_iter_as_ref", since = "1.13.0")]
177#[cfg(not(feature = "ferrocene_certified"))]
178impl<T> AsRef<[T]> for Iter<'_, T> {
179    #[inline]
180    fn as_ref(&self) -> &[T] {
181        self.as_slice()
182    }
183}
184
185/// Mutable slice iterator.
186///
187/// This struct is created by the [`iter_mut`] method on [slices].
188///
189/// # Examples
190///
191/// Basic usage:
192///
193/// ```
194/// // First, we need a slice to call the `iter_mut` method on:
195/// let slice = &mut [1, 2, 3];
196///
197/// // Then we call `iter_mut` on the slice to get the `IterMut` iterator,
198/// // iterate over it and increment each element value:
199/// for element in slice.iter_mut() {
200///     *element += 1;
201/// }
202///
203/// // We now have "[2, 3, 4]":
204/// println!("{slice:?}");
205/// ```
206///
207/// [`iter_mut`]: slice::iter_mut
208/// [slices]: slice
209#[stable(feature = "rust1", since = "1.0.0")]
210#[must_use = "iterators are lazy and do nothing unless consumed"]
211pub struct IterMut<'a, T: 'a> {
212    /// The pointer to the next element to return, or the past-the-end location
213    /// if the iterator is empty.
214    ///
215    /// This address will be used for all ZST elements, never changed.
216    ptr: NonNull<T>,
217    /// For non-ZSTs, the non-null pointer to the past-the-end element.
218    ///
219    /// For ZSTs, this is `ptr::without_provenance_mut(len)`.
220    end_or_len: *mut T,
221    _marker: PhantomData<&'a mut T>,
222}
223
224#[stable(feature = "core_impl_debug", since = "1.9.0")]
225#[cfg(not(feature = "ferrocene_certified"))]
226impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
227    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228        f.debug_tuple("IterMut").field(&self.make_slice()).finish()
229    }
230}
231
232#[stable(feature = "rust1", since = "1.0.0")]
233unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
234#[stable(feature = "rust1", since = "1.0.0")]
235unsafe impl<T: Send> Send for IterMut<'_, T> {}
236
237impl<'a, T> IterMut<'a, T> {
238    #[inline]
239    pub(super) const fn new(slice: &'a mut [T]) -> Self {
240        let len = slice.len();
241        let ptr: NonNull<T> = NonNull::from_mut(slice).cast();
242        // SAFETY: There are several things here:
243        //
244        // `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid
245        // reference thus it is non-NUL and safe to use and pass to
246        // `NonNull::new_unchecked` .
247        //
248        // Adding `slice.len()` to the starting pointer gives a pointer
249        // at the end of `slice`. `end` will never be dereferenced, only checked
250        // for direct pointer equality with `ptr` to check if the iterator is
251        // done.
252        //
253        // In the case of a ZST, the end pointer is just the length.  It's never
254        // used as a pointer at all, and thus it's fine to have no provenance.
255        //
256        // See the `next_unchecked!` and `is_empty!` macros as well as the
257        // `post_inc_start` method for more information.
258        unsafe {
259            let end_or_len =
260                if T::IS_ZST { without_provenance_mut(len) } else { ptr.as_ptr().add(len) };
261
262            Self { ptr, end_or_len, _marker: PhantomData }
263        }
264    }
265
266    /// Views the underlying data as a subslice of the original data.
267    ///
268    /// To avoid creating `&mut` references that alias, this is forced
269    /// to consume the iterator.
270    ///
271    /// # Examples
272    ///
273    /// Basic usage:
274    ///
275    /// ```
276    /// // First, we need a slice to call the `iter_mut` method on:
277    /// let mut slice = &mut [1, 2, 3];
278    ///
279    /// // Then we call `iter_mut` on the slice to get the `IterMut` struct:
280    /// let mut iter = slice.iter_mut();
281    /// // Now, we call the `next` method to remove the first element of the iterator,
282    /// // unwrap and dereference what we get from `next` and increase its value by 1:
283    /// *iter.next().unwrap() += 1;
284    /// // Here the iterator does not contain the first element of the slice any more,
285    /// // so `into_slice` only returns the last two elements of the slice,
286    /// // and so this prints "[2, 3]":
287    /// println!("{:?}", iter.into_slice());
288    /// // The underlying slice still contains three elements, but its first element
289    /// // was increased by 1, so this prints "[2, 2, 3]":
290    /// println!("{:?}", slice);
291    /// ```
292    #[must_use = "`self` will be dropped if the result is not used"]
293    #[stable(feature = "iter_to_slice", since = "1.4.0")]
294    #[cfg(not(feature = "ferrocene_certified"))]
295    pub fn into_slice(self) -> &'a mut [T] {
296        // SAFETY: the iterator was created from a mutable slice with pointer
297        // `self.ptr` and length `len!(self)`. This guarantees that all the prerequisites
298        // for `from_raw_parts_mut` are fulfilled.
299        unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
300    }
301
302    /// Views the underlying data as a subslice of the original data.
303    ///
304    /// # Examples
305    ///
306    /// Basic usage:
307    ///
308    /// ```
309    /// // First, we need a slice to call the `iter_mut` method on:
310    /// let slice = &mut [1, 2, 3];
311    ///
312    /// // Then we call `iter_mut` on the slice to get the `IterMut` iterator:
313    /// let mut iter = slice.iter_mut();
314    /// // Here `as_slice` still returns the whole slice, so this prints "[1, 2, 3]":
315    /// println!("{:?}", iter.as_slice());
316    ///
317    /// // Now, we call the `next` method to remove the first element from the iterator
318    /// // and increment its value:
319    /// *iter.next().unwrap() += 1;
320    /// // Here the iterator does not contain the first element of the slice any more,
321    /// // so `as_slice` only returns the last two elements of the slice,
322    /// // and so this prints "[2, 3]":
323    /// println!("{:?}", iter.as_slice());
324    ///
325    /// // The underlying slice still contains three elements, but its first element
326    /// // was increased by 1, so this prints "[2, 2, 3]":
327    /// println!("{:?}", slice);
328    /// ```
329    #[must_use]
330    #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
331    #[inline]
332    #[cfg(not(feature = "ferrocene_certified"))]
333    pub fn as_slice(&self) -> &[T] {
334        self.make_slice()
335    }
336
337    /// Views the underlying data as a mutable subslice of the original data.
338    ///
339    /// # Examples
340    ///
341    /// Basic usage:
342    ///
343    /// ```
344    /// #![feature(slice_iter_mut_as_mut_slice)]
345    ///
346    /// let mut slice: &mut [usize] = &mut [1, 2, 3];
347    ///
348    /// // First, we get the iterator:
349    /// let mut iter = slice.iter_mut();
350    /// // Then, we get a mutable slice from it:
351    /// let mut_slice = iter.as_mut_slice();
352    /// // So if we check what the `as_mut_slice` method returned, we have "[1, 2, 3]":
353    /// assert_eq!(mut_slice, &mut [1, 2, 3]);
354    ///
355    /// // We can use it to mutate the slice:
356    /// mut_slice[0] = 4;
357    /// mut_slice[2] = 5;
358    ///
359    /// // Next, we can move to the second element of the slice, checking that
360    /// // it yields the value we just wrote:
361    /// assert_eq!(iter.next(), Some(&mut 4));
362    /// // Now `as_mut_slice` returns "[2, 5]":
363    /// assert_eq!(iter.as_mut_slice(), &mut [2, 5]);
364    /// ```
365    #[must_use]
366    // FIXME: Uncomment the `AsMut<[T]>` impl when this gets stabilized.
367    #[unstable(feature = "slice_iter_mut_as_mut_slice", issue = "93079")]
368    pub fn as_mut_slice(&mut self) -> &mut [T] {
369        // SAFETY: the iterator was created from a mutable slice with pointer
370        // `self.ptr` and length `len!(self)`. This guarantees that all the prerequisites
371        // for `from_raw_parts_mut` are fulfilled.
372        unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
373    }
374}
375
376#[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
377#[cfg(not(feature = "ferrocene_certified"))]
378impl<T> AsRef<[T]> for IterMut<'_, T> {
379    #[inline]
380    fn as_ref(&self) -> &[T] {
381        self.as_slice()
382    }
383}
384
385// #[stable(feature = "slice_iter_mut_as_mut_slice", since = "FIXME")]
386// impl<T> AsMut<[T]> for IterMut<'_, T> {
387//     fn as_mut(&mut self) -> &mut [T] {
388//         self.as_mut_slice()
389//     }
390// }
391
392iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, as_mut, {}}
393
394/// An internal abstraction over the splitting iterators, so that
395/// splitn, splitn_mut etc can be implemented once.
396#[doc(hidden)]
397#[cfg(not(feature = "ferrocene_certified"))]
398pub(super) trait SplitIter: DoubleEndedIterator {
399    /// Marks the underlying iterator as complete, extracting the remaining
400    /// portion of the slice.
401    fn finish(&mut self) -> Option<Self::Item>;
402}
403
404/// An iterator over subslices separated by elements that match a predicate
405/// function.
406///
407/// This struct is created by the [`split`] method on [slices].
408///
409/// # Example
410///
411/// ```
412/// let slice = [10, 40, 33, 20];
413/// let mut iter = slice.split(|num| num % 3 == 0);
414/// assert_eq!(iter.next(), Some(&[10, 40][..]));
415/// assert_eq!(iter.next(), Some(&[20][..]));
416/// assert_eq!(iter.next(), None);
417/// ```
418///
419/// [`split`]: slice::split
420/// [slices]: slice
421#[stable(feature = "rust1", since = "1.0.0")]
422#[must_use = "iterators are lazy and do nothing unless consumed"]
423#[cfg(not(feature = "ferrocene_certified"))]
424pub struct Split<'a, T: 'a, P>
425where
426    P: FnMut(&T) -> bool,
427{
428    // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods
429    pub(crate) v: &'a [T],
430    pred: P,
431    // Used for `SplitAsciiWhitespace` `as_str` method
432    pub(crate) finished: bool,
433}
434
435#[cfg(not(feature = "ferrocene_certified"))]
436impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {
437    #[inline]
438    pub(super) fn new(slice: &'a [T], pred: P) -> Self {
439        Self { v: slice, pred, finished: false }
440    }
441    /// Returns a slice which contains items not yet handled by split.
442    /// # Example
443    ///
444    /// ```
445    /// #![feature(split_as_slice)]
446    /// let slice = [1,2,3,4,5];
447    /// let mut split = slice.split(|v| v % 2 == 0);
448    /// assert!(split.next().is_some());
449    /// assert_eq!(split.as_slice(), &[3,4,5]);
450    /// ```
451    #[unstable(feature = "split_as_slice", issue = "96137")]
452    pub fn as_slice(&self) -> &'a [T] {
453        if self.finished { &[] } else { &self.v }
454    }
455}
456
457#[stable(feature = "core_impl_debug", since = "1.9.0")]
458#[cfg(not(feature = "ferrocene_certified"))]
459impl<T: fmt::Debug, P> fmt::Debug for Split<'_, T, P>
460where
461    P: FnMut(&T) -> bool,
462{
463    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464        f.debug_struct("Split").field("v", &self.v).field("finished", &self.finished).finish()
465    }
466}
467
468// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
469#[stable(feature = "rust1", since = "1.0.0")]
470#[cfg(not(feature = "ferrocene_certified"))]
471impl<T, P> Clone for Split<'_, T, P>
472where
473    P: Clone + FnMut(&T) -> bool,
474{
475    fn clone(&self) -> Self {
476        Split { v: self.v, pred: self.pred.clone(), finished: self.finished }
477    }
478}
479
480#[stable(feature = "rust1", since = "1.0.0")]
481#[cfg(not(feature = "ferrocene_certified"))]
482impl<'a, T, P> Iterator for Split<'a, T, P>
483where
484    P: FnMut(&T) -> bool,
485{
486    type Item = &'a [T];
487
488    #[inline]
489    fn next(&mut self) -> Option<&'a [T]> {
490        if self.finished {
491            return None;
492        }
493
494        match self.v.iter().position(|x| (self.pred)(x)) {
495            None => self.finish(),
496            Some(idx) => {
497                let (left, right) =
498                    // SAFETY: if v.iter().position returns Some(idx), that
499                    // idx is definitely a valid index for v
500                    unsafe { (self.v.get_unchecked(..idx), self.v.get_unchecked(idx + 1..)) };
501                let ret = Some(left);
502                self.v = right;
503                ret
504            }
505        }
506    }
507
508    #[inline]
509    fn size_hint(&self) -> (usize, Option<usize>) {
510        if self.finished {
511            (0, Some(0))
512        } else {
513            // If the predicate doesn't match anything, we yield one slice.
514            // If it matches every element, we yield `len() + 1` empty slices.
515            (1, Some(self.v.len() + 1))
516        }
517    }
518}
519
520#[stable(feature = "rust1", since = "1.0.0")]
521#[cfg(not(feature = "ferrocene_certified"))]
522impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P>
523where
524    P: FnMut(&T) -> bool,
525{
526    #[inline]
527    fn next_back(&mut self) -> Option<&'a [T]> {
528        if self.finished {
529            return None;
530        }
531
532        match self.v.iter().rposition(|x| (self.pred)(x)) {
533            None => self.finish(),
534            Some(idx) => {
535                let (left, right) =
536                    // SAFETY: if v.iter().rposition returns Some(idx), then
537                    // idx is definitely a valid index for v
538                    unsafe { (self.v.get_unchecked(..idx), self.v.get_unchecked(idx + 1..)) };
539                let ret = Some(right);
540                self.v = left;
541                ret
542            }
543        }
544    }
545}
546
547#[cfg(not(feature = "ferrocene_certified"))]
548impl<'a, T, P> SplitIter for Split<'a, T, P>
549where
550    P: FnMut(&T) -> bool,
551{
552    #[inline]
553    fn finish(&mut self) -> Option<&'a [T]> {
554        if self.finished {
555            None
556        } else {
557            self.finished = true;
558            Some(self.v)
559        }
560    }
561}
562
563#[stable(feature = "fused", since = "1.26.0")]
564#[cfg(not(feature = "ferrocene_certified"))]
565impl<T, P> FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {}
566
567/// An iterator over subslices separated by elements that match a predicate
568/// function. Unlike `Split`, it contains the matched part as a terminator
569/// of the subslice.
570///
571/// This struct is created by the [`split_inclusive`] method on [slices].
572///
573/// # Example
574///
575/// ```
576/// let slice = [10, 40, 33, 20];
577/// let mut iter = slice.split_inclusive(|num| num % 3 == 0);
578/// assert_eq!(iter.next(), Some(&[10, 40, 33][..]));
579/// assert_eq!(iter.next(), Some(&[20][..]));
580/// assert_eq!(iter.next(), None);
581/// ```
582///
583/// [`split_inclusive`]: slice::split_inclusive
584/// [slices]: slice
585#[stable(feature = "split_inclusive", since = "1.51.0")]
586#[must_use = "iterators are lazy and do nothing unless consumed"]
587#[cfg(not(feature = "ferrocene_certified"))]
588pub struct SplitInclusive<'a, T: 'a, P>
589where
590    P: FnMut(&T) -> bool,
591{
592    v: &'a [T],
593    pred: P,
594    finished: bool,
595}
596
597#[cfg(not(feature = "ferrocene_certified"))]
598impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> {
599    #[inline]
600    pub(super) fn new(slice: &'a [T], pred: P) -> Self {
601        let finished = slice.is_empty();
602        Self { v: slice, pred, finished }
603    }
604}
605
606#[stable(feature = "split_inclusive", since = "1.51.0")]
607#[cfg(not(feature = "ferrocene_certified"))]
608impl<T: fmt::Debug, P> fmt::Debug for SplitInclusive<'_, T, P>
609where
610    P: FnMut(&T) -> bool,
611{
612    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
613        f.debug_struct("SplitInclusive")
614            .field("v", &self.v)
615            .field("finished", &self.finished)
616            .finish()
617    }
618}
619
620// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
621#[stable(feature = "split_inclusive", since = "1.51.0")]
622#[cfg(not(feature = "ferrocene_certified"))]
623impl<T, P> Clone for SplitInclusive<'_, T, P>
624where
625    P: Clone + FnMut(&T) -> bool,
626{
627    fn clone(&self) -> Self {
628        SplitInclusive { v: self.v, pred: self.pred.clone(), finished: self.finished }
629    }
630}
631
632#[stable(feature = "split_inclusive", since = "1.51.0")]
633#[cfg(not(feature = "ferrocene_certified"))]
634impl<'a, T, P> Iterator for SplitInclusive<'a, T, P>
635where
636    P: FnMut(&T) -> bool,
637{
638    type Item = &'a [T];
639
640    #[inline]
641    fn next(&mut self) -> Option<&'a [T]> {
642        if self.finished {
643            return None;
644        }
645
646        let idx =
647            self.v.iter().position(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(self.v.len());
648        if idx == self.v.len() {
649            self.finished = true;
650        }
651        let ret = Some(&self.v[..idx]);
652        self.v = &self.v[idx..];
653        ret
654    }
655
656    #[inline]
657    fn size_hint(&self) -> (usize, Option<usize>) {
658        if self.finished {
659            (0, Some(0))
660        } else {
661            // If the predicate doesn't match anything, we yield one slice.
662            // If it matches every element, we yield `len()` one-element slices,
663            // or a single empty slice.
664            (1, Some(cmp::max(1, self.v.len())))
665        }
666    }
667}
668
669#[stable(feature = "split_inclusive", since = "1.51.0")]
670#[cfg(not(feature = "ferrocene_certified"))]
671impl<'a, T, P> DoubleEndedIterator for SplitInclusive<'a, T, P>
672where
673    P: FnMut(&T) -> bool,
674{
675    #[inline]
676    fn next_back(&mut self) -> Option<&'a [T]> {
677        if self.finished {
678            return None;
679        }
680
681        // The last index of self.v is already checked and found to match
682        // by the last iteration, so we start searching a new match
683        // one index to the left.
684        let remainder = if self.v.is_empty() { &[] } else { &self.v[..(self.v.len() - 1)] };
685        let idx = remainder.iter().rposition(|x| (self.pred)(x)).map(|idx| idx + 1).unwrap_or(0);
686        if idx == 0 {
687            self.finished = true;
688        }
689        let ret = Some(&self.v[idx..]);
690        self.v = &self.v[..idx];
691        ret
692    }
693}
694
695#[stable(feature = "split_inclusive", since = "1.51.0")]
696#[cfg(not(feature = "ferrocene_certified"))]
697impl<T, P> FusedIterator for SplitInclusive<'_, T, P> where P: FnMut(&T) -> bool {}
698
699/// An iterator over the mutable subslices of the vector which are separated
700/// by elements that match `pred`.
701///
702/// This struct is created by the [`split_mut`] method on [slices].
703///
704/// # Example
705///
706/// ```
707/// let mut v = [10, 40, 30, 20, 60, 50];
708/// let iter = v.split_mut(|num| *num % 3 == 0);
709/// ```
710///
711/// [`split_mut`]: slice::split_mut
712/// [slices]: slice
713#[stable(feature = "rust1", since = "1.0.0")]
714#[must_use = "iterators are lazy and do nothing unless consumed"]
715#[cfg(not(feature = "ferrocene_certified"))]
716pub struct SplitMut<'a, T: 'a, P>
717where
718    P: FnMut(&T) -> bool,
719{
720    v: &'a mut [T],
721    pred: P,
722    finished: bool,
723}
724
725#[cfg(not(feature = "ferrocene_certified"))]
726impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitMut<'a, T, P> {
727    #[inline]
728    pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
729        Self { v: slice, pred, finished: false }
730    }
731}
732
733#[stable(feature = "core_impl_debug", since = "1.9.0")]
734#[cfg(not(feature = "ferrocene_certified"))]
735impl<T: fmt::Debug, P> fmt::Debug for SplitMut<'_, T, P>
736where
737    P: FnMut(&T) -> bool,
738{
739    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
740        f.debug_struct("SplitMut").field("v", &self.v).field("finished", &self.finished).finish()
741    }
742}
743
744#[cfg(not(feature = "ferrocene_certified"))]
745impl<'a, T, P> SplitIter for SplitMut<'a, T, P>
746where
747    P: FnMut(&T) -> bool,
748{
749    #[inline]
750    fn finish(&mut self) -> Option<&'a mut [T]> {
751        if self.finished {
752            None
753        } else {
754            self.finished = true;
755            Some(mem::take(&mut self.v))
756        }
757    }
758}
759
760#[stable(feature = "rust1", since = "1.0.0")]
761#[cfg(not(feature = "ferrocene_certified"))]
762impl<'a, T, P> Iterator for SplitMut<'a, T, P>
763where
764    P: FnMut(&T) -> bool,
765{
766    type Item = &'a mut [T];
767
768    #[inline]
769    fn next(&mut self) -> Option<&'a mut [T]> {
770        if self.finished {
771            return None;
772        }
773
774        match self.v.iter().position(|x| (self.pred)(x)) {
775            None => self.finish(),
776            Some(idx) => {
777                let tmp = mem::take(&mut self.v);
778                // idx is the index of the element we are splitting on. We want to set self to the
779                // region after idx, and return the subslice before and not including idx.
780                // So first we split after idx
781                let (head, tail) = tmp.split_at_mut(idx + 1);
782                self.v = tail;
783                // Then return the subslice up to but not including the found element
784                Some(&mut head[..idx])
785            }
786        }
787    }
788
789    #[inline]
790    fn size_hint(&self) -> (usize, Option<usize>) {
791        if self.finished {
792            (0, Some(0))
793        } else {
794            // If the predicate doesn't match anything, we yield one slice.
795            // If it matches every element, we yield `len() + 1` empty slices.
796            (1, Some(self.v.len() + 1))
797        }
798    }
799}
800
801#[stable(feature = "rust1", since = "1.0.0")]
802#[cfg(not(feature = "ferrocene_certified"))]
803impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P>
804where
805    P: FnMut(&T) -> bool,
806{
807    #[inline]
808    fn next_back(&mut self) -> Option<&'a mut [T]> {
809        if self.finished {
810            return None;
811        }
812
813        let idx_opt = {
814            // work around borrowck limitations
815            let pred = &mut self.pred;
816            self.v.iter().rposition(|x| (*pred)(x))
817        };
818        match idx_opt {
819            None => self.finish(),
820            Some(idx) => {
821                let tmp = mem::take(&mut self.v);
822                let (head, tail) = tmp.split_at_mut(idx);
823                self.v = head;
824                Some(&mut tail[1..])
825            }
826        }
827    }
828}
829
830#[stable(feature = "fused", since = "1.26.0")]
831#[cfg(not(feature = "ferrocene_certified"))]
832impl<T, P> FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
833
834/// An iterator over the mutable subslices of the vector which are separated
835/// by elements that match `pred`. Unlike `SplitMut`, it contains the matched
836/// parts in the ends of the subslices.
837///
838/// This struct is created by the [`split_inclusive_mut`] method on [slices].
839///
840/// # Example
841///
842/// ```
843/// let mut v = [10, 40, 30, 20, 60, 50];
844/// let iter = v.split_inclusive_mut(|num| *num % 3 == 0);
845/// ```
846///
847/// [`split_inclusive_mut`]: slice::split_inclusive_mut
848/// [slices]: slice
849#[stable(feature = "split_inclusive", since = "1.51.0")]
850#[must_use = "iterators are lazy and do nothing unless consumed"]
851#[cfg(not(feature = "ferrocene_certified"))]
852pub struct SplitInclusiveMut<'a, T: 'a, P>
853where
854    P: FnMut(&T) -> bool,
855{
856    v: &'a mut [T],
857    pred: P,
858    finished: bool,
859}
860
861#[cfg(not(feature = "ferrocene_certified"))]
862impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> {
863    #[inline]
864    pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
865        let finished = slice.is_empty();
866        Self { v: slice, pred, finished }
867    }
868}
869
870#[stable(feature = "split_inclusive", since = "1.51.0")]
871#[cfg(not(feature = "ferrocene_certified"))]
872impl<T: fmt::Debug, P> fmt::Debug for SplitInclusiveMut<'_, T, P>
873where
874    P: FnMut(&T) -> bool,
875{
876    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
877        f.debug_struct("SplitInclusiveMut")
878            .field("v", &self.v)
879            .field("finished", &self.finished)
880            .finish()
881    }
882}
883
884#[stable(feature = "split_inclusive", since = "1.51.0")]
885#[cfg(not(feature = "ferrocene_certified"))]
886impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P>
887where
888    P: FnMut(&T) -> bool,
889{
890    type Item = &'a mut [T];
891
892    #[inline]
893    fn next(&mut self) -> Option<&'a mut [T]> {
894        if self.finished {
895            return None;
896        }
897
898        let idx_opt = {
899            // work around borrowck limitations
900            let pred = &mut self.pred;
901            self.v.iter().position(|x| (*pred)(x))
902        };
903        let idx = idx_opt.map(|idx| idx + 1).unwrap_or(self.v.len());
904        if idx == self.v.len() {
905            self.finished = true;
906        }
907        let tmp = mem::take(&mut self.v);
908        let (head, tail) = tmp.split_at_mut(idx);
909        self.v = tail;
910        Some(head)
911    }
912
913    #[inline]
914    fn size_hint(&self) -> (usize, Option<usize>) {
915        if self.finished {
916            (0, Some(0))
917        } else {
918            // If the predicate doesn't match anything, we yield one slice.
919            // If it matches every element, we yield `len()` one-element slices,
920            // or a single empty slice.
921            (1, Some(cmp::max(1, self.v.len())))
922        }
923    }
924}
925
926#[stable(feature = "split_inclusive", since = "1.51.0")]
927#[cfg(not(feature = "ferrocene_certified"))]
928impl<'a, T, P> DoubleEndedIterator for SplitInclusiveMut<'a, T, P>
929where
930    P: FnMut(&T) -> bool,
931{
932    #[inline]
933    fn next_back(&mut self) -> Option<&'a mut [T]> {
934        if self.finished {
935            return None;
936        }
937
938        let idx_opt = if self.v.is_empty() {
939            None
940        } else {
941            // work around borrowck limitations
942            let pred = &mut self.pred;
943
944            // The last index of self.v is already checked and found to match
945            // by the last iteration, so we start searching a new match
946            // one index to the left.
947            let remainder = &self.v[..(self.v.len() - 1)];
948            remainder.iter().rposition(|x| (*pred)(x))
949        };
950        let idx = idx_opt.map(|idx| idx + 1).unwrap_or(0);
951        if idx == 0 {
952            self.finished = true;
953        }
954        let tmp = mem::take(&mut self.v);
955        let (head, tail) = tmp.split_at_mut(idx);
956        self.v = head;
957        Some(tail)
958    }
959}
960
961#[stable(feature = "split_inclusive", since = "1.51.0")]
962#[cfg(not(feature = "ferrocene_certified"))]
963impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> bool {}
964
965/// An iterator over subslices separated by elements that match a predicate
966/// function, starting from the end of the slice.
967///
968/// This struct is created by the [`rsplit`] method on [slices].
969///
970/// # Example
971///
972/// ```
973/// let slice = [11, 22, 33, 0, 44, 55];
974/// let mut iter = slice.rsplit(|num| *num == 0);
975/// assert_eq!(iter.next(), Some(&[44, 55][..]));
976/// assert_eq!(iter.next(), Some(&[11, 22, 33][..]));
977/// assert_eq!(iter.next(), None);
978/// ```
979///
980/// [`rsplit`]: slice::rsplit
981/// [slices]: slice
982#[stable(feature = "slice_rsplit", since = "1.27.0")]
983#[must_use = "iterators are lazy and do nothing unless consumed"]
984#[cfg(not(feature = "ferrocene_certified"))]
985pub struct RSplit<'a, T: 'a, P>
986where
987    P: FnMut(&T) -> bool,
988{
989    inner: Split<'a, T, P>,
990}
991
992#[cfg(not(feature = "ferrocene_certified"))]
993impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplit<'a, T, P> {
994    #[inline]
995    pub(super) fn new(slice: &'a [T], pred: P) -> Self {
996        Self { inner: Split::new(slice, pred) }
997    }
998}
999
1000#[stable(feature = "slice_rsplit", since = "1.27.0")]
1001#[cfg(not(feature = "ferrocene_certified"))]
1002impl<T: fmt::Debug, P> fmt::Debug for RSplit<'_, T, P>
1003where
1004    P: FnMut(&T) -> bool,
1005{
1006    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1007        f.debug_struct("RSplit")
1008            .field("v", &self.inner.v)
1009            .field("finished", &self.inner.finished)
1010            .finish()
1011    }
1012}
1013
1014// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1015#[stable(feature = "slice_rsplit", since = "1.27.0")]
1016#[cfg(not(feature = "ferrocene_certified"))]
1017impl<T, P> Clone for RSplit<'_, T, P>
1018where
1019    P: Clone + FnMut(&T) -> bool,
1020{
1021    fn clone(&self) -> Self {
1022        RSplit { inner: self.inner.clone() }
1023    }
1024}
1025
1026#[stable(feature = "slice_rsplit", since = "1.27.0")]
1027#[cfg(not(feature = "ferrocene_certified"))]
1028impl<'a, T, P> Iterator for RSplit<'a, T, P>
1029where
1030    P: FnMut(&T) -> bool,
1031{
1032    type Item = &'a [T];
1033
1034    #[inline]
1035    fn next(&mut self) -> Option<&'a [T]> {
1036        self.inner.next_back()
1037    }
1038
1039    #[inline]
1040    fn size_hint(&self) -> (usize, Option<usize>) {
1041        self.inner.size_hint()
1042    }
1043}
1044
1045#[stable(feature = "slice_rsplit", since = "1.27.0")]
1046#[cfg(not(feature = "ferrocene_certified"))]
1047impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P>
1048where
1049    P: FnMut(&T) -> bool,
1050{
1051    #[inline]
1052    fn next_back(&mut self) -> Option<&'a [T]> {
1053        self.inner.next()
1054    }
1055}
1056
1057#[stable(feature = "slice_rsplit", since = "1.27.0")]
1058#[cfg(not(feature = "ferrocene_certified"))]
1059impl<'a, T, P> SplitIter for RSplit<'a, T, P>
1060where
1061    P: FnMut(&T) -> bool,
1062{
1063    #[inline]
1064    fn finish(&mut self) -> Option<&'a [T]> {
1065        self.inner.finish()
1066    }
1067}
1068
1069#[stable(feature = "slice_rsplit", since = "1.27.0")]
1070#[cfg(not(feature = "ferrocene_certified"))]
1071impl<T, P> FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {}
1072
1073/// An iterator over the subslices of the vector which are separated
1074/// by elements that match `pred`, starting from the end of the slice.
1075///
1076/// This struct is created by the [`rsplit_mut`] method on [slices].
1077///
1078/// # Example
1079///
1080/// ```
1081/// let mut slice = [11, 22, 33, 0, 44, 55];
1082/// let iter = slice.rsplit_mut(|num| *num == 0);
1083/// ```
1084///
1085/// [`rsplit_mut`]: slice::rsplit_mut
1086/// [slices]: slice
1087#[stable(feature = "slice_rsplit", since = "1.27.0")]
1088#[must_use = "iterators are lazy and do nothing unless consumed"]
1089#[cfg(not(feature = "ferrocene_certified"))]
1090pub struct RSplitMut<'a, T: 'a, P>
1091where
1092    P: FnMut(&T) -> bool,
1093{
1094    inner: SplitMut<'a, T, P>,
1095}
1096
1097#[cfg(not(feature = "ferrocene_certified"))]
1098impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitMut<'a, T, P> {
1099    #[inline]
1100    pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
1101        Self { inner: SplitMut::new(slice, pred) }
1102    }
1103}
1104
1105#[stable(feature = "slice_rsplit", since = "1.27.0")]
1106#[cfg(not(feature = "ferrocene_certified"))]
1107impl<T: fmt::Debug, P> fmt::Debug for RSplitMut<'_, T, P>
1108where
1109    P: FnMut(&T) -> bool,
1110{
1111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1112        f.debug_struct("RSplitMut")
1113            .field("v", &self.inner.v)
1114            .field("finished", &self.inner.finished)
1115            .finish()
1116    }
1117}
1118
1119#[stable(feature = "slice_rsplit", since = "1.27.0")]
1120#[cfg(not(feature = "ferrocene_certified"))]
1121impl<'a, T, P> SplitIter for RSplitMut<'a, T, P>
1122where
1123    P: FnMut(&T) -> bool,
1124{
1125    #[inline]
1126    fn finish(&mut self) -> Option<&'a mut [T]> {
1127        self.inner.finish()
1128    }
1129}
1130
1131#[stable(feature = "slice_rsplit", since = "1.27.0")]
1132#[cfg(not(feature = "ferrocene_certified"))]
1133impl<'a, T, P> Iterator for RSplitMut<'a, T, P>
1134where
1135    P: FnMut(&T) -> bool,
1136{
1137    type Item = &'a mut [T];
1138
1139    #[inline]
1140    fn next(&mut self) -> Option<&'a mut [T]> {
1141        self.inner.next_back()
1142    }
1143
1144    #[inline]
1145    fn size_hint(&self) -> (usize, Option<usize>) {
1146        self.inner.size_hint()
1147    }
1148}
1149
1150#[stable(feature = "slice_rsplit", since = "1.27.0")]
1151#[cfg(not(feature = "ferrocene_certified"))]
1152impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P>
1153where
1154    P: FnMut(&T) -> bool,
1155{
1156    #[inline]
1157    fn next_back(&mut self) -> Option<&'a mut [T]> {
1158        self.inner.next()
1159    }
1160}
1161
1162#[stable(feature = "slice_rsplit", since = "1.27.0")]
1163#[cfg(not(feature = "ferrocene_certified"))]
1164impl<T, P> FusedIterator for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
1165
1166/// An private iterator over subslices separated by elements that
1167/// match a predicate function, splitting at most a fixed number of
1168/// times.
1169#[derive(Debug)]
1170#[cfg(not(feature = "ferrocene_certified"))]
1171struct GenericSplitN<I> {
1172    iter: I,
1173    count: usize,
1174}
1175
1176#[cfg(not(feature = "ferrocene_certified"))]
1177impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
1178    type Item = T;
1179
1180    #[inline]
1181    fn next(&mut self) -> Option<T> {
1182        match self.count {
1183            0 => None,
1184            1 => {
1185                self.count -= 1;
1186                self.iter.finish()
1187            }
1188            _ => {
1189                self.count -= 1;
1190                self.iter.next()
1191            }
1192        }
1193    }
1194
1195    #[inline]
1196    fn size_hint(&self) -> (usize, Option<usize>) {
1197        let (lower, upper_opt) = self.iter.size_hint();
1198        (
1199            cmp::min(self.count, lower),
1200            Some(upper_opt.map_or(self.count, |upper| cmp::min(self.count, upper))),
1201        )
1202    }
1203}
1204
1205/// An iterator over subslices separated by elements that match a predicate
1206/// function, limited to a given number of splits.
1207///
1208/// This struct is created by the [`splitn`] method on [slices].
1209///
1210/// # Example
1211///
1212/// ```
1213/// let slice = [10, 40, 30, 20, 60, 50];
1214/// let mut iter = slice.splitn(2, |num| *num % 3 == 0);
1215/// assert_eq!(iter.next(), Some(&[10, 40][..]));
1216/// assert_eq!(iter.next(), Some(&[20, 60, 50][..]));
1217/// assert_eq!(iter.next(), None);
1218/// ```
1219///
1220/// [`splitn`]: slice::splitn
1221/// [slices]: slice
1222#[stable(feature = "rust1", since = "1.0.0")]
1223#[must_use = "iterators are lazy and do nothing unless consumed"]
1224#[cfg(not(feature = "ferrocene_certified"))]
1225pub struct SplitN<'a, T: 'a, P>
1226where
1227    P: FnMut(&T) -> bool,
1228{
1229    inner: GenericSplitN<Split<'a, T, P>>,
1230}
1231
1232#[cfg(not(feature = "ferrocene_certified"))]
1233impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitN<'a, T, P> {
1234    #[inline]
1235    pub(super) fn new(s: Split<'a, T, P>, n: usize) -> Self {
1236        Self { inner: GenericSplitN { iter: s, count: n } }
1237    }
1238}
1239
1240#[stable(feature = "core_impl_debug", since = "1.9.0")]
1241#[cfg(not(feature = "ferrocene_certified"))]
1242impl<T: fmt::Debug, P> fmt::Debug for SplitN<'_, T, P>
1243where
1244    P: FnMut(&T) -> bool,
1245{
1246    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1247        f.debug_struct("SplitN").field("inner", &self.inner).finish()
1248    }
1249}
1250
1251/// An iterator over subslices separated by elements that match a
1252/// predicate function, limited to a given number of splits, starting
1253/// from the end of the slice.
1254///
1255/// This struct is created by the [`rsplitn`] method on [slices].
1256///
1257/// # Example
1258///
1259/// ```
1260/// let slice = [10, 40, 30, 20, 60, 50];
1261/// let mut iter = slice.rsplitn(2, |num| *num % 3 == 0);
1262/// assert_eq!(iter.next(), Some(&[50][..]));
1263/// assert_eq!(iter.next(), Some(&[10, 40, 30, 20][..]));
1264/// assert_eq!(iter.next(), None);
1265/// ```
1266///
1267/// [`rsplitn`]: slice::rsplitn
1268/// [slices]: slice
1269#[stable(feature = "rust1", since = "1.0.0")]
1270#[must_use = "iterators are lazy and do nothing unless consumed"]
1271#[cfg(not(feature = "ferrocene_certified"))]
1272pub struct RSplitN<'a, T: 'a, P>
1273where
1274    P: FnMut(&T) -> bool,
1275{
1276    inner: GenericSplitN<RSplit<'a, T, P>>,
1277}
1278
1279#[cfg(not(feature = "ferrocene_certified"))]
1280impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitN<'a, T, P> {
1281    #[inline]
1282    pub(super) fn new(s: RSplit<'a, T, P>, n: usize) -> Self {
1283        Self { inner: GenericSplitN { iter: s, count: n } }
1284    }
1285}
1286
1287#[stable(feature = "core_impl_debug", since = "1.9.0")]
1288#[cfg(not(feature = "ferrocene_certified"))]
1289impl<T: fmt::Debug, P> fmt::Debug for RSplitN<'_, T, P>
1290where
1291    P: FnMut(&T) -> bool,
1292{
1293    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1294        f.debug_struct("RSplitN").field("inner", &self.inner).finish()
1295    }
1296}
1297
1298/// An iterator over subslices separated by elements that match a predicate
1299/// function, limited to a given number of splits.
1300///
1301/// This struct is created by the [`splitn_mut`] method on [slices].
1302///
1303/// # Example
1304///
1305/// ```
1306/// let mut slice = [10, 40, 30, 20, 60, 50];
1307/// let iter = slice.splitn_mut(2, |num| *num % 3 == 0);
1308/// ```
1309///
1310/// [`splitn_mut`]: slice::splitn_mut
1311/// [slices]: slice
1312#[stable(feature = "rust1", since = "1.0.0")]
1313#[must_use = "iterators are lazy and do nothing unless consumed"]
1314#[cfg(not(feature = "ferrocene_certified"))]
1315pub struct SplitNMut<'a, T: 'a, P>
1316where
1317    P: FnMut(&T) -> bool,
1318{
1319    inner: GenericSplitN<SplitMut<'a, T, P>>,
1320}
1321
1322#[cfg(not(feature = "ferrocene_certified"))]
1323impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitNMut<'a, T, P> {
1324    #[inline]
1325    pub(super) fn new(s: SplitMut<'a, T, P>, n: usize) -> Self {
1326        Self { inner: GenericSplitN { iter: s, count: n } }
1327    }
1328}
1329
1330#[stable(feature = "core_impl_debug", since = "1.9.0")]
1331#[cfg(not(feature = "ferrocene_certified"))]
1332impl<T: fmt::Debug, P> fmt::Debug for SplitNMut<'_, T, P>
1333where
1334    P: FnMut(&T) -> bool,
1335{
1336    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1337        f.debug_struct("SplitNMut").field("inner", &self.inner).finish()
1338    }
1339}
1340
1341/// An iterator over subslices separated by elements that match a
1342/// predicate function, limited to a given number of splits, starting
1343/// from the end of the slice.
1344///
1345/// This struct is created by the [`rsplitn_mut`] method on [slices].
1346///
1347/// # Example
1348///
1349/// ```
1350/// let mut slice = [10, 40, 30, 20, 60, 50];
1351/// let iter = slice.rsplitn_mut(2, |num| *num % 3 == 0);
1352/// ```
1353///
1354/// [`rsplitn_mut`]: slice::rsplitn_mut
1355/// [slices]: slice
1356#[stable(feature = "rust1", since = "1.0.0")]
1357#[must_use = "iterators are lazy and do nothing unless consumed"]
1358#[cfg(not(feature = "ferrocene_certified"))]
1359pub struct RSplitNMut<'a, T: 'a, P>
1360where
1361    P: FnMut(&T) -> bool,
1362{
1363    inner: GenericSplitN<RSplitMut<'a, T, P>>,
1364}
1365
1366#[cfg(not(feature = "ferrocene_certified"))]
1367impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitNMut<'a, T, P> {
1368    #[inline]
1369    pub(super) fn new(s: RSplitMut<'a, T, P>, n: usize) -> Self {
1370        Self { inner: GenericSplitN { iter: s, count: n } }
1371    }
1372}
1373
1374#[stable(feature = "core_impl_debug", since = "1.9.0")]
1375#[cfg(not(feature = "ferrocene_certified"))]
1376impl<T: fmt::Debug, P> fmt::Debug for RSplitNMut<'_, T, P>
1377where
1378    P: FnMut(&T) -> bool,
1379{
1380    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1381        f.debug_struct("RSplitNMut").field("inner", &self.inner).finish()
1382    }
1383}
1384
1385#[cfg(not(feature = "ferrocene_certified"))]
1386forward_iterator! { SplitN: T, &'a [T] }
1387#[cfg(not(feature = "ferrocene_certified"))]
1388forward_iterator! { RSplitN: T, &'a [T] }
1389#[cfg(not(feature = "ferrocene_certified"))]
1390forward_iterator! { SplitNMut: T, &'a mut [T] }
1391#[cfg(not(feature = "ferrocene_certified"))]
1392forward_iterator! { RSplitNMut: T, &'a mut [T] }
1393
1394/// An iterator over overlapping subslices of length `size`.
1395///
1396/// This struct is created by the [`windows`] method on [slices].
1397///
1398/// # Example
1399///
1400/// ```
1401/// let slice = ['r', 'u', 's', 't'];
1402/// let mut iter = slice.windows(2);
1403/// assert_eq!(iter.next(), Some(&['r', 'u'][..]));
1404/// assert_eq!(iter.next(), Some(&['u', 's'][..]));
1405/// assert_eq!(iter.next(), Some(&['s', 't'][..]));
1406/// assert_eq!(iter.next(), None);
1407/// ```
1408///
1409/// [`windows`]: slice::windows
1410/// [slices]: slice
1411#[cfg_attr(not(feature = "ferrocene_certified"), derive(Debug))]
1412#[stable(feature = "rust1", since = "1.0.0")]
1413#[must_use = "iterators are lazy and do nothing unless consumed"]
1414pub struct Windows<'a, T: 'a> {
1415    v: &'a [T],
1416    size: NonZero<usize>,
1417}
1418
1419impl<'a, T: 'a> Windows<'a, T> {
1420    #[inline]
1421    pub(super) const fn new(slice: &'a [T], size: NonZero<usize>) -> Self {
1422        Self { v: slice, size }
1423    }
1424}
1425
1426// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1427#[stable(feature = "rust1", since = "1.0.0")]
1428#[cfg(not(feature = "ferrocene_certified"))]
1429impl<T> Clone for Windows<'_, T> {
1430    fn clone(&self) -> Self {
1431        Windows { v: self.v, size: self.size }
1432    }
1433}
1434
1435#[stable(feature = "rust1", since = "1.0.0")]
1436impl<'a, T> Iterator for Windows<'a, T> {
1437    type Item = &'a [T];
1438
1439    #[inline]
1440    fn next(&mut self) -> Option<&'a [T]> {
1441        if self.size.get() > self.v.len() {
1442            None
1443        } else {
1444            let ret = Some(&self.v[..self.size.get()]);
1445            self.v = &self.v[1..];
1446            ret
1447        }
1448    }
1449
1450    #[inline]
1451    fn size_hint(&self) -> (usize, Option<usize>) {
1452        if self.size.get() > self.v.len() {
1453            (0, Some(0))
1454        } else {
1455            let size = self.v.len() - self.size.get() + 1;
1456            (size, Some(size))
1457        }
1458    }
1459
1460    #[inline]
1461    #[cfg(not(feature = "ferrocene_certified"))]
1462    fn count(self) -> usize {
1463        self.len()
1464    }
1465
1466    #[inline]
1467    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1468        let size = self.size.get();
1469        if let Some(rest) = self.v.get(n..)
1470            && let Some(nth) = rest.get(..size)
1471        {
1472            self.v = &rest[1..];
1473            Some(nth)
1474        } else {
1475            // setting length to 0 is cheaper than overwriting the pointer when assigning &[]
1476            self.v = &self.v[..0]; // cheaper than &[]
1477            None
1478        }
1479    }
1480
1481    #[inline]
1482    #[cfg(not(feature = "ferrocene_certified"))]
1483    fn last(self) -> Option<Self::Item> {
1484        if self.size.get() > self.v.len() {
1485            None
1486        } else {
1487            let start = self.v.len() - self.size.get();
1488            Some(&self.v[start..])
1489        }
1490    }
1491
1492    #[cfg(not(feature = "ferrocene_certified"))]
1493    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1494        // SAFETY: since the caller guarantees that `i` is in bounds,
1495        // which means that `i` cannot overflow an `isize`, and the
1496        // slice created by `from_raw_parts` is a subslice of `self.v`
1497        // thus is guaranteed to be valid for the lifetime `'a` of `self.v`.
1498        unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size.get()) }
1499    }
1500}
1501
1502#[stable(feature = "rust1", since = "1.0.0")]
1503#[cfg(not(feature = "ferrocene_certified"))]
1504impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
1505    #[inline]
1506    fn next_back(&mut self) -> Option<&'a [T]> {
1507        if self.size.get() > self.v.len() {
1508            None
1509        } else {
1510            let ret = Some(&self.v[self.v.len() - self.size.get()..]);
1511            self.v = &self.v[..self.v.len() - 1];
1512            ret
1513        }
1514    }
1515
1516    #[inline]
1517    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1518        let (end, overflow) = self.v.len().overflowing_sub(n);
1519        if end < self.size.get() || overflow {
1520            self.v = &self.v[..0]; // cheaper than &[]
1521            None
1522        } else {
1523            let ret = &self.v[end - self.size.get()..end];
1524            self.v = &self.v[..end - 1];
1525            Some(ret)
1526        }
1527    }
1528}
1529
1530#[stable(feature = "rust1", since = "1.0.0")]
1531#[cfg(not(feature = "ferrocene_certified"))]
1532impl<T> ExactSizeIterator for Windows<'_, T> {}
1533
1534#[unstable(feature = "trusted_len", issue = "37572")]
1535#[cfg(not(feature = "ferrocene_certified"))]
1536unsafe impl<T> TrustedLen for Windows<'_, T> {}
1537
1538#[stable(feature = "fused", since = "1.26.0")]
1539#[cfg(not(feature = "ferrocene_certified"))]
1540impl<T> FusedIterator for Windows<'_, T> {}
1541
1542#[doc(hidden)]
1543#[unstable(feature = "trusted_random_access", issue = "none")]
1544#[cfg(not(feature = "ferrocene_certified"))]
1545unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {}
1546
1547#[doc(hidden)]
1548#[unstable(feature = "trusted_random_access", issue = "none")]
1549#[cfg(not(feature = "ferrocene_certified"))]
1550unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Windows<'a, T> {
1551    const MAY_HAVE_SIDE_EFFECT: bool = false;
1552}
1553
1554/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
1555/// time), starting at the beginning of the slice.
1556///
1557/// When the slice len is not evenly divided by the chunk size, the last slice
1558/// of the iteration will be the remainder.
1559///
1560/// This struct is created by the [`chunks`] method on [slices].
1561///
1562/// # Example
1563///
1564/// ```
1565/// let slice = ['l', 'o', 'r', 'e', 'm'];
1566/// let mut iter = slice.chunks(2);
1567/// assert_eq!(iter.next(), Some(&['l', 'o'][..]));
1568/// assert_eq!(iter.next(), Some(&['r', 'e'][..]));
1569/// assert_eq!(iter.next(), Some(&['m'][..]));
1570/// assert_eq!(iter.next(), None);
1571/// ```
1572///
1573/// [`chunks`]: slice::chunks
1574/// [slices]: slice
1575#[cfg_attr(not(feature = "ferrocene_certified"), derive(Debug))]
1576#[stable(feature = "rust1", since = "1.0.0")]
1577#[must_use = "iterators are lazy and do nothing unless consumed"]
1578pub struct Chunks<'a, T: 'a> {
1579    v: &'a [T],
1580    chunk_size: usize,
1581}
1582
1583impl<'a, T: 'a> Chunks<'a, T> {
1584    #[inline]
1585    pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
1586        Self { v: slice, chunk_size: size }
1587    }
1588}
1589
1590// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1591#[stable(feature = "rust1", since = "1.0.0")]
1592#[cfg(not(feature = "ferrocene_certified"))]
1593impl<T> Clone for Chunks<'_, T> {
1594    fn clone(&self) -> Self {
1595        Chunks { v: self.v, chunk_size: self.chunk_size }
1596    }
1597}
1598
1599#[stable(feature = "rust1", since = "1.0.0")]
1600impl<'a, T> Iterator for Chunks<'a, T> {
1601    type Item = &'a [T];
1602
1603    #[inline]
1604    fn next(&mut self) -> Option<&'a [T]> {
1605        if self.v.is_empty() {
1606            None
1607        } else {
1608            let chunksz = cmp::min(self.v.len(), self.chunk_size);
1609            let (fst, snd) = self.v.split_at(chunksz);
1610            self.v = snd;
1611            Some(fst)
1612        }
1613    }
1614
1615    #[inline]
1616    fn size_hint(&self) -> (usize, Option<usize>) {
1617        if self.v.is_empty() {
1618            (0, Some(0))
1619        } else {
1620            let n = self.v.len() / self.chunk_size;
1621            let rem = self.v.len() % self.chunk_size;
1622            let n = if rem > 0 { n + 1 } else { n };
1623            (n, Some(n))
1624        }
1625    }
1626
1627    #[inline]
1628    #[cfg(not(feature = "ferrocene_certified"))]
1629    fn count(self) -> usize {
1630        self.len()
1631    }
1632
1633    #[inline]
1634    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1635        let (start, overflow) = n.overflowing_mul(self.chunk_size);
1636        // min(len) makes a wrong start harmless, but enables optimizing this to brachless code
1637        let chunk_start = &self.v[start.min(self.v.len())..];
1638        let (nth, remainder) = chunk_start.split_at(self.chunk_size.min(chunk_start.len()));
1639        if !overflow && start < self.v.len() {
1640            self.v = remainder;
1641            Some(nth)
1642        } else {
1643            self.v = &self.v[..0]; // cheaper than &[]
1644            None
1645        }
1646    }
1647
1648    #[inline]
1649    #[cfg(not(feature = "ferrocene_certified"))]
1650    fn last(self) -> Option<Self::Item> {
1651        if self.v.is_empty() {
1652            None
1653        } else {
1654            let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
1655            Some(&self.v[start..])
1656        }
1657    }
1658
1659    #[cfg(not(feature = "ferrocene_certified"))]
1660    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1661        let start = idx * self.chunk_size;
1662        // SAFETY: the caller guarantees that `i` is in bounds,
1663        // which means that `start` must be in bounds of the
1664        // underlying `self.v` slice, and we made sure that `len`
1665        // is also in bounds of `self.v`. Thus, `start` cannot overflow
1666        // an `isize`, and the slice constructed by `from_raw_parts`
1667        // is a subslice of `self.v` which is guaranteed to be valid
1668        // for the lifetime `'a` of `self.v`.
1669        unsafe {
1670            let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
1671            from_raw_parts(self.v.as_ptr().add(start), len)
1672        }
1673    }
1674}
1675
1676#[stable(feature = "rust1", since = "1.0.0")]
1677#[cfg(not(feature = "ferrocene_certified"))]
1678impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
1679    #[inline]
1680    fn next_back(&mut self) -> Option<&'a [T]> {
1681        if self.v.is_empty() {
1682            None
1683        } else {
1684            let remainder = self.v.len() % self.chunk_size;
1685            let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
1686            // SAFETY: split_at_unchecked requires the argument be less than or
1687            // equal to the length. This is guaranteed, but subtle: `chunksz`
1688            // will always either be `self.v.len() % self.chunk_size`, which
1689            // will always evaluate to strictly less than `self.v.len()` (or
1690            // panic, in the case that `self.chunk_size` is zero), or it can be
1691            // `self.chunk_size`, in the case that the length is exactly
1692            // divisible by the chunk size.
1693            //
1694            // While it seems like using `self.chunk_size` in this case could
1695            // lead to a value greater than `self.v.len()`, it cannot: if
1696            // `self.chunk_size` were greater than `self.v.len()`, then
1697            // `self.v.len() % self.chunk_size` would return nonzero (note that
1698            // in this branch of the `if`, we already know that `self.v` is
1699            // non-empty).
1700            let (fst, snd) = unsafe { self.v.split_at_unchecked(self.v.len() - chunksz) };
1701            self.v = fst;
1702            Some(snd)
1703        }
1704    }
1705
1706    #[inline]
1707    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1708        let len = self.len();
1709        if n >= len {
1710            self.v = &self.v[..0]; // cheaper than &[]
1711            None
1712        } else {
1713            let start = (len - 1 - n) * self.chunk_size;
1714            let end = match start.checked_add(self.chunk_size) {
1715                Some(res) => cmp::min(self.v.len(), res),
1716                None => self.v.len(),
1717            };
1718            let nth_back = &self.v[start..end];
1719            self.v = &self.v[..start];
1720            Some(nth_back)
1721        }
1722    }
1723}
1724
1725#[stable(feature = "rust1", since = "1.0.0")]
1726#[cfg(not(feature = "ferrocene_certified"))]
1727impl<T> ExactSizeIterator for Chunks<'_, T> {}
1728
1729#[unstable(feature = "trusted_len", issue = "37572")]
1730#[cfg(not(feature = "ferrocene_certified"))]
1731unsafe impl<T> TrustedLen for Chunks<'_, T> {}
1732
1733#[stable(feature = "fused", since = "1.26.0")]
1734#[cfg(not(feature = "ferrocene_certified"))]
1735impl<T> FusedIterator for Chunks<'_, T> {}
1736
1737#[doc(hidden)]
1738#[unstable(feature = "trusted_random_access", issue = "none")]
1739#[cfg(not(feature = "ferrocene_certified"))]
1740unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {}
1741
1742#[doc(hidden)]
1743#[unstable(feature = "trusted_random_access", issue = "none")]
1744#[cfg(not(feature = "ferrocene_certified"))]
1745unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> {
1746    const MAY_HAVE_SIDE_EFFECT: bool = false;
1747}
1748
1749/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
1750/// elements at a time), starting at the beginning of the slice.
1751///
1752/// When the slice len is not evenly divided by the chunk size, the last slice
1753/// of the iteration will be the remainder.
1754///
1755/// This struct is created by the [`chunks_mut`] method on [slices].
1756///
1757/// # Example
1758///
1759/// ```
1760/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
1761/// let iter = slice.chunks_mut(2);
1762/// ```
1763///
1764/// [`chunks_mut`]: slice::chunks_mut
1765/// [slices]: slice
1766#[cfg_attr(not(feature = "ferrocene_certified"), derive(Debug))]
1767#[stable(feature = "rust1", since = "1.0.0")]
1768#[must_use = "iterators are lazy and do nothing unless consumed"]
1769pub struct ChunksMut<'a, T: 'a> {
1770    /// # Safety
1771    /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
1772    /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
1773    /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
1774    /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
1775    /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
1776    v: *mut [T],
1777    chunk_size: usize,
1778    _marker: PhantomData<&'a mut T>,
1779}
1780
1781impl<'a, T: 'a> ChunksMut<'a, T> {
1782    #[inline]
1783    pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
1784        Self { v: slice, chunk_size: size, _marker: PhantomData }
1785    }
1786}
1787
1788#[stable(feature = "rust1", since = "1.0.0")]
1789impl<'a, T> Iterator for ChunksMut<'a, T> {
1790    type Item = &'a mut [T];
1791
1792    #[inline]
1793    fn next(&mut self) -> Option<&'a mut [T]> {
1794        if self.v.is_empty() {
1795            None
1796        } else {
1797            let sz = cmp::min(self.v.len(), self.chunk_size);
1798            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1799            let (head, tail) = unsafe { self.v.split_at_mut(sz) };
1800            self.v = tail;
1801            // SAFETY: Nothing else points to or will point to the contents of this slice.
1802            Some(unsafe { &mut *head })
1803        }
1804    }
1805
1806    #[inline]
1807    fn size_hint(&self) -> (usize, Option<usize>) {
1808        if self.v.is_empty() {
1809            (0, Some(0))
1810        } else {
1811            let n = self.v.len() / self.chunk_size;
1812            let rem = self.v.len() % self.chunk_size;
1813            let n = if rem > 0 { n + 1 } else { n };
1814            (n, Some(n))
1815        }
1816    }
1817
1818    #[inline]
1819    #[cfg(not(feature = "ferrocene_certified"))]
1820    fn count(self) -> usize {
1821        self.len()
1822    }
1823
1824    #[inline]
1825    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
1826        let (start, overflow) = n.overflowing_mul(self.chunk_size);
1827        if start >= self.v.len() || overflow {
1828            self.v = &mut [];
1829            None
1830        } else {
1831            let end = match start.checked_add(self.chunk_size) {
1832                Some(sum) => cmp::min(self.v.len(), sum),
1833                None => self.v.len(),
1834            };
1835            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1836            let (head, tail) = unsafe { self.v.split_at_mut(end) };
1837            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1838            let (_, nth) = unsafe { head.split_at_mut(start) };
1839            self.v = tail;
1840            // SAFETY: Nothing else points to or will point to the contents of this slice.
1841            Some(unsafe { &mut *nth })
1842        }
1843    }
1844
1845    #[inline]
1846    #[cfg(not(feature = "ferrocene_certified"))]
1847    fn last(self) -> Option<Self::Item> {
1848        if self.v.is_empty() {
1849            None
1850        } else {
1851            let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
1852            // SAFETY: Nothing else points to or will point to the contents of this slice.
1853            Some(unsafe { &mut *self.v.get_unchecked_mut(start..) })
1854        }
1855    }
1856
1857    #[cfg(not(feature = "ferrocene_certified"))]
1858    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1859        let start = idx * self.chunk_size;
1860        // SAFETY: see comments for `Chunks::__iterator_get_unchecked` and `self.v`.
1861        //
1862        // Also note that the caller also guarantees that we're never called
1863        // with the same index again, and that no other methods that will
1864        // access this subslice are called, so it is valid for the returned
1865        // slice to be mutable.
1866        unsafe {
1867            let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
1868            from_raw_parts_mut(self.v.as_mut_ptr().add(start), len)
1869        }
1870    }
1871}
1872
1873#[stable(feature = "rust1", since = "1.0.0")]
1874#[cfg(not(feature = "ferrocene_certified"))]
1875impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
1876    #[inline]
1877    fn next_back(&mut self) -> Option<&'a mut [T]> {
1878        if self.v.is_empty() {
1879            None
1880        } else {
1881            let remainder = self.v.len() % self.chunk_size;
1882            let sz = if remainder != 0 { remainder } else { self.chunk_size };
1883            let len = self.v.len();
1884            // SAFETY: Similar to `Chunks::next_back`
1885            let (head, tail) = unsafe { self.v.split_at_mut_unchecked(len - sz) };
1886            self.v = head;
1887            // SAFETY: Nothing else points to or will point to the contents of this slice.
1888            Some(unsafe { &mut *tail })
1889        }
1890    }
1891
1892    #[inline]
1893    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1894        let len = self.len();
1895        if n >= len {
1896            self.v = &mut [];
1897            None
1898        } else {
1899            let start = (len - 1 - n) * self.chunk_size;
1900            let end = match start.checked_add(self.chunk_size) {
1901                Some(res) => cmp::min(self.v.len(), res),
1902                None => self.v.len(),
1903            };
1904            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1905            let (temp, _tail) = unsafe { self.v.split_at_mut(end) };
1906            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1907            let (head, nth_back) = unsafe { temp.split_at_mut(start) };
1908            self.v = head;
1909            // SAFETY: Nothing else points to or will point to the contents of this slice.
1910            Some(unsafe { &mut *nth_back })
1911        }
1912    }
1913}
1914
1915#[stable(feature = "rust1", since = "1.0.0")]
1916#[cfg(not(feature = "ferrocene_certified"))]
1917impl<T> ExactSizeIterator for ChunksMut<'_, T> {}
1918
1919#[unstable(feature = "trusted_len", issue = "37572")]
1920#[cfg(not(feature = "ferrocene_certified"))]
1921unsafe impl<T> TrustedLen for ChunksMut<'_, T> {}
1922
1923#[stable(feature = "fused", since = "1.26.0")]
1924#[cfg(not(feature = "ferrocene_certified"))]
1925impl<T> FusedIterator for ChunksMut<'_, T> {}
1926
1927#[doc(hidden)]
1928#[unstable(feature = "trusted_random_access", issue = "none")]
1929#[cfg(not(feature = "ferrocene_certified"))]
1930unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {}
1931
1932#[doc(hidden)]
1933#[unstable(feature = "trusted_random_access", issue = "none")]
1934#[cfg(not(feature = "ferrocene_certified"))]
1935unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksMut<'a, T> {
1936    const MAY_HAVE_SIDE_EFFECT: bool = false;
1937}
1938
1939#[stable(feature = "rust1", since = "1.0.0")]
1940#[cfg(not(feature = "ferrocene_certified"))]
1941unsafe impl<T> Send for ChunksMut<'_, T> where T: Send {}
1942
1943#[stable(feature = "rust1", since = "1.0.0")]
1944#[cfg(not(feature = "ferrocene_certified"))]
1945unsafe impl<T> Sync for ChunksMut<'_, T> where T: Sync {}
1946
1947/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
1948/// time), starting at the beginning of the slice.
1949///
1950/// When the slice len is not evenly divided by the chunk size, the last
1951/// up to `chunk_size-1` elements will be omitted but can be retrieved from
1952/// the [`remainder`] function from the iterator.
1953///
1954/// This struct is created by the [`chunks_exact`] method on [slices].
1955///
1956/// # Example
1957///
1958/// ```
1959/// let slice = ['l', 'o', 'r', 'e', 'm'];
1960/// let mut iter = slice.chunks_exact(2);
1961/// assert_eq!(iter.next(), Some(&['l', 'o'][..]));
1962/// assert_eq!(iter.next(), Some(&['r', 'e'][..]));
1963/// assert_eq!(iter.next(), None);
1964/// ```
1965///
1966/// [`chunks_exact`]: slice::chunks_exact
1967/// [`remainder`]: ChunksExact::remainder
1968/// [slices]: slice
1969#[cfg_attr(not(feature = "ferrocene_certified"), derive(Debug))]
1970#[stable(feature = "chunks_exact", since = "1.31.0")]
1971#[must_use = "iterators are lazy and do nothing unless consumed"]
1972pub struct ChunksExact<'a, T: 'a> {
1973    v: &'a [T],
1974    rem: &'a [T],
1975    chunk_size: usize,
1976}
1977
1978impl<'a, T> ChunksExact<'a, T> {
1979    #[inline]
1980    pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
1981        let rem = slice.len() % chunk_size;
1982        let fst_len = slice.len() - rem;
1983        // SAFETY: 0 <= fst_len <= slice.len() by construction above
1984        let (fst, snd) = unsafe { slice.split_at_unchecked(fst_len) };
1985        Self { v: fst, rem: snd, chunk_size }
1986    }
1987
1988    /// Returns the remainder of the original slice that is not going to be
1989    /// returned by the iterator. The returned slice has at most `chunk_size-1`
1990    /// elements.
1991    ///
1992    /// # Example
1993    ///
1994    /// ```
1995    /// let slice = ['l', 'o', 'r', 'e', 'm'];
1996    /// let mut iter = slice.chunks_exact(2);
1997    /// assert_eq!(iter.remainder(), &['m'][..]);
1998    /// assert_eq!(iter.next(), Some(&['l', 'o'][..]));
1999    /// assert_eq!(iter.remainder(), &['m'][..]);
2000    /// assert_eq!(iter.next(), Some(&['r', 'e'][..]));
2001    /// assert_eq!(iter.remainder(), &['m'][..]);
2002    /// assert_eq!(iter.next(), None);
2003    /// assert_eq!(iter.remainder(), &['m'][..]);
2004    /// ```
2005    #[must_use]
2006    #[stable(feature = "chunks_exact", since = "1.31.0")]
2007    pub fn remainder(&self) -> &'a [T] {
2008        self.rem
2009    }
2010}
2011
2012// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2013#[stable(feature = "chunks_exact", since = "1.31.0")]
2014#[cfg(not(feature = "ferrocene_certified"))]
2015impl<T> Clone for ChunksExact<'_, T> {
2016    fn clone(&self) -> Self {
2017        ChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
2018    }
2019}
2020
2021#[stable(feature = "chunks_exact", since = "1.31.0")]
2022impl<'a, T> Iterator for ChunksExact<'a, T> {
2023    type Item = &'a [T];
2024
2025    #[inline]
2026    fn next(&mut self) -> Option<&'a [T]> {
2027        if self.v.len() < self.chunk_size {
2028            None
2029        } else {
2030            let (fst, snd) = self.v.split_at(self.chunk_size);
2031            self.v = snd;
2032            Some(fst)
2033        }
2034    }
2035
2036    #[inline]
2037    fn size_hint(&self) -> (usize, Option<usize>) {
2038        let n = self.v.len() / self.chunk_size;
2039        (n, Some(n))
2040    }
2041
2042    #[inline]
2043    #[cfg(not(feature = "ferrocene_certified"))]
2044    fn count(self) -> usize {
2045        self.len()
2046    }
2047
2048    #[inline]
2049    fn nth(&mut self, n: usize) -> Option<Self::Item> {
2050        let (start, overflow) = n.overflowing_mul(self.chunk_size);
2051        if start >= self.v.len() || overflow {
2052            self.v = &self.v[..0]; // cheaper than &[]
2053            None
2054        } else {
2055            let (_, snd) = self.v.split_at(start);
2056            self.v = snd;
2057            self.next()
2058        }
2059    }
2060
2061    #[inline]
2062    #[cfg(not(feature = "ferrocene_certified"))]
2063    fn last(mut self) -> Option<Self::Item> {
2064        self.next_back()
2065    }
2066
2067    #[cfg(not(feature = "ferrocene_certified"))]
2068    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2069        let start = idx * self.chunk_size;
2070        // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
2071        unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
2072    }
2073}
2074
2075#[stable(feature = "chunks_exact", since = "1.31.0")]
2076#[cfg(not(feature = "ferrocene_certified"))]
2077impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
2078    #[inline]
2079    fn next_back(&mut self) -> Option<&'a [T]> {
2080        if self.v.len() < self.chunk_size {
2081            None
2082        } else {
2083            let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
2084            self.v = fst;
2085            Some(snd)
2086        }
2087    }
2088
2089    #[inline]
2090    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2091        let len = self.len();
2092        if n >= len {
2093            self.v = &self.v[..0]; // cheaper than &[]
2094            None
2095        } else {
2096            let start = (len - 1 - n) * self.chunk_size;
2097            let end = start + self.chunk_size;
2098            let nth_back = &self.v[start..end];
2099            self.v = &self.v[..start];
2100            Some(nth_back)
2101        }
2102    }
2103}
2104
2105#[stable(feature = "chunks_exact", since = "1.31.0")]
2106#[cfg(not(feature = "ferrocene_certified"))]
2107impl<T> ExactSizeIterator for ChunksExact<'_, T> {
2108    fn is_empty(&self) -> bool {
2109        self.v.is_empty()
2110    }
2111}
2112
2113#[unstable(feature = "trusted_len", issue = "37572")]
2114#[cfg(not(feature = "ferrocene_certified"))]
2115unsafe impl<T> TrustedLen for ChunksExact<'_, T> {}
2116
2117#[stable(feature = "chunks_exact", since = "1.31.0")]
2118#[cfg(not(feature = "ferrocene_certified"))]
2119impl<T> FusedIterator for ChunksExact<'_, T> {}
2120
2121#[doc(hidden)]
2122#[unstable(feature = "trusted_random_access", issue = "none")]
2123#[cfg(not(feature = "ferrocene_certified"))]
2124unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {}
2125
2126#[doc(hidden)]
2127#[unstable(feature = "trusted_random_access", issue = "none")]
2128#[cfg(not(feature = "ferrocene_certified"))]
2129unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> {
2130    const MAY_HAVE_SIDE_EFFECT: bool = false;
2131}
2132
2133/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
2134/// elements at a time), starting at the beginning of the slice.
2135///
2136/// When the slice len is not evenly divided by the chunk size, the last up to
2137/// `chunk_size-1` elements will be omitted but can be retrieved from the
2138/// [`into_remainder`] function from the iterator.
2139///
2140/// This struct is created by the [`chunks_exact_mut`] method on [slices].
2141///
2142/// # Example
2143///
2144/// ```
2145/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
2146/// let iter = slice.chunks_exact_mut(2);
2147/// ```
2148///
2149/// [`chunks_exact_mut`]: slice::chunks_exact_mut
2150/// [`into_remainder`]: ChunksExactMut::into_remainder
2151/// [slices]: slice
2152#[cfg_attr(not(feature = "ferrocene_certified"), derive(Debug))]
2153#[stable(feature = "chunks_exact", since = "1.31.0")]
2154#[must_use = "iterators are lazy and do nothing unless consumed"]
2155pub struct ChunksExactMut<'a, T: 'a> {
2156    /// # Safety
2157    /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
2158    /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
2159    /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
2160    /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
2161    /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
2162    v: *mut [T],
2163    rem: &'a mut [T], // The iterator never yields from here, so this can be unique
2164    chunk_size: usize,
2165    _marker: PhantomData<&'a mut T>,
2166}
2167
2168impl<'a, T> ChunksExactMut<'a, T> {
2169    #[inline]
2170    pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
2171        let rem = slice.len() % chunk_size;
2172        let fst_len = slice.len() - rem;
2173        // SAFETY: 0 <= fst_len <= slice.len() by construction above
2174        let (fst, snd) = unsafe { slice.split_at_mut_unchecked(fst_len) };
2175        Self { v: fst, rem: snd, chunk_size, _marker: PhantomData }
2176    }
2177
2178    /// Returns the remainder of the original slice that is not going to be
2179    /// returned by the iterator. The returned slice has at most `chunk_size-1`
2180    /// elements.
2181    #[must_use = "`self` will be dropped if the result is not used"]
2182    #[stable(feature = "chunks_exact", since = "1.31.0")]
2183    pub fn into_remainder(self) -> &'a mut [T] {
2184        self.rem
2185    }
2186}
2187
2188#[stable(feature = "chunks_exact", since = "1.31.0")]
2189impl<'a, T> Iterator for ChunksExactMut<'a, T> {
2190    type Item = &'a mut [T];
2191
2192    #[inline]
2193    fn next(&mut self) -> Option<&'a mut [T]> {
2194        if self.v.len() < self.chunk_size {
2195            None
2196        } else {
2197            // SAFETY: self.chunk_size is inbounds because we compared above against self.v.len()
2198            let (head, tail) = unsafe { self.v.split_at_mut(self.chunk_size) };
2199            self.v = tail;
2200            // SAFETY: Nothing else points to or will point to the contents of this slice.
2201            Some(unsafe { &mut *head })
2202        }
2203    }
2204
2205    #[inline]
2206    fn size_hint(&self) -> (usize, Option<usize>) {
2207        let n = self.v.len() / self.chunk_size;
2208        (n, Some(n))
2209    }
2210
2211    #[inline]
2212    #[cfg(not(feature = "ferrocene_certified"))]
2213    fn count(self) -> usize {
2214        self.len()
2215    }
2216
2217    #[inline]
2218    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2219        let (start, overflow) = n.overflowing_mul(self.chunk_size);
2220        if start >= self.v.len() || overflow {
2221            self.v = &mut [];
2222            None
2223        } else {
2224            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2225            let (_, snd) = unsafe { self.v.split_at_mut(start) };
2226            self.v = snd;
2227            self.next()
2228        }
2229    }
2230
2231    #[inline]
2232    #[cfg(not(feature = "ferrocene_certified"))]
2233    fn last(mut self) -> Option<Self::Item> {
2234        self.next_back()
2235    }
2236
2237    #[cfg(not(feature = "ferrocene_certified"))]
2238    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2239        let start = idx * self.chunk_size;
2240        // SAFETY: see comments for `Chunks::__iterator_get_unchecked` and `self.v`.
2241        unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
2242    }
2243}
2244
2245#[stable(feature = "chunks_exact", since = "1.31.0")]
2246#[cfg(not(feature = "ferrocene_certified"))]
2247impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
2248    #[inline]
2249    fn next_back(&mut self) -> Option<&'a mut [T]> {
2250        if self.v.len() < self.chunk_size {
2251            None
2252        } else {
2253            // SAFETY: This subtraction is inbounds because of the check above
2254            let (head, tail) = unsafe { self.v.split_at_mut(self.v.len() - self.chunk_size) };
2255            self.v = head;
2256            // SAFETY: Nothing else points to or will point to the contents of this slice.
2257            Some(unsafe { &mut *tail })
2258        }
2259    }
2260
2261    #[inline]
2262    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2263        let len = self.len();
2264        if n >= len {
2265            self.v = &mut [];
2266            None
2267        } else {
2268            let start = (len - 1 - n) * self.chunk_size;
2269            let end = start + self.chunk_size;
2270            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2271            let (temp, _tail) = unsafe { mem::replace(&mut self.v, &mut []).split_at_mut(end) };
2272            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2273            let (head, nth_back) = unsafe { temp.split_at_mut(start) };
2274            self.v = head;
2275            // SAFETY: Nothing else points to or will point to the contents of this slice.
2276            Some(unsafe { &mut *nth_back })
2277        }
2278    }
2279}
2280
2281#[stable(feature = "chunks_exact", since = "1.31.0")]
2282#[cfg(not(feature = "ferrocene_certified"))]
2283impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
2284    fn is_empty(&self) -> bool {
2285        self.v.is_empty()
2286    }
2287}
2288
2289#[unstable(feature = "trusted_len", issue = "37572")]
2290#[cfg(not(feature = "ferrocene_certified"))]
2291unsafe impl<T> TrustedLen for ChunksExactMut<'_, T> {}
2292
2293#[stable(feature = "chunks_exact", since = "1.31.0")]
2294#[cfg(not(feature = "ferrocene_certified"))]
2295impl<T> FusedIterator for ChunksExactMut<'_, T> {}
2296
2297#[doc(hidden)]
2298#[unstable(feature = "trusted_random_access", issue = "none")]
2299#[cfg(not(feature = "ferrocene_certified"))]
2300unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {}
2301
2302#[doc(hidden)]
2303#[unstable(feature = "trusted_random_access", issue = "none")]
2304#[cfg(not(feature = "ferrocene_certified"))]
2305unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExactMut<'a, T> {
2306    const MAY_HAVE_SIDE_EFFECT: bool = false;
2307}
2308
2309#[stable(feature = "chunks_exact", since = "1.31.0")]
2310#[cfg(not(feature = "ferrocene_certified"))]
2311unsafe impl<T> Send for ChunksExactMut<'_, T> where T: Send {}
2312
2313#[stable(feature = "chunks_exact", since = "1.31.0")]
2314#[cfg(not(feature = "ferrocene_certified"))]
2315unsafe impl<T> Sync for ChunksExactMut<'_, T> where T: Sync {}
2316
2317/// A windowed iterator over a slice in overlapping chunks (`N` elements at a
2318/// time), starting at the beginning of the slice
2319///
2320/// This struct is created by the [`array_windows`] method on [slices].
2321///
2322/// # Example
2323///
2324/// ```
2325/// #![feature(array_windows)]
2326///
2327/// let slice = [0, 1, 2, 3];
2328/// let mut iter = slice.array_windows::<2>();
2329/// assert_eq!(iter.next(), Some(&[0, 1]));
2330/// assert_eq!(iter.next(), Some(&[1, 2]));
2331/// assert_eq!(iter.next(), Some(&[2, 3]));
2332/// assert_eq!(iter.next(), None);
2333/// ```
2334///
2335/// [`array_windows`]: slice::array_windows
2336/// [slices]: slice
2337#[derive(Debug, Clone, Copy)]
2338#[unstable(feature = "array_windows", issue = "75027")]
2339#[must_use = "iterators are lazy and do nothing unless consumed"]
2340#[cfg(not(feature = "ferrocene_certified"))]
2341pub struct ArrayWindows<'a, T: 'a, const N: usize> {
2342    v: &'a [T],
2343}
2344
2345#[cfg(not(feature = "ferrocene_certified"))]
2346impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
2347    #[inline]
2348    pub(super) const fn new(slice: &'a [T]) -> Self {
2349        Self { v: slice }
2350    }
2351}
2352
2353#[unstable(feature = "array_windows", issue = "75027")]
2354#[cfg(not(feature = "ferrocene_certified"))]
2355impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
2356    type Item = &'a [T; N];
2357
2358    #[inline]
2359    fn next(&mut self) -> Option<Self::Item> {
2360        let ret = self.v.first_chunk();
2361        if ret.is_some() {
2362            self.v = &self.v[1..];
2363        }
2364        ret
2365    }
2366
2367    #[inline]
2368    fn size_hint(&self) -> (usize, Option<usize>) {
2369        let size = self.v.len().saturating_sub(N - 1);
2370        (size, Some(size))
2371    }
2372
2373    #[inline]
2374    fn count(self) -> usize {
2375        self.len()
2376    }
2377
2378    #[inline]
2379    fn nth(&mut self, n: usize) -> Option<Self::Item> {
2380        let idx = n.min(self.v.len());
2381        self.v = &self.v[idx..];
2382        self.next()
2383    }
2384
2385    #[inline]
2386    fn last(self) -> Option<Self::Item> {
2387        self.v.last_chunk()
2388    }
2389}
2390
2391#[unstable(feature = "array_windows", issue = "75027")]
2392#[cfg(not(feature = "ferrocene_certified"))]
2393impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
2394    #[inline]
2395    fn next_back(&mut self) -> Option<&'a [T; N]> {
2396        let ret = self.v.last_chunk();
2397        if ret.is_some() {
2398            self.v = &self.v[..self.v.len() - 1];
2399        }
2400        ret
2401    }
2402
2403    #[inline]
2404    fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
2405        let idx = self.v.len().saturating_sub(n);
2406        self.v = &self.v[..idx];
2407        self.next_back()
2408    }
2409}
2410
2411#[unstable(feature = "array_windows", issue = "75027")]
2412#[cfg(not(feature = "ferrocene_certified"))]
2413impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
2414    fn is_empty(&self) -> bool {
2415        self.v.len() < N
2416    }
2417}
2418
2419/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
2420/// time), starting at the end of the slice.
2421///
2422/// When the slice len is not evenly divided by the chunk size, the last slice
2423/// of the iteration will be the remainder.
2424///
2425/// This struct is created by the [`rchunks`] method on [slices].
2426///
2427/// # Example
2428///
2429/// ```
2430/// let slice = ['l', 'o', 'r', 'e', 'm'];
2431/// let mut iter = slice.rchunks(2);
2432/// assert_eq!(iter.next(), Some(&['e', 'm'][..]));
2433/// assert_eq!(iter.next(), Some(&['o', 'r'][..]));
2434/// assert_eq!(iter.next(), Some(&['l'][..]));
2435/// assert_eq!(iter.next(), None);
2436/// ```
2437///
2438/// [`rchunks`]: slice::rchunks
2439/// [slices]: slice
2440#[derive(Debug)]
2441#[stable(feature = "rchunks", since = "1.31.0")]
2442#[must_use = "iterators are lazy and do nothing unless consumed"]
2443#[cfg(not(feature = "ferrocene_certified"))]
2444pub struct RChunks<'a, T: 'a> {
2445    v: &'a [T],
2446    chunk_size: usize,
2447}
2448
2449#[cfg(not(feature = "ferrocene_certified"))]
2450impl<'a, T: 'a> RChunks<'a, T> {
2451    #[inline]
2452    pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
2453        Self { v: slice, chunk_size: size }
2454    }
2455}
2456
2457// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2458#[stable(feature = "rchunks", since = "1.31.0")]
2459#[cfg(not(feature = "ferrocene_certified"))]
2460impl<T> Clone for RChunks<'_, T> {
2461    fn clone(&self) -> Self {
2462        RChunks { v: self.v, chunk_size: self.chunk_size }
2463    }
2464}
2465
2466#[stable(feature = "rchunks", since = "1.31.0")]
2467#[cfg(not(feature = "ferrocene_certified"))]
2468impl<'a, T> Iterator for RChunks<'a, T> {
2469    type Item = &'a [T];
2470
2471    #[inline]
2472    fn next(&mut self) -> Option<&'a [T]> {
2473        if self.v.is_empty() {
2474            None
2475        } else {
2476            let len = self.v.len();
2477            let chunksz = cmp::min(len, self.chunk_size);
2478            // SAFETY: split_at_unchecked just requires the argument be less
2479            // than the length. This could only happen if the expression `len -
2480            // chunksz` overflows. This could only happen if `chunksz > len`,
2481            // which is impossible as we initialize it as the `min` of `len` and
2482            // `self.chunk_size`.
2483            let (fst, snd) = unsafe { self.v.split_at_unchecked(len - chunksz) };
2484            self.v = fst;
2485            Some(snd)
2486        }
2487    }
2488
2489    #[inline]
2490    fn size_hint(&self) -> (usize, Option<usize>) {
2491        if self.v.is_empty() {
2492            (0, Some(0))
2493        } else {
2494            let n = self.v.len() / self.chunk_size;
2495            let rem = self.v.len() % self.chunk_size;
2496            let n = if rem > 0 { n + 1 } else { n };
2497            (n, Some(n))
2498        }
2499    }
2500
2501    #[inline]
2502    fn count(self) -> usize {
2503        self.len()
2504    }
2505
2506    #[inline]
2507    fn nth(&mut self, n: usize) -> Option<Self::Item> {
2508        let (end, overflow) = n.overflowing_mul(self.chunk_size);
2509        if end >= self.v.len() || overflow {
2510            self.v = &self.v[..0]; // cheaper than &[]
2511            None
2512        } else {
2513            // Can't underflow because of the check above
2514            let end = self.v.len() - end;
2515            let start = match end.checked_sub(self.chunk_size) {
2516                Some(sum) => sum,
2517                None => 0,
2518            };
2519            let nth = &self.v[start..end];
2520            self.v = &self.v[0..start];
2521            Some(nth)
2522        }
2523    }
2524
2525    #[inline]
2526    fn last(self) -> Option<Self::Item> {
2527        if self.v.is_empty() {
2528            None
2529        } else {
2530            let rem = self.v.len() % self.chunk_size;
2531            let end = if rem == 0 { self.chunk_size } else { rem };
2532            Some(&self.v[0..end])
2533        }
2534    }
2535
2536    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2537        let end = self.v.len() - idx * self.chunk_size;
2538        let start = match end.checked_sub(self.chunk_size) {
2539            None => 0,
2540            Some(start) => start,
2541        };
2542        // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
2543        unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
2544    }
2545}
2546
2547#[stable(feature = "rchunks", since = "1.31.0")]
2548#[cfg(not(feature = "ferrocene_certified"))]
2549impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
2550    #[inline]
2551    fn next_back(&mut self) -> Option<&'a [T]> {
2552        if self.v.is_empty() {
2553            None
2554        } else {
2555            let remainder = self.v.len() % self.chunk_size;
2556            let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
2557            // SAFETY: similar to Chunks::next_back
2558            let (fst, snd) = unsafe { self.v.split_at_unchecked(chunksz) };
2559            self.v = snd;
2560            Some(fst)
2561        }
2562    }
2563
2564    #[inline]
2565    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2566        let len = self.len();
2567        if n >= len {
2568            self.v = &self.v[..0]; // cheaper than &[]
2569            None
2570        } else {
2571            // can't underflow because `n < len`
2572            let offset_from_end = (len - 1 - n) * self.chunk_size;
2573            let end = self.v.len() - offset_from_end;
2574            let start = end.saturating_sub(self.chunk_size);
2575            let nth_back = &self.v[start..end];
2576            self.v = &self.v[end..];
2577            Some(nth_back)
2578        }
2579    }
2580}
2581
2582#[stable(feature = "rchunks", since = "1.31.0")]
2583#[cfg(not(feature = "ferrocene_certified"))]
2584impl<T> ExactSizeIterator for RChunks<'_, T> {}
2585
2586#[unstable(feature = "trusted_len", issue = "37572")]
2587#[cfg(not(feature = "ferrocene_certified"))]
2588unsafe impl<T> TrustedLen for RChunks<'_, T> {}
2589
2590#[stable(feature = "rchunks", since = "1.31.0")]
2591#[cfg(not(feature = "ferrocene_certified"))]
2592impl<T> FusedIterator for RChunks<'_, T> {}
2593
2594#[doc(hidden)]
2595#[unstable(feature = "trusted_random_access", issue = "none")]
2596#[cfg(not(feature = "ferrocene_certified"))]
2597unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {}
2598
2599#[doc(hidden)]
2600#[unstable(feature = "trusted_random_access", issue = "none")]
2601#[cfg(not(feature = "ferrocene_certified"))]
2602unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> {
2603    const MAY_HAVE_SIDE_EFFECT: bool = false;
2604}
2605
2606/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
2607/// elements at a time), starting at the end of the slice.
2608///
2609/// When the slice len is not evenly divided by the chunk size, the last slice
2610/// of the iteration will be the remainder.
2611///
2612/// This struct is created by the [`rchunks_mut`] method on [slices].
2613///
2614/// # Example
2615///
2616/// ```
2617/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
2618/// let iter = slice.rchunks_mut(2);
2619/// ```
2620///
2621/// [`rchunks_mut`]: slice::rchunks_mut
2622/// [slices]: slice
2623#[derive(Debug)]
2624#[stable(feature = "rchunks", since = "1.31.0")]
2625#[must_use = "iterators are lazy and do nothing unless consumed"]
2626#[cfg(not(feature = "ferrocene_certified"))]
2627pub struct RChunksMut<'a, T: 'a> {
2628    /// # Safety
2629    /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
2630    /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
2631    /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
2632    /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
2633    /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
2634    v: *mut [T],
2635    chunk_size: usize,
2636    _marker: PhantomData<&'a mut T>,
2637}
2638
2639#[cfg(not(feature = "ferrocene_certified"))]
2640impl<'a, T: 'a> RChunksMut<'a, T> {
2641    #[inline]
2642    pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
2643        Self { v: slice, chunk_size: size, _marker: PhantomData }
2644    }
2645}
2646
2647#[stable(feature = "rchunks", since = "1.31.0")]
2648#[cfg(not(feature = "ferrocene_certified"))]
2649impl<'a, T> Iterator for RChunksMut<'a, T> {
2650    type Item = &'a mut [T];
2651
2652    #[inline]
2653    fn next(&mut self) -> Option<&'a mut [T]> {
2654        if self.v.is_empty() {
2655            None
2656        } else {
2657            let sz = cmp::min(self.v.len(), self.chunk_size);
2658            let len = self.v.len();
2659            // SAFETY: split_at_mut_unchecked just requires the argument be less
2660            // than the length. This could only happen if the expression
2661            // `len - sz` overflows. This could only happen if `sz >
2662            // len`, which is impossible as we initialize it as the `min` of
2663            // `self.v.len()` (e.g. `len`) and `self.chunk_size`.
2664            let (head, tail) = unsafe { self.v.split_at_mut_unchecked(len - sz) };
2665            self.v = head;
2666            // SAFETY: Nothing else points to or will point to the contents of this slice.
2667            Some(unsafe { &mut *tail })
2668        }
2669    }
2670
2671    #[inline]
2672    fn size_hint(&self) -> (usize, Option<usize>) {
2673        if self.v.is_empty() {
2674            (0, Some(0))
2675        } else {
2676            let n = self.v.len() / self.chunk_size;
2677            let rem = self.v.len() % self.chunk_size;
2678            let n = if rem > 0 { n + 1 } else { n };
2679            (n, Some(n))
2680        }
2681    }
2682
2683    #[inline]
2684    fn count(self) -> usize {
2685        self.len()
2686    }
2687
2688    #[inline]
2689    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2690        let (end, overflow) = n.overflowing_mul(self.chunk_size);
2691        if end >= self.v.len() || overflow {
2692            self.v = &mut [];
2693            None
2694        } else {
2695            // Can't underflow because of the check above
2696            let end = self.v.len() - end;
2697            let start = match end.checked_sub(self.chunk_size) {
2698                Some(sum) => sum,
2699                None => 0,
2700            };
2701            // SAFETY: This type ensures that self.v is a valid pointer with a correct len.
2702            // Therefore the bounds check in split_at_mut guarantees the split point is inbounds.
2703            let (head, tail) = unsafe { self.v.split_at_mut(start) };
2704            // SAFETY: This type ensures that self.v is a valid pointer with a correct len.
2705            // Therefore the bounds check in split_at_mut guarantees the split point is inbounds.
2706            let (nth, _) = unsafe { tail.split_at_mut(end - start) };
2707            self.v = head;
2708            // SAFETY: Nothing else points to or will point to the contents of this slice.
2709            Some(unsafe { &mut *nth })
2710        }
2711    }
2712
2713    #[inline]
2714    fn last(self) -> Option<Self::Item> {
2715        if self.v.is_empty() {
2716            None
2717        } else {
2718            let rem = self.v.len() % self.chunk_size;
2719            let end = if rem == 0 { self.chunk_size } else { rem };
2720            // SAFETY: Nothing else points to or will point to the contents of this slice.
2721            Some(unsafe { &mut *self.v.get_unchecked_mut(0..end) })
2722        }
2723    }
2724
2725    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2726        let end = self.v.len() - idx * self.chunk_size;
2727        let start = match end.checked_sub(self.chunk_size) {
2728            None => 0,
2729            Some(start) => start,
2730        };
2731        // SAFETY: see comments for `RChunks::__iterator_get_unchecked` and
2732        // `ChunksMut::__iterator_get_unchecked`, `self.v`.
2733        unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
2734    }
2735}
2736
2737#[stable(feature = "rchunks", since = "1.31.0")]
2738#[cfg(not(feature = "ferrocene_certified"))]
2739impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
2740    #[inline]
2741    fn next_back(&mut self) -> Option<&'a mut [T]> {
2742        if self.v.is_empty() {
2743            None
2744        } else {
2745            let remainder = self.v.len() % self.chunk_size;
2746            let sz = if remainder != 0 { remainder } else { self.chunk_size };
2747            // SAFETY: Similar to `Chunks::next_back`
2748            let (head, tail) = unsafe { self.v.split_at_mut_unchecked(sz) };
2749            self.v = tail;
2750            // SAFETY: Nothing else points to or will point to the contents of this slice.
2751            Some(unsafe { &mut *head })
2752        }
2753    }
2754
2755    #[inline]
2756    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2757        let len = self.len();
2758        if n >= len {
2759            self.v = &mut [];
2760            None
2761        } else {
2762            // can't underflow because `n < len`
2763            let offset_from_end = (len - 1 - n) * self.chunk_size;
2764            let end = self.v.len() - offset_from_end;
2765            let start = end.saturating_sub(self.chunk_size);
2766            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2767            let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
2768            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2769            let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
2770            self.v = tail;
2771            // SAFETY: Nothing else points to or will point to the contents of this slice.
2772            Some(unsafe { &mut *nth_back })
2773        }
2774    }
2775}
2776
2777#[stable(feature = "rchunks", since = "1.31.0")]
2778#[cfg(not(feature = "ferrocene_certified"))]
2779impl<T> ExactSizeIterator for RChunksMut<'_, T> {}
2780
2781#[unstable(feature = "trusted_len", issue = "37572")]
2782#[cfg(not(feature = "ferrocene_certified"))]
2783unsafe impl<T> TrustedLen for RChunksMut<'_, T> {}
2784
2785#[stable(feature = "rchunks", since = "1.31.0")]
2786#[cfg(not(feature = "ferrocene_certified"))]
2787impl<T> FusedIterator for RChunksMut<'_, T> {}
2788
2789#[doc(hidden)]
2790#[unstable(feature = "trusted_random_access", issue = "none")]
2791#[cfg(not(feature = "ferrocene_certified"))]
2792unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {}
2793
2794#[doc(hidden)]
2795#[unstable(feature = "trusted_random_access", issue = "none")]
2796#[cfg(not(feature = "ferrocene_certified"))]
2797unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksMut<'a, T> {
2798    const MAY_HAVE_SIDE_EFFECT: bool = false;
2799}
2800
2801#[stable(feature = "rchunks", since = "1.31.0")]
2802#[cfg(not(feature = "ferrocene_certified"))]
2803unsafe impl<T> Send for RChunksMut<'_, T> where T: Send {}
2804
2805#[stable(feature = "rchunks", since = "1.31.0")]
2806#[cfg(not(feature = "ferrocene_certified"))]
2807unsafe impl<T> Sync for RChunksMut<'_, T> where T: Sync {}
2808
2809/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
2810/// time), starting at the end of the slice.
2811///
2812/// When the slice len is not evenly divided by the chunk size, the last
2813/// up to `chunk_size-1` elements will be omitted but can be retrieved from
2814/// the [`remainder`] function from the iterator.
2815///
2816/// This struct is created by the [`rchunks_exact`] method on [slices].
2817///
2818/// # Example
2819///
2820/// ```
2821/// let slice = ['l', 'o', 'r', 'e', 'm'];
2822/// let mut iter = slice.rchunks_exact(2);
2823/// assert_eq!(iter.next(), Some(&['e', 'm'][..]));
2824/// assert_eq!(iter.next(), Some(&['o', 'r'][..]));
2825/// assert_eq!(iter.next(), None);
2826/// ```
2827///
2828/// [`rchunks_exact`]: slice::rchunks_exact
2829/// [`remainder`]: RChunksExact::remainder
2830/// [slices]: slice
2831#[derive(Debug)]
2832#[stable(feature = "rchunks", since = "1.31.0")]
2833#[must_use = "iterators are lazy and do nothing unless consumed"]
2834#[cfg(not(feature = "ferrocene_certified"))]
2835pub struct RChunksExact<'a, T: 'a> {
2836    v: &'a [T],
2837    rem: &'a [T],
2838    chunk_size: usize,
2839}
2840
2841#[cfg(not(feature = "ferrocene_certified"))]
2842impl<'a, T> RChunksExact<'a, T> {
2843    #[inline]
2844    pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
2845        let rem = slice.len() % chunk_size;
2846        // SAFETY: 0 <= rem <= slice.len() by construction above
2847        let (fst, snd) = unsafe { slice.split_at_unchecked(rem) };
2848        Self { v: snd, rem: fst, chunk_size }
2849    }
2850
2851    /// Returns the remainder of the original slice that is not going to be
2852    /// returned by the iterator. The returned slice has at most `chunk_size-1`
2853    /// elements.
2854    ///
2855    /// # Example
2856    ///
2857    /// ```
2858    /// let slice = ['l', 'o', 'r', 'e', 'm'];
2859    /// let mut iter = slice.rchunks_exact(2);
2860    /// assert_eq!(iter.remainder(), &['l'][..]);
2861    /// assert_eq!(iter.next(), Some(&['e', 'm'][..]));
2862    /// assert_eq!(iter.remainder(), &['l'][..]);
2863    /// assert_eq!(iter.next(), Some(&['o', 'r'][..]));
2864    /// assert_eq!(iter.remainder(), &['l'][..]);
2865    /// assert_eq!(iter.next(), None);
2866    /// assert_eq!(iter.remainder(), &['l'][..]);
2867    /// ```
2868    #[must_use]
2869    #[stable(feature = "rchunks", since = "1.31.0")]
2870    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
2871    pub const fn remainder(&self) -> &'a [T] {
2872        self.rem
2873    }
2874}
2875
2876// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2877#[stable(feature = "rchunks", since = "1.31.0")]
2878#[cfg(not(feature = "ferrocene_certified"))]
2879impl<'a, T> Clone for RChunksExact<'a, T> {
2880    fn clone(&self) -> RChunksExact<'a, T> {
2881        RChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
2882    }
2883}
2884
2885#[stable(feature = "rchunks", since = "1.31.0")]
2886#[cfg(not(feature = "ferrocene_certified"))]
2887impl<'a, T> Iterator for RChunksExact<'a, T> {
2888    type Item = &'a [T];
2889
2890    #[inline]
2891    fn next(&mut self) -> Option<&'a [T]> {
2892        if self.v.len() < self.chunk_size {
2893            None
2894        } else {
2895            let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
2896            self.v = fst;
2897            Some(snd)
2898        }
2899    }
2900
2901    #[inline]
2902    fn size_hint(&self) -> (usize, Option<usize>) {
2903        let n = self.v.len() / self.chunk_size;
2904        (n, Some(n))
2905    }
2906
2907    #[inline]
2908    fn count(self) -> usize {
2909        self.len()
2910    }
2911
2912    #[inline]
2913    fn nth(&mut self, n: usize) -> Option<Self::Item> {
2914        let (end, overflow) = n.overflowing_mul(self.chunk_size);
2915        if end >= self.v.len() || overflow {
2916            self.v = &self.v[..0]; // cheaper than &[]
2917            None
2918        } else {
2919            let (fst, _) = self.v.split_at(self.v.len() - end);
2920            self.v = fst;
2921            self.next()
2922        }
2923    }
2924
2925    #[inline]
2926    fn last(mut self) -> Option<Self::Item> {
2927        self.next_back()
2928    }
2929
2930    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2931        let end = self.v.len() - idx * self.chunk_size;
2932        let start = end - self.chunk_size;
2933        // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
2934        unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
2935    }
2936}
2937
2938#[stable(feature = "rchunks", since = "1.31.0")]
2939#[cfg(not(feature = "ferrocene_certified"))]
2940impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
2941    #[inline]
2942    fn next_back(&mut self) -> Option<&'a [T]> {
2943        if self.v.len() < self.chunk_size {
2944            None
2945        } else {
2946            let (fst, snd) = self.v.split_at(self.chunk_size);
2947            self.v = snd;
2948            Some(fst)
2949        }
2950    }
2951
2952    #[inline]
2953    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2954        let len = self.len();
2955        if n >= len {
2956            self.v = &self.v[..0]; // cheaper than &[]
2957            None
2958        } else {
2959            // now that we know that `n` corresponds to a chunk,
2960            // none of these operations can underflow/overflow
2961            let offset = (len - n) * self.chunk_size;
2962            let start = self.v.len() - offset;
2963            let end = start + self.chunk_size;
2964            let nth_back = &self.v[start..end];
2965            self.v = &self.v[end..];
2966            Some(nth_back)
2967        }
2968    }
2969}
2970
2971#[stable(feature = "rchunks", since = "1.31.0")]
2972#[cfg(not(feature = "ferrocene_certified"))]
2973impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
2974    fn is_empty(&self) -> bool {
2975        self.v.is_empty()
2976    }
2977}
2978
2979#[unstable(feature = "trusted_len", issue = "37572")]
2980#[cfg(not(feature = "ferrocene_certified"))]
2981unsafe impl<T> TrustedLen for RChunksExact<'_, T> {}
2982
2983#[stable(feature = "rchunks", since = "1.31.0")]
2984#[cfg(not(feature = "ferrocene_certified"))]
2985impl<T> FusedIterator for RChunksExact<'_, T> {}
2986
2987#[doc(hidden)]
2988#[unstable(feature = "trusted_random_access", issue = "none")]
2989#[cfg(not(feature = "ferrocene_certified"))]
2990unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {}
2991
2992#[doc(hidden)]
2993#[unstable(feature = "trusted_random_access", issue = "none")]
2994#[cfg(not(feature = "ferrocene_certified"))]
2995unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
2996    const MAY_HAVE_SIDE_EFFECT: bool = false;
2997}
2998
2999/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
3000/// elements at a time), starting at the end of the slice.
3001///
3002/// When the slice len is not evenly divided by the chunk size, the last up to
3003/// `chunk_size-1` elements will be omitted but can be retrieved from the
3004/// [`into_remainder`] function from the iterator.
3005///
3006/// This struct is created by the [`rchunks_exact_mut`] method on [slices].
3007///
3008/// # Example
3009///
3010/// ```
3011/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
3012/// let iter = slice.rchunks_exact_mut(2);
3013/// ```
3014///
3015/// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
3016/// [`into_remainder`]: RChunksExactMut::into_remainder
3017/// [slices]: slice
3018#[derive(Debug)]
3019#[stable(feature = "rchunks", since = "1.31.0")]
3020#[must_use = "iterators are lazy and do nothing unless consumed"]
3021#[cfg(not(feature = "ferrocene_certified"))]
3022pub struct RChunksExactMut<'a, T: 'a> {
3023    /// # Safety
3024    /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
3025    /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
3026    /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
3027    /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
3028    /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
3029    v: *mut [T],
3030    rem: &'a mut [T],
3031    chunk_size: usize,
3032}
3033
3034#[cfg(not(feature = "ferrocene_certified"))]
3035impl<'a, T> RChunksExactMut<'a, T> {
3036    #[inline]
3037    pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
3038        let rem = slice.len() % chunk_size;
3039        // SAFETY: 0 <= rem <= slice.len() by construction above
3040        let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) };
3041        Self { v: snd, rem: fst, chunk_size }
3042    }
3043
3044    /// Returns the remainder of the original slice that is not going to be
3045    /// returned by the iterator. The returned slice has at most `chunk_size-1`
3046    /// elements.
3047    #[must_use = "`self` will be dropped if the result is not used"]
3048    #[stable(feature = "rchunks", since = "1.31.0")]
3049    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
3050    pub const fn into_remainder(self) -> &'a mut [T] {
3051        self.rem
3052    }
3053}
3054
3055#[stable(feature = "rchunks", since = "1.31.0")]
3056#[cfg(not(feature = "ferrocene_certified"))]
3057impl<'a, T> Iterator for RChunksExactMut<'a, T> {
3058    type Item = &'a mut [T];
3059
3060    #[inline]
3061    fn next(&mut self) -> Option<&'a mut [T]> {
3062        if self.v.len() < self.chunk_size {
3063            None
3064        } else {
3065            let len = self.v.len();
3066            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3067            let (head, tail) = unsafe { self.v.split_at_mut(len - self.chunk_size) };
3068            self.v = head;
3069            // SAFETY: Nothing else points to or will point to the contents of this slice.
3070            Some(unsafe { &mut *tail })
3071        }
3072    }
3073
3074    #[inline]
3075    fn size_hint(&self) -> (usize, Option<usize>) {
3076        let n = self.v.len() / self.chunk_size;
3077        (n, Some(n))
3078    }
3079
3080    #[inline]
3081    fn count(self) -> usize {
3082        self.len()
3083    }
3084
3085    #[inline]
3086    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
3087        let (end, overflow) = n.overflowing_mul(self.chunk_size);
3088        if end >= self.v.len() || overflow {
3089            self.v = &mut [];
3090            None
3091        } else {
3092            let len = self.v.len();
3093            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3094            let (fst, _) = unsafe { self.v.split_at_mut(len - end) };
3095            self.v = fst;
3096            self.next()
3097        }
3098    }
3099
3100    #[inline]
3101    fn last(mut self) -> Option<Self::Item> {
3102        self.next_back()
3103    }
3104
3105    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
3106        let end = self.v.len() - idx * self.chunk_size;
3107        let start = end - self.chunk_size;
3108        // SAFETY: see comments for `RChunksMut::__iterator_get_unchecked` and `self.v`.
3109        unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
3110    }
3111}
3112
3113#[stable(feature = "rchunks", since = "1.31.0")]
3114#[cfg(not(feature = "ferrocene_certified"))]
3115impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
3116    #[inline]
3117    fn next_back(&mut self) -> Option<&'a mut [T]> {
3118        if self.v.len() < self.chunk_size {
3119            None
3120        } else {
3121            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3122            let (head, tail) = unsafe { self.v.split_at_mut(self.chunk_size) };
3123            self.v = tail;
3124            // SAFETY: Nothing else points to or will point to the contents of this slice.
3125            Some(unsafe { &mut *head })
3126        }
3127    }
3128
3129    #[inline]
3130    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
3131        let len = self.len();
3132        if n >= len {
3133            self.v = &mut [];
3134            None
3135        } else {
3136            // now that we know that `n` corresponds to a chunk,
3137            // none of these operations can underflow/overflow
3138            let offset = (len - n) * self.chunk_size;
3139            let start = self.v.len() - offset;
3140            let end = start + self.chunk_size;
3141            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3142            let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
3143            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3144            let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
3145            self.v = tail;
3146            // SAFETY: Nothing else points to or will point to the contents of this slice.
3147            Some(unsafe { &mut *nth_back })
3148        }
3149    }
3150}
3151
3152#[stable(feature = "rchunks", since = "1.31.0")]
3153#[cfg(not(feature = "ferrocene_certified"))]
3154impl<T> ExactSizeIterator for RChunksExactMut<'_, T> {
3155    fn is_empty(&self) -> bool {
3156        self.v.is_empty()
3157    }
3158}
3159
3160#[unstable(feature = "trusted_len", issue = "37572")]
3161#[cfg(not(feature = "ferrocene_certified"))]
3162unsafe impl<T> TrustedLen for RChunksExactMut<'_, T> {}
3163
3164#[stable(feature = "rchunks", since = "1.31.0")]
3165#[cfg(not(feature = "ferrocene_certified"))]
3166impl<T> FusedIterator for RChunksExactMut<'_, T> {}
3167
3168#[doc(hidden)]
3169#[unstable(feature = "trusted_random_access", issue = "none")]
3170#[cfg(not(feature = "ferrocene_certified"))]
3171unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {}
3172
3173#[doc(hidden)]
3174#[unstable(feature = "trusted_random_access", issue = "none")]
3175#[cfg(not(feature = "ferrocene_certified"))]
3176unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExactMut<'a, T> {
3177    const MAY_HAVE_SIDE_EFFECT: bool = false;
3178}
3179
3180#[stable(feature = "rchunks", since = "1.31.0")]
3181#[cfg(not(feature = "ferrocene_certified"))]
3182unsafe impl<T> Send for RChunksExactMut<'_, T> where T: Send {}
3183
3184#[stable(feature = "rchunks", since = "1.31.0")]
3185#[cfg(not(feature = "ferrocene_certified"))]
3186unsafe impl<T> Sync for RChunksExactMut<'_, T> where T: Sync {}
3187
3188#[doc(hidden)]
3189#[unstable(feature = "trusted_random_access", issue = "none")]
3190#[cfg(not(feature = "ferrocene_certified"))]
3191unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {}
3192
3193#[doc(hidden)]
3194#[unstable(feature = "trusted_random_access", issue = "none")]
3195#[cfg(not(feature = "ferrocene_certified"))]
3196unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Iter<'a, T> {
3197    const MAY_HAVE_SIDE_EFFECT: bool = false;
3198}
3199
3200#[doc(hidden)]
3201#[unstable(feature = "trusted_random_access", issue = "none")]
3202#[cfg(not(feature = "ferrocene_certified"))]
3203unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {}
3204
3205#[doc(hidden)]
3206#[unstable(feature = "trusted_random_access", issue = "none")]
3207#[cfg(not(feature = "ferrocene_certified"))]
3208unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {
3209    const MAY_HAVE_SIDE_EFFECT: bool = false;
3210}
3211
3212/// An iterator over slice in (non-overlapping) chunks separated by a predicate.
3213///
3214/// This struct is created by the [`chunk_by`] method on [slices].
3215///
3216/// [`chunk_by`]: slice::chunk_by
3217/// [slices]: slice
3218#[stable(feature = "slice_group_by", since = "1.77.0")]
3219#[must_use = "iterators are lazy and do nothing unless consumed"]
3220#[cfg(not(feature = "ferrocene_certified"))]
3221pub struct ChunkBy<'a, T: 'a, P> {
3222    slice: &'a [T],
3223    predicate: P,
3224}
3225
3226#[stable(feature = "slice_group_by", since = "1.77.0")]
3227#[cfg(not(feature = "ferrocene_certified"))]
3228impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
3229    pub(super) const fn new(slice: &'a [T], predicate: P) -> Self {
3230        ChunkBy { slice, predicate }
3231    }
3232}
3233
3234#[stable(feature = "slice_group_by", since = "1.77.0")]
3235#[cfg(not(feature = "ferrocene_certified"))]
3236impl<'a, T: 'a, P> Iterator for ChunkBy<'a, T, P>
3237where
3238    P: FnMut(&T, &T) -> bool,
3239{
3240    type Item = &'a [T];
3241
3242    #[inline]
3243    fn next(&mut self) -> Option<Self::Item> {
3244        if self.slice.is_empty() {
3245            None
3246        } else {
3247            let mut len = 1;
3248            let mut iter = self.slice.windows(2);
3249            while let Some([l, r]) = iter.next() {
3250                if (self.predicate)(l, r) { len += 1 } else { break }
3251            }
3252            let (head, tail) = self.slice.split_at(len);
3253            self.slice = tail;
3254            Some(head)
3255        }
3256    }
3257
3258    #[inline]
3259    fn size_hint(&self) -> (usize, Option<usize>) {
3260        if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) }
3261    }
3262
3263    #[inline]
3264    fn last(mut self) -> Option<Self::Item> {
3265        self.next_back()
3266    }
3267}
3268
3269#[stable(feature = "slice_group_by", since = "1.77.0")]
3270#[cfg(not(feature = "ferrocene_certified"))]
3271impl<'a, T: 'a, P> DoubleEndedIterator for ChunkBy<'a, T, P>
3272where
3273    P: FnMut(&T, &T) -> bool,
3274{
3275    #[inline]
3276    fn next_back(&mut self) -> Option<Self::Item> {
3277        if self.slice.is_empty() {
3278            None
3279        } else {
3280            let mut len = 1;
3281            let mut iter = self.slice.windows(2);
3282            while let Some([l, r]) = iter.next_back() {
3283                if (self.predicate)(l, r) { len += 1 } else { break }
3284            }
3285            let (head, tail) = self.slice.split_at(self.slice.len() - len);
3286            self.slice = head;
3287            Some(tail)
3288        }
3289    }
3290}
3291
3292#[stable(feature = "slice_group_by", since = "1.77.0")]
3293#[cfg(not(feature = "ferrocene_certified"))]
3294impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
3295
3296#[stable(feature = "slice_group_by_clone", since = "1.89.0")]
3297#[cfg(not(feature = "ferrocene_certified"))]
3298impl<'a, T: 'a, P: Clone> Clone for ChunkBy<'a, T, P> {
3299    fn clone(&self) -> Self {
3300        Self { slice: self.slice, predicate: self.predicate.clone() }
3301    }
3302}
3303
3304#[stable(feature = "slice_group_by", since = "1.77.0")]
3305#[cfg(not(feature = "ferrocene_certified"))]
3306impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
3307    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3308        f.debug_struct("ChunkBy").field("slice", &self.slice).finish()
3309    }
3310}
3311
3312/// An iterator over slice in (non-overlapping) mutable chunks separated
3313/// by a predicate.
3314///
3315/// This struct is created by the [`chunk_by_mut`] method on [slices].
3316///
3317/// [`chunk_by_mut`]: slice::chunk_by_mut
3318/// [slices]: slice
3319#[stable(feature = "slice_group_by", since = "1.77.0")]
3320#[must_use = "iterators are lazy and do nothing unless consumed"]
3321#[cfg(not(feature = "ferrocene_certified"))]
3322pub struct ChunkByMut<'a, T: 'a, P> {
3323    slice: &'a mut [T],
3324    predicate: P,
3325}
3326
3327#[stable(feature = "slice_group_by", since = "1.77.0")]
3328#[cfg(not(feature = "ferrocene_certified"))]
3329impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
3330    pub(super) const fn new(slice: &'a mut [T], predicate: P) -> Self {
3331        ChunkByMut { slice, predicate }
3332    }
3333}
3334
3335#[stable(feature = "slice_group_by", since = "1.77.0")]
3336#[cfg(not(feature = "ferrocene_certified"))]
3337impl<'a, T: 'a, P> Iterator for ChunkByMut<'a, T, P>
3338where
3339    P: FnMut(&T, &T) -> bool,
3340{
3341    type Item = &'a mut [T];
3342
3343    #[inline]
3344    fn next(&mut self) -> Option<Self::Item> {
3345        if self.slice.is_empty() {
3346            None
3347        } else {
3348            let mut len = 1;
3349            let mut iter = self.slice.windows(2);
3350            while let Some([l, r]) = iter.next() {
3351                if (self.predicate)(l, r) { len += 1 } else { break }
3352            }
3353            let slice = mem::take(&mut self.slice);
3354            let (head, tail) = slice.split_at_mut(len);
3355            self.slice = tail;
3356            Some(head)
3357        }
3358    }
3359
3360    #[inline]
3361    fn size_hint(&self) -> (usize, Option<usize>) {
3362        if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) }
3363    }
3364
3365    #[inline]
3366    fn last(mut self) -> Option<Self::Item> {
3367        self.next_back()
3368    }
3369}
3370
3371#[stable(feature = "slice_group_by", since = "1.77.0")]
3372#[cfg(not(feature = "ferrocene_certified"))]
3373impl<'a, T: 'a, P> DoubleEndedIterator for ChunkByMut<'a, T, P>
3374where
3375    P: FnMut(&T, &T) -> bool,
3376{
3377    #[inline]
3378    fn next_back(&mut self) -> Option<Self::Item> {
3379        if self.slice.is_empty() {
3380            None
3381        } else {
3382            let mut len = 1;
3383            let mut iter = self.slice.windows(2);
3384            while let Some([l, r]) = iter.next_back() {
3385                if (self.predicate)(l, r) { len += 1 } else { break }
3386            }
3387            let slice = mem::take(&mut self.slice);
3388            let (head, tail) = slice.split_at_mut(slice.len() - len);
3389            self.slice = head;
3390            Some(tail)
3391        }
3392    }
3393}
3394
3395#[stable(feature = "slice_group_by", since = "1.77.0")]
3396#[cfg(not(feature = "ferrocene_certified"))]
3397impl<'a, T: 'a, P> FusedIterator for ChunkByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
3398
3399#[stable(feature = "slice_group_by", since = "1.77.0")]
3400#[cfg(not(feature = "ferrocene_certified"))]
3401impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkByMut<'a, T, P> {
3402    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3403        f.debug_struct("ChunkByMut").field("slice", &self.slice).finish()
3404    }
3405}