Skip to main content

core/slice/
iter.rs

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