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