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