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