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    fn count(self) -> usize {
1462        self.len()
1463    }
1464
1465    #[inline]
1466    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1467        let size = self.size.get();
1468        if let Some(rest) = self.v.get(n..)
1469            && let Some(nth) = rest.get(..size)
1470        {
1471            self.v = &rest[1..];
1472            Some(nth)
1473        } else {
1474            // setting length to 0 is cheaper than overwriting the pointer when assigning &[]
1475            self.v = &self.v[..0]; // cheaper than &[]
1476            None
1477        }
1478    }
1479
1480    #[inline]
1481    fn last(self) -> Option<Self::Item> {
1482        if self.size.get() > self.v.len() {
1483            None
1484        } else {
1485            let start = self.v.len() - self.size.get();
1486            Some(&self.v[start..])
1487        }
1488    }
1489
1490    #[cfg(not(feature = "ferrocene_subset"))]
1491    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1492        // SAFETY: since the caller guarantees that `i` is in bounds,
1493        // which means that `i` cannot overflow an `isize`, and the
1494        // slice created by `from_raw_parts` is a subslice of `self.v`
1495        // thus is guaranteed to be valid for the lifetime `'a` of `self.v`.
1496        unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size.get()) }
1497    }
1498}
1499
1500#[stable(feature = "rust1", since = "1.0.0")]
1501#[cfg(not(feature = "ferrocene_subset"))]
1502impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
1503    #[inline]
1504    fn next_back(&mut self) -> Option<Self::Item> {
1505        self.nth_back(0)
1506    }
1507
1508    #[inline]
1509    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1510        if let Some(end) = self.v.len().checked_sub(n)
1511            && let Some(start) = end.checked_sub(self.size.get())
1512        {
1513            let res = &self.v[start..end];
1514            self.v = &self.v[..end - 1];
1515            Some(res)
1516        } else {
1517            self.v = &self.v[..0]; // cheaper than &[]
1518            None
1519        }
1520    }
1521}
1522
1523#[stable(feature = "rust1", since = "1.0.0")]
1524impl<T> ExactSizeIterator for Windows<'_, T> {}
1525
1526#[unstable(feature = "trusted_len", issue = "37572")]
1527#[cfg(not(feature = "ferrocene_subset"))]
1528unsafe impl<T> TrustedLen for Windows<'_, T> {}
1529
1530#[stable(feature = "fused", since = "1.26.0")]
1531#[cfg(not(feature = "ferrocene_subset"))]
1532impl<T> FusedIterator for Windows<'_, T> {}
1533
1534#[doc(hidden)]
1535#[unstable(feature = "trusted_random_access", issue = "none")]
1536#[cfg(not(feature = "ferrocene_subset"))]
1537unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {}
1538
1539#[doc(hidden)]
1540#[unstable(feature = "trusted_random_access", issue = "none")]
1541#[cfg(not(feature = "ferrocene_subset"))]
1542unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Windows<'a, T> {
1543    const MAY_HAVE_SIDE_EFFECT: bool = false;
1544}
1545
1546/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
1547/// time), starting at the beginning of the slice.
1548///
1549/// When the slice len is not evenly divided by the chunk size, the last slice
1550/// of the iteration will be the remainder.
1551///
1552/// This struct is created by the [`chunks`] method on [slices].
1553///
1554/// # Example
1555///
1556/// ```
1557/// let slice = ['l', 'o', 'r', 'e', 'm'];
1558/// let mut iter = slice.chunks(2);
1559/// assert_eq!(iter.next(), Some(&['l', 'o'][..]));
1560/// assert_eq!(iter.next(), Some(&['r', 'e'][..]));
1561/// assert_eq!(iter.next(), Some(&['m'][..]));
1562/// assert_eq!(iter.next(), None);
1563/// ```
1564///
1565/// [`chunks`]: slice::chunks
1566/// [slices]: slice
1567#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
1568#[stable(feature = "rust1", since = "1.0.0")]
1569#[must_use = "iterators are lazy and do nothing unless consumed"]
1570pub struct Chunks<'a, T: 'a> {
1571    v: &'a [T],
1572    chunk_size: usize,
1573}
1574
1575impl<'a, T: 'a> Chunks<'a, T> {
1576    #[inline]
1577    pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
1578        Self { v: slice, chunk_size: size }
1579    }
1580}
1581
1582// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1583#[stable(feature = "rust1", since = "1.0.0")]
1584#[cfg(not(feature = "ferrocene_subset"))]
1585impl<T> Clone for Chunks<'_, T> {
1586    fn clone(&self) -> Self {
1587        Chunks { v: self.v, chunk_size: self.chunk_size }
1588    }
1589}
1590
1591#[stable(feature = "rust1", since = "1.0.0")]
1592impl<'a, T> Iterator for Chunks<'a, T> {
1593    type Item = &'a [T];
1594
1595    #[inline]
1596    fn next(&mut self) -> Option<&'a [T]> {
1597        if self.v.is_empty() {
1598            None
1599        } else {
1600            let chunksz = cmp::min(self.v.len(), self.chunk_size);
1601            let (fst, snd) = self.v.split_at(chunksz);
1602            self.v = snd;
1603            Some(fst)
1604        }
1605    }
1606
1607    #[inline]
1608    fn size_hint(&self) -> (usize, Option<usize>) {
1609        if self.v.is_empty() {
1610            (0, Some(0))
1611        } else {
1612            let n = self.v.len().div_ceil(self.chunk_size);
1613            (n, Some(n))
1614        }
1615    }
1616
1617    #[inline]
1618    fn count(self) -> usize {
1619        self.len()
1620    }
1621
1622    #[inline]
1623    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1624        if let Some(start) = n.checked_mul(self.chunk_size)
1625            && start < self.v.len()
1626        {
1627            let rest = &self.v[start..];
1628            let (chunk, rest) = rest.split_at(self.chunk_size.min(rest.len()));
1629            self.v = rest;
1630            Some(chunk)
1631        } else {
1632            self.v = &self.v[..0]; // cheaper than &[]
1633            None
1634        }
1635    }
1636
1637    #[inline]
1638    fn last(self) -> Option<Self::Item> {
1639        if self.v.is_empty() {
1640            None
1641        } else {
1642            let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
1643            Some(&self.v[start..])
1644        }
1645    }
1646
1647    #[cfg(not(feature = "ferrocene_subset"))]
1648    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1649        let start = idx * self.chunk_size;
1650        // SAFETY: the caller guarantees that `i` is in bounds,
1651        // which means that `start` must be in bounds of the
1652        // underlying `self.v` slice, and we made sure that `len`
1653        // is also in bounds of `self.v`. Thus, `start` cannot overflow
1654        // an `isize`, and the slice constructed by `from_raw_parts`
1655        // is a subslice of `self.v` which is guaranteed to be valid
1656        // for the lifetime `'a` of `self.v`.
1657        unsafe {
1658            let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
1659            from_raw_parts(self.v.as_ptr().add(start), len)
1660        }
1661    }
1662}
1663
1664#[stable(feature = "rust1", since = "1.0.0")]
1665#[cfg(not(feature = "ferrocene_subset"))]
1666impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
1667    #[inline]
1668    fn next_back(&mut self) -> Option<&'a [T]> {
1669        if self.v.is_empty() {
1670            None
1671        } else {
1672            let remainder = self.v.len() % self.chunk_size;
1673            let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
1674            // SAFETY: split_at_unchecked requires the argument be less than or
1675            // equal to the length. This is guaranteed, but subtle: `chunksz`
1676            // will always either be `self.v.len() % self.chunk_size`, which
1677            // will always evaluate to strictly less than `self.v.len()` (or
1678            // panic, in the case that `self.chunk_size` is zero), or it can be
1679            // `self.chunk_size`, in the case that the length is exactly
1680            // divisible by the chunk size.
1681            //
1682            // While it seems like using `self.chunk_size` in this case could
1683            // lead to a value greater than `self.v.len()`, it cannot: if
1684            // `self.chunk_size` were greater than `self.v.len()`, then
1685            // `self.v.len() % self.chunk_size` would return nonzero (note that
1686            // in this branch of the `if`, we already know that `self.v` is
1687            // non-empty).
1688            let (fst, snd) = unsafe { self.v.split_at_unchecked(self.v.len() - chunksz) };
1689            self.v = fst;
1690            Some(snd)
1691        }
1692    }
1693
1694    #[inline]
1695    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1696        let len = self.len();
1697        if n < len {
1698            let start = (len - 1 - n) * self.chunk_size;
1699            let end = start + (self.v.len() - start).min(self.chunk_size);
1700            let nth_back = &self.v[start..end];
1701            self.v = &self.v[..start];
1702            Some(nth_back)
1703        } else {
1704            self.v = &self.v[..0]; // cheaper than &[]
1705            None
1706        }
1707    }
1708}
1709
1710#[stable(feature = "rust1", since = "1.0.0")]
1711impl<T> ExactSizeIterator for Chunks<'_, T> {}
1712
1713#[unstable(feature = "trusted_len", issue = "37572")]
1714#[cfg(not(feature = "ferrocene_subset"))]
1715unsafe impl<T> TrustedLen for Chunks<'_, T> {}
1716
1717#[stable(feature = "fused", since = "1.26.0")]
1718#[cfg(not(feature = "ferrocene_subset"))]
1719impl<T> FusedIterator for Chunks<'_, T> {}
1720
1721#[doc(hidden)]
1722#[unstable(feature = "trusted_random_access", issue = "none")]
1723#[cfg(not(feature = "ferrocene_subset"))]
1724unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {}
1725
1726#[doc(hidden)]
1727#[unstable(feature = "trusted_random_access", issue = "none")]
1728#[cfg(not(feature = "ferrocene_subset"))]
1729unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Chunks<'a, T> {
1730    const MAY_HAVE_SIDE_EFFECT: bool = false;
1731}
1732
1733/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
1734/// elements at a time), starting at the beginning of the slice.
1735///
1736/// When the slice len is not evenly divided by the chunk size, the last slice
1737/// of the iteration will be the remainder.
1738///
1739/// This struct is created by the [`chunks_mut`] method on [slices].
1740///
1741/// # Example
1742///
1743/// ```
1744/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
1745/// let iter = slice.chunks_mut(2);
1746/// ```
1747///
1748/// [`chunks_mut`]: slice::chunks_mut
1749/// [slices]: slice
1750#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
1751#[stable(feature = "rust1", since = "1.0.0")]
1752#[must_use = "iterators are lazy and do nothing unless consumed"]
1753pub struct ChunksMut<'a, T: 'a> {
1754    /// # Safety
1755    /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
1756    /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
1757    /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
1758    /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
1759    /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
1760    v: *mut [T],
1761    chunk_size: usize,
1762    _marker: PhantomData<&'a mut T>,
1763}
1764
1765impl<'a, T: 'a> ChunksMut<'a, T> {
1766    #[inline]
1767    pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
1768        Self { v: slice, chunk_size: size, _marker: PhantomData }
1769    }
1770}
1771
1772#[stable(feature = "rust1", since = "1.0.0")]
1773impl<'a, T> Iterator for ChunksMut<'a, T> {
1774    type Item = &'a mut [T];
1775
1776    #[inline]
1777    fn next(&mut self) -> Option<&'a mut [T]> {
1778        if self.v.is_empty() {
1779            None
1780        } else {
1781            let sz = cmp::min(self.v.len(), self.chunk_size);
1782            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1783            let (head, tail) = unsafe { self.v.split_at_mut(sz) };
1784            self.v = tail;
1785            // SAFETY: Nothing else points to or will point to the contents of this slice.
1786            Some(unsafe { &mut *head })
1787        }
1788    }
1789
1790    #[inline]
1791    fn size_hint(&self) -> (usize, Option<usize>) {
1792        if self.v.is_empty() {
1793            (0, Some(0))
1794        } else {
1795            let n = self.v.len().div_ceil(self.chunk_size);
1796            (n, Some(n))
1797        }
1798    }
1799
1800    #[inline]
1801    fn count(self) -> usize {
1802        self.len()
1803    }
1804
1805    #[inline]
1806    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
1807        if let Some(start) = n.checked_mul(self.chunk_size)
1808            && start < self.v.len()
1809        {
1810            // SAFETY: `start < self.v.len()` ensures this is in bounds
1811            let (_, rest) = unsafe { self.v.split_at_mut(start) };
1812            // SAFETY: `.min(rest.len()` ensures this is in bounds
1813            let (chunk, rest) = unsafe { rest.split_at_mut(self.chunk_size.min(rest.len())) };
1814            self.v = rest;
1815            // SAFETY: Nothing else points to or will point to the contents of this slice.
1816            Some(unsafe { &mut *chunk })
1817        } else {
1818            self.v = &mut [];
1819            None
1820        }
1821    }
1822
1823    #[inline]
1824    fn last(self) -> Option<Self::Item> {
1825        if self.v.is_empty() {
1826            None
1827        } else {
1828            let start = (self.v.len() - 1) / self.chunk_size * self.chunk_size;
1829            // SAFETY: Nothing else points to or will point to the contents of this slice.
1830            Some(unsafe { &mut *self.v.get_unchecked_mut(start..) })
1831        }
1832    }
1833
1834    #[cfg(not(feature = "ferrocene_subset"))]
1835    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
1836        let start = idx * self.chunk_size;
1837        // SAFETY: see comments for `Chunks::__iterator_get_unchecked` and `self.v`.
1838        //
1839        // Also note that the caller also guarantees that we're never called
1840        // with the same index again, and that no other methods that will
1841        // access this subslice are called, so it is valid for the returned
1842        // slice to be mutable.
1843        unsafe {
1844            let len = cmp::min(self.v.len().unchecked_sub(start), self.chunk_size);
1845            from_raw_parts_mut(self.v.as_mut_ptr().add(start), len)
1846        }
1847    }
1848}
1849
1850#[stable(feature = "rust1", since = "1.0.0")]
1851#[cfg(not(feature = "ferrocene_subset"))]
1852impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
1853    #[inline]
1854    fn next_back(&mut self) -> Option<&'a mut [T]> {
1855        if self.v.is_empty() {
1856            None
1857        } else {
1858            let remainder = self.v.len() % self.chunk_size;
1859            let sz = if remainder != 0 { remainder } else { self.chunk_size };
1860            let len = self.v.len();
1861            // SAFETY: Similar to `Chunks::next_back`
1862            let (head, tail) = unsafe { self.v.split_at_mut_unchecked(len - sz) };
1863            self.v = head;
1864            // SAFETY: Nothing else points to or will point to the contents of this slice.
1865            Some(unsafe { &mut *tail })
1866        }
1867    }
1868
1869    #[inline]
1870    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1871        let len = self.len();
1872        if n < len {
1873            let start = (len - 1 - n) * self.chunk_size;
1874            let end = match start.checked_add(self.chunk_size) {
1875                Some(res) => cmp::min(self.v.len(), res),
1876                None => self.v.len(),
1877            };
1878            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1879            let (temp, _tail) = unsafe { self.v.split_at_mut(end) };
1880            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
1881            let (head, nth_back) = unsafe { temp.split_at_mut(start) };
1882            self.v = head;
1883            // SAFETY: Nothing else points to or will point to the contents of this slice.
1884            Some(unsafe { &mut *nth_back })
1885        } else {
1886            self.v = &mut [];
1887            None
1888        }
1889    }
1890}
1891
1892#[stable(feature = "rust1", since = "1.0.0")]
1893impl<T> ExactSizeIterator for ChunksMut<'_, T> {}
1894
1895#[unstable(feature = "trusted_len", issue = "37572")]
1896#[cfg(not(feature = "ferrocene_subset"))]
1897unsafe impl<T> TrustedLen for ChunksMut<'_, T> {}
1898
1899#[stable(feature = "fused", since = "1.26.0")]
1900#[cfg(not(feature = "ferrocene_subset"))]
1901impl<T> FusedIterator for ChunksMut<'_, T> {}
1902
1903#[doc(hidden)]
1904#[unstable(feature = "trusted_random_access", issue = "none")]
1905#[cfg(not(feature = "ferrocene_subset"))]
1906unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {}
1907
1908#[doc(hidden)]
1909#[unstable(feature = "trusted_random_access", issue = "none")]
1910#[cfg(not(feature = "ferrocene_subset"))]
1911unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksMut<'a, T> {
1912    const MAY_HAVE_SIDE_EFFECT: bool = false;
1913}
1914
1915#[stable(feature = "rust1", since = "1.0.0")]
1916#[cfg(not(feature = "ferrocene_subset"))]
1917unsafe impl<T> Send for ChunksMut<'_, T> where T: Send {}
1918
1919#[stable(feature = "rust1", since = "1.0.0")]
1920#[cfg(not(feature = "ferrocene_subset"))]
1921unsafe impl<T> Sync for ChunksMut<'_, T> where T: Sync {}
1922
1923/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
1924/// time), starting at the beginning of the slice.
1925///
1926/// When the slice len is not evenly divided by the chunk size, the last
1927/// up to `chunk_size-1` elements will be omitted but can be retrieved from
1928/// the [`remainder`] function from the iterator.
1929///
1930/// This struct is created by the [`chunks_exact`] method on [slices].
1931///
1932/// # Example
1933///
1934/// ```
1935/// let slice = ['l', 'o', 'r', 'e', 'm'];
1936/// let mut iter = slice.chunks_exact(2);
1937/// assert_eq!(iter.next(), Some(&['l', 'o'][..]));
1938/// assert_eq!(iter.next(), Some(&['r', 'e'][..]));
1939/// assert_eq!(iter.next(), None);
1940/// ```
1941///
1942/// [`chunks_exact`]: slice::chunks_exact
1943/// [`remainder`]: ChunksExact::remainder
1944/// [slices]: slice
1945#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
1946#[stable(feature = "chunks_exact", since = "1.31.0")]
1947#[must_use = "iterators are lazy and do nothing unless consumed"]
1948pub struct ChunksExact<'a, T: 'a> {
1949    v: &'a [T],
1950    rem: &'a [T],
1951    chunk_size: usize,
1952}
1953
1954impl<'a, T> ChunksExact<'a, T> {
1955    #[inline]
1956    pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
1957        let rem = slice.len() % chunk_size;
1958        let fst_len = slice.len() - rem;
1959        // SAFETY: 0 <= fst_len <= slice.len() by construction above
1960        let (fst, snd) = unsafe { slice.split_at_unchecked(fst_len) };
1961        Self { v: fst, rem: snd, chunk_size }
1962    }
1963
1964    /// Returns the remainder of the original slice that is not going to be
1965    /// returned by the iterator. The returned slice has at most `chunk_size-1`
1966    /// elements.
1967    ///
1968    /// # Example
1969    ///
1970    /// ```
1971    /// let slice = ['l', 'o', 'r', 'e', 'm'];
1972    /// let mut iter = slice.chunks_exact(2);
1973    /// assert_eq!(iter.remainder(), &['m'][..]);
1974    /// assert_eq!(iter.next(), Some(&['l', 'o'][..]));
1975    /// assert_eq!(iter.remainder(), &['m'][..]);
1976    /// assert_eq!(iter.next(), Some(&['r', 'e'][..]));
1977    /// assert_eq!(iter.remainder(), &['m'][..]);
1978    /// assert_eq!(iter.next(), None);
1979    /// assert_eq!(iter.remainder(), &['m'][..]);
1980    /// ```
1981    #[must_use]
1982    #[stable(feature = "chunks_exact", since = "1.31.0")]
1983    pub fn remainder(&self) -> &'a [T] {
1984        self.rem
1985    }
1986}
1987
1988// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
1989#[stable(feature = "chunks_exact", since = "1.31.0")]
1990#[cfg(not(feature = "ferrocene_subset"))]
1991impl<T> Clone for ChunksExact<'_, T> {
1992    fn clone(&self) -> Self {
1993        ChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
1994    }
1995}
1996
1997#[stable(feature = "chunks_exact", since = "1.31.0")]
1998impl<'a, T> Iterator for ChunksExact<'a, T> {
1999    type Item = &'a [T];
2000
2001    #[inline]
2002    fn next(&mut self) -> Option<&'a [T]> {
2003        self.v.split_at_checked(self.chunk_size).and_then(|(chunk, rest)| {
2004            self.v = rest;
2005            Some(chunk)
2006        })
2007    }
2008
2009    #[inline]
2010    fn size_hint(&self) -> (usize, Option<usize>) {
2011        let n = self.v.len() / self.chunk_size;
2012        (n, Some(n))
2013    }
2014
2015    #[inline]
2016    fn count(self) -> usize {
2017        self.len()
2018    }
2019
2020    #[inline]
2021    fn nth(&mut self, n: usize) -> Option<Self::Item> {
2022        if let Some(start) = n.checked_mul(self.chunk_size)
2023            && start < self.v.len()
2024        {
2025            self.v = &self.v[start..];
2026            self.next()
2027        } else {
2028            self.v = &self.v[..0]; // cheaper than &[]
2029            None
2030        }
2031    }
2032
2033    #[inline]
2034    fn last(mut self) -> Option<Self::Item> {
2035        self.next_back()
2036    }
2037
2038    #[cfg(not(feature = "ferrocene_subset"))]
2039    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2040        let start = idx * self.chunk_size;
2041        // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
2042        unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
2043    }
2044}
2045
2046#[stable(feature = "chunks_exact", since = "1.31.0")]
2047impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
2048    #[inline]
2049    fn next_back(&mut self) -> Option<&'a [T]> {
2050        if self.v.len() < self.chunk_size {
2051            None
2052        } else {
2053            let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
2054            self.v = fst;
2055            Some(snd)
2056        }
2057    }
2058
2059    #[inline]
2060    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2061        let len = self.len();
2062        if n < len {
2063            let start = (len - 1 - n) * self.chunk_size;
2064            let end = start + self.chunk_size;
2065            let nth_back = &self.v[start..end];
2066            self.v = &self.v[..start];
2067            Some(nth_back)
2068        } else {
2069            self.v = &self.v[..0]; // cheaper than &[]
2070            None
2071        }
2072    }
2073}
2074
2075#[stable(feature = "chunks_exact", since = "1.31.0")]
2076impl<T> ExactSizeIterator for ChunksExact<'_, T> {
2077    fn is_empty(&self) -> bool {
2078        self.v.is_empty()
2079    }
2080}
2081
2082#[unstable(feature = "trusted_len", issue = "37572")]
2083#[cfg(not(feature = "ferrocene_subset"))]
2084unsafe impl<T> TrustedLen for ChunksExact<'_, T> {}
2085
2086#[stable(feature = "chunks_exact", since = "1.31.0")]
2087#[cfg(not(feature = "ferrocene_subset"))]
2088impl<T> FusedIterator for ChunksExact<'_, T> {}
2089
2090#[doc(hidden)]
2091#[unstable(feature = "trusted_random_access", issue = "none")]
2092#[cfg(not(feature = "ferrocene_subset"))]
2093unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {}
2094
2095#[doc(hidden)]
2096#[unstable(feature = "trusted_random_access", issue = "none")]
2097#[cfg(not(feature = "ferrocene_subset"))]
2098unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExact<'a, T> {
2099    const MAY_HAVE_SIDE_EFFECT: bool = false;
2100}
2101
2102/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
2103/// elements at a time), starting at the beginning of the slice.
2104///
2105/// When the slice len is not evenly divided by the chunk size, the last up to
2106/// `chunk_size-1` elements will be omitted but can be retrieved from the
2107/// [`into_remainder`] function from the iterator.
2108///
2109/// This struct is created by the [`chunks_exact_mut`] method on [slices].
2110///
2111/// # Example
2112///
2113/// ```
2114/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
2115/// let iter = slice.chunks_exact_mut(2);
2116/// ```
2117///
2118/// [`chunks_exact_mut`]: slice::chunks_exact_mut
2119/// [`into_remainder`]: ChunksExactMut::into_remainder
2120/// [slices]: slice
2121#[cfg_attr(not(feature = "ferrocene_subset"), derive(Debug))]
2122#[stable(feature = "chunks_exact", since = "1.31.0")]
2123#[must_use = "iterators are lazy and do nothing unless consumed"]
2124pub struct ChunksExactMut<'a, T: 'a> {
2125    /// # Safety
2126    /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
2127    /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
2128    /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
2129    /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
2130    /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
2131    v: *mut [T],
2132    rem: &'a mut [T], // The iterator never yields from here, so this can be unique
2133    chunk_size: usize,
2134    _marker: PhantomData<&'a mut T>,
2135}
2136
2137impl<'a, T> ChunksExactMut<'a, T> {
2138    #[inline]
2139    pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
2140        let rem = slice.len() % chunk_size;
2141        let fst_len = slice.len() - rem;
2142        // SAFETY: 0 <= fst_len <= slice.len() by construction above
2143        let (fst, snd) = unsafe { slice.split_at_mut_unchecked(fst_len) };
2144        Self { v: fst, rem: snd, chunk_size, _marker: PhantomData }
2145    }
2146
2147    /// Returns the remainder of the original slice that is not going to be
2148    /// returned by the iterator. The returned slice has at most `chunk_size-1`
2149    /// elements.
2150    #[must_use = "`self` will be dropped if the result is not used"]
2151    #[stable(feature = "chunks_exact", since = "1.31.0")]
2152    pub fn into_remainder(self) -> &'a mut [T] {
2153        self.rem
2154    }
2155}
2156
2157#[stable(feature = "chunks_exact", since = "1.31.0")]
2158impl<'a, T> Iterator for ChunksExactMut<'a, T> {
2159    type Item = &'a mut [T];
2160
2161    #[inline]
2162    fn next(&mut self) -> Option<&'a mut [T]> {
2163        // SAFETY: we have `&mut self`, so are allowed to temporarily materialize a mut slice
2164        unsafe { &mut *self.v }.split_at_mut_checked(self.chunk_size).and_then(|(chunk, rest)| {
2165            self.v = rest;
2166            Some(chunk)
2167        })
2168    }
2169
2170    #[inline]
2171    fn size_hint(&self) -> (usize, Option<usize>) {
2172        let n = self.v.len() / self.chunk_size;
2173        (n, Some(n))
2174    }
2175
2176    #[inline]
2177    fn count(self) -> usize {
2178        self.len()
2179    }
2180
2181    #[inline]
2182    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2183        if let Some(start) = n.checked_mul(self.chunk_size)
2184            && start < self.v.len()
2185        {
2186            // SAFETY: `start < self.v.len()`
2187            self.v = unsafe { self.v.split_at_mut(start).1 };
2188            self.next()
2189        } else {
2190            self.v = &mut [];
2191            None
2192        }
2193    }
2194
2195    #[inline]
2196    fn last(mut self) -> Option<Self::Item> {
2197        self.next_back()
2198    }
2199
2200    #[cfg(not(feature = "ferrocene_subset"))]
2201    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2202        let start = idx * self.chunk_size;
2203        // SAFETY: see comments for `Chunks::__iterator_get_unchecked` and `self.v`.
2204        unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
2205    }
2206}
2207
2208#[stable(feature = "chunks_exact", since = "1.31.0")]
2209impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
2210    #[inline]
2211    fn next_back(&mut self) -> Option<&'a mut [T]> {
2212        if self.v.len() < self.chunk_size {
2213            None
2214        } else {
2215            // SAFETY: This subtraction is inbounds because of the check above
2216            let (head, tail) = unsafe { self.v.split_at_mut(self.v.len() - self.chunk_size) };
2217            self.v = head;
2218            // SAFETY: Nothing else points to or will point to the contents of this slice.
2219            Some(unsafe { &mut *tail })
2220        }
2221    }
2222
2223    #[inline]
2224    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2225        let len = self.len();
2226        if n < len {
2227            let start = (len - 1 - n) * self.chunk_size;
2228            let end = start + self.chunk_size;
2229            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2230            let (temp, _tail) = unsafe { mem::replace(&mut self.v, &mut []).split_at_mut(end) };
2231            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2232            let (head, nth_back) = unsafe { temp.split_at_mut(start) };
2233            self.v = head;
2234            // SAFETY: Nothing else points to or will point to the contents of this slice.
2235            Some(unsafe { &mut *nth_back })
2236        } else {
2237            self.v = &mut [];
2238            None
2239        }
2240    }
2241}
2242
2243#[stable(feature = "chunks_exact", since = "1.31.0")]
2244impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
2245    fn is_empty(&self) -> bool {
2246        self.v.is_empty()
2247    }
2248}
2249
2250#[unstable(feature = "trusted_len", issue = "37572")]
2251#[cfg(not(feature = "ferrocene_subset"))]
2252unsafe impl<T> TrustedLen for ChunksExactMut<'_, T> {}
2253
2254#[stable(feature = "chunks_exact", since = "1.31.0")]
2255#[cfg(not(feature = "ferrocene_subset"))]
2256impl<T> FusedIterator for ChunksExactMut<'_, T> {}
2257
2258#[doc(hidden)]
2259#[unstable(feature = "trusted_random_access", issue = "none")]
2260#[cfg(not(feature = "ferrocene_subset"))]
2261unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {}
2262
2263#[doc(hidden)]
2264#[unstable(feature = "trusted_random_access", issue = "none")]
2265#[cfg(not(feature = "ferrocene_subset"))]
2266unsafe impl<'a, T> TrustedRandomAccessNoCoerce for ChunksExactMut<'a, T> {
2267    const MAY_HAVE_SIDE_EFFECT: bool = false;
2268}
2269
2270#[stable(feature = "chunks_exact", since = "1.31.0")]
2271#[cfg(not(feature = "ferrocene_subset"))]
2272unsafe impl<T> Send for ChunksExactMut<'_, T> where T: Send {}
2273
2274#[stable(feature = "chunks_exact", since = "1.31.0")]
2275#[cfg(not(feature = "ferrocene_subset"))]
2276unsafe impl<T> Sync for ChunksExactMut<'_, T> where T: Sync {}
2277
2278/// A windowed iterator over a slice in overlapping chunks (`N` elements at a
2279/// time), starting at the beginning of the slice
2280///
2281/// This struct is created by the [`array_windows`] method on [slices].
2282///
2283/// # Example
2284///
2285/// ```
2286/// let slice = [0, 1, 2, 3];
2287/// let mut iter = slice.array_windows::<2>();
2288/// assert_eq!(iter.next(), Some(&[0, 1]));
2289/// assert_eq!(iter.next(), Some(&[1, 2]));
2290/// assert_eq!(iter.next(), Some(&[2, 3]));
2291/// assert_eq!(iter.next(), None);
2292/// ```
2293///
2294/// [`array_windows`]: slice::array_windows
2295/// [slices]: slice
2296#[derive(Debug, Clone, Copy)]
2297#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")]
2298#[must_use = "iterators are lazy and do nothing unless consumed"]
2299#[cfg(not(feature = "ferrocene_subset"))]
2300pub struct ArrayWindows<'a, T: 'a, const N: usize> {
2301    v: &'a [T],
2302}
2303
2304#[cfg(not(feature = "ferrocene_subset"))]
2305impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
2306    #[inline]
2307    pub(super) const fn new(slice: &'a [T]) -> Self {
2308        Self { v: slice }
2309    }
2310}
2311
2312#[cfg(not(feature = "ferrocene_subset"))]
2313#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")]
2314impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
2315    type Item = &'a [T; N];
2316
2317    #[inline]
2318    fn next(&mut self) -> Option<Self::Item> {
2319        let ret = self.v.first_chunk();
2320        if ret.is_some() {
2321            self.v = &self.v[1..];
2322        }
2323        ret
2324    }
2325
2326    #[inline]
2327    fn size_hint(&self) -> (usize, Option<usize>) {
2328        let size = self.v.len().saturating_sub(N - 1);
2329        (size, Some(size))
2330    }
2331
2332    #[inline]
2333    fn count(self) -> usize {
2334        self.len()
2335    }
2336
2337    #[inline]
2338    fn nth(&mut self, n: usize) -> Option<Self::Item> {
2339        let idx = n.min(self.v.len());
2340        self.v = &self.v[idx..];
2341        self.next()
2342    }
2343
2344    #[inline]
2345    fn last(self) -> Option<Self::Item> {
2346        self.v.last_chunk()
2347    }
2348}
2349
2350#[cfg(not(feature = "ferrocene_subset"))]
2351#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")]
2352impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
2353    #[inline]
2354    fn next_back(&mut self) -> Option<&'a [T; N]> {
2355        let ret = self.v.last_chunk();
2356        if ret.is_some() {
2357            self.v = &self.v[..self.v.len() - 1];
2358        }
2359        ret
2360    }
2361
2362    #[inline]
2363    fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
2364        let idx = self.v.len().saturating_sub(n);
2365        self.v = &self.v[..idx];
2366        self.next_back()
2367    }
2368}
2369
2370#[cfg(not(feature = "ferrocene_subset"))]
2371#[stable(feature = "array_windows", since = "CURRENT_RUSTC_VERSION")]
2372impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
2373    fn is_empty(&self) -> bool {
2374        self.v.len() < N
2375    }
2376}
2377
2378/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
2379/// time), starting at the end of the slice.
2380///
2381/// When the slice len is not evenly divided by the chunk size, the last slice
2382/// of the iteration will be the remainder.
2383///
2384/// This struct is created by the [`rchunks`] method on [slices].
2385///
2386/// # Example
2387///
2388/// ```
2389/// let slice = ['l', 'o', 'r', 'e', 'm'];
2390/// let mut iter = slice.rchunks(2);
2391/// assert_eq!(iter.next(), Some(&['e', 'm'][..]));
2392/// assert_eq!(iter.next(), Some(&['o', 'r'][..]));
2393/// assert_eq!(iter.next(), Some(&['l'][..]));
2394/// assert_eq!(iter.next(), None);
2395/// ```
2396///
2397/// [`rchunks`]: slice::rchunks
2398/// [slices]: slice
2399#[derive(Debug)]
2400#[stable(feature = "rchunks", since = "1.31.0")]
2401#[must_use = "iterators are lazy and do nothing unless consumed"]
2402#[cfg(not(feature = "ferrocene_subset"))]
2403pub struct RChunks<'a, T: 'a> {
2404    v: &'a [T],
2405    chunk_size: usize,
2406}
2407
2408#[cfg(not(feature = "ferrocene_subset"))]
2409impl<'a, T: 'a> RChunks<'a, T> {
2410    #[inline]
2411    pub(super) const fn new(slice: &'a [T], size: usize) -> Self {
2412        Self { v: slice, chunk_size: size }
2413    }
2414}
2415
2416// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2417#[stable(feature = "rchunks", since = "1.31.0")]
2418#[cfg(not(feature = "ferrocene_subset"))]
2419impl<T> Clone for RChunks<'_, T> {
2420    fn clone(&self) -> Self {
2421        RChunks { v: self.v, chunk_size: self.chunk_size }
2422    }
2423}
2424
2425#[stable(feature = "rchunks", since = "1.31.0")]
2426#[cfg(not(feature = "ferrocene_subset"))]
2427impl<'a, T> Iterator for RChunks<'a, T> {
2428    type Item = &'a [T];
2429
2430    #[inline]
2431    fn next(&mut self) -> Option<&'a [T]> {
2432        if self.v.is_empty() {
2433            None
2434        } else {
2435            let idx = self.v.len().saturating_sub(self.chunk_size);
2436            // SAFETY: self.chunk_size() > 0, so 0 <= idx < self.v.len().
2437            // Thus `idx` is in-bounds for `self.v` and can be used as a valid argument for `split_at_mut_unchecked`.
2438            let (rest, chunk) = unsafe { self.v.split_at_unchecked(idx) };
2439            self.v = rest;
2440            Some(chunk)
2441        }
2442    }
2443
2444    #[inline]
2445    fn size_hint(&self) -> (usize, Option<usize>) {
2446        if self.v.is_empty() {
2447            (0, Some(0))
2448        } else {
2449            let n = self.v.len().div_ceil(self.chunk_size);
2450            (n, Some(n))
2451        }
2452    }
2453
2454    #[inline]
2455    fn count(self) -> usize {
2456        self.len()
2457    }
2458
2459    #[inline]
2460    fn nth(&mut self, n: usize) -> Option<Self::Item> {
2461        if let Some(end) = n.checked_mul(self.chunk_size)
2462            && end < self.v.len()
2463        {
2464            let end = self.v.len() - end;
2465            let rest = &self.v[..end];
2466            let (rest, chunk) = rest.split_at(end.saturating_sub(self.chunk_size));
2467            self.v = rest;
2468            Some(chunk)
2469        } else {
2470            self.v = &self.v[..0]; // cheaper than &[]
2471            None
2472        }
2473    }
2474
2475    #[inline]
2476    fn last(self) -> Option<Self::Item> {
2477        if self.v.is_empty() {
2478            None
2479        } else {
2480            let rem = self.v.len() % self.chunk_size;
2481            let end = if rem == 0 { self.chunk_size } else { rem };
2482            Some(&self.v[0..end])
2483        }
2484    }
2485
2486    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2487        let end = self.v.len() - idx * self.chunk_size;
2488        let start = end.saturating_sub(self.chunk_size);
2489        // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
2490        unsafe { from_raw_parts(self.v.as_ptr().add(start), end - start) }
2491    }
2492}
2493
2494#[stable(feature = "rchunks", since = "1.31.0")]
2495#[cfg(not(feature = "ferrocene_subset"))]
2496impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
2497    #[inline]
2498    fn next_back(&mut self) -> Option<&'a [T]> {
2499        if self.v.is_empty() {
2500            None
2501        } else {
2502            let remainder = self.v.len() % self.chunk_size;
2503            let chunksz = if remainder != 0 { remainder } else { self.chunk_size };
2504            // SAFETY: similar to Chunks::next_back
2505            let (fst, snd) = unsafe { self.v.split_at_unchecked(chunksz) };
2506            self.v = snd;
2507            Some(fst)
2508        }
2509    }
2510
2511    #[inline]
2512    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2513        let len = self.len();
2514        if n < len {
2515            let offset_from_end = (len - 1 - n) * self.chunk_size;
2516            let end = self.v.len() - offset_from_end;
2517            let start = end.saturating_sub(self.chunk_size);
2518            let nth_back = &self.v[start..end];
2519            self.v = &self.v[end..];
2520            Some(nth_back)
2521        } else {
2522            self.v = &self.v[..0]; // cheaper than &[]
2523            None
2524        }
2525    }
2526}
2527
2528#[stable(feature = "rchunks", since = "1.31.0")]
2529#[cfg(not(feature = "ferrocene_subset"))]
2530impl<T> ExactSizeIterator for RChunks<'_, T> {}
2531
2532#[unstable(feature = "trusted_len", issue = "37572")]
2533#[cfg(not(feature = "ferrocene_subset"))]
2534unsafe impl<T> TrustedLen for RChunks<'_, T> {}
2535
2536#[stable(feature = "rchunks", since = "1.31.0")]
2537#[cfg(not(feature = "ferrocene_subset"))]
2538impl<T> FusedIterator for RChunks<'_, T> {}
2539
2540#[doc(hidden)]
2541#[unstable(feature = "trusted_random_access", issue = "none")]
2542#[cfg(not(feature = "ferrocene_subset"))]
2543unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {}
2544
2545#[doc(hidden)]
2546#[unstable(feature = "trusted_random_access", issue = "none")]
2547#[cfg(not(feature = "ferrocene_subset"))]
2548unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunks<'a, T> {
2549    const MAY_HAVE_SIDE_EFFECT: bool = false;
2550}
2551
2552/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
2553/// elements at a time), starting at the end of the slice.
2554///
2555/// When the slice len is not evenly divided by the chunk size, the last slice
2556/// of the iteration will be the remainder.
2557///
2558/// This struct is created by the [`rchunks_mut`] method on [slices].
2559///
2560/// # Example
2561///
2562/// ```
2563/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
2564/// let iter = slice.rchunks_mut(2);
2565/// ```
2566///
2567/// [`rchunks_mut`]: slice::rchunks_mut
2568/// [slices]: slice
2569#[derive(Debug)]
2570#[stable(feature = "rchunks", since = "1.31.0")]
2571#[must_use = "iterators are lazy and do nothing unless consumed"]
2572#[cfg(not(feature = "ferrocene_subset"))]
2573pub struct RChunksMut<'a, T: 'a> {
2574    /// # Safety
2575    /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
2576    /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
2577    /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
2578    /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
2579    /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
2580    v: *mut [T],
2581    chunk_size: usize,
2582    _marker: PhantomData<&'a mut T>,
2583}
2584
2585#[cfg(not(feature = "ferrocene_subset"))]
2586impl<'a, T: 'a> RChunksMut<'a, T> {
2587    #[inline]
2588    pub(super) const fn new(slice: &'a mut [T], size: usize) -> Self {
2589        Self { v: slice, chunk_size: size, _marker: PhantomData }
2590    }
2591}
2592
2593#[stable(feature = "rchunks", since = "1.31.0")]
2594#[cfg(not(feature = "ferrocene_subset"))]
2595impl<'a, T> Iterator for RChunksMut<'a, T> {
2596    type Item = &'a mut [T];
2597
2598    #[inline]
2599    fn next(&mut self) -> Option<&'a mut [T]> {
2600        if self.v.is_empty() {
2601            None
2602        } else {
2603            let idx = self.v.len().saturating_sub(self.chunk_size);
2604            // SAFETY: self.chunk_size() > 0, so 0 <= idx < self.v.len().
2605            // Thus `idx` is in-bounds for `self.v` and can be used as a valid argument for `split_at_mut_unchecked`.
2606            let (rest, chunk) = unsafe { self.v.split_at_mut_unchecked(idx) };
2607            self.v = rest;
2608            // SAFETY: Nothing else points to or will point to the contents of this slice.
2609            Some(unsafe { &mut *chunk })
2610        }
2611    }
2612
2613    #[inline]
2614    fn size_hint(&self) -> (usize, Option<usize>) {
2615        if self.v.is_empty() {
2616            (0, Some(0))
2617        } else {
2618            let n = self.v.len().div_ceil(self.chunk_size);
2619            (n, Some(n))
2620        }
2621    }
2622
2623    #[inline]
2624    fn count(self) -> usize {
2625        self.len()
2626    }
2627
2628    #[inline]
2629    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
2630        if let Some(end) = n.checked_mul(self.chunk_size)
2631            && end < self.v.len()
2632        {
2633            let end = self.v.len() - end;
2634            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2635            let (rest, _) = unsafe { self.v.split_at_mut(end) };
2636            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2637            let (rest, chunk) = unsafe { rest.split_at_mut(end.saturating_sub(self.chunk_size)) };
2638            self.v = rest;
2639            // SAFETY: Nothing else points to or will point to the contents of this slice.
2640            Some(unsafe { &mut *chunk })
2641        } else {
2642            self.v = &mut [];
2643            None
2644        }
2645    }
2646
2647    #[inline]
2648    fn last(self) -> Option<Self::Item> {
2649        if self.v.is_empty() {
2650            None
2651        } else {
2652            let rem = self.v.len() % self.chunk_size;
2653            let end = if rem == 0 { self.chunk_size } else { rem };
2654            // SAFETY: Nothing else points to or will point to the contents of this slice.
2655            Some(unsafe { &mut *self.v.get_unchecked_mut(0..end) })
2656        }
2657    }
2658
2659    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2660        let end = self.v.len() - idx * self.chunk_size;
2661        let start = end.saturating_sub(self.chunk_size);
2662        // SAFETY: see comments for `RChunks::__iterator_get_unchecked` and
2663        // `ChunksMut::__iterator_get_unchecked`, `self.v`.
2664        unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) }
2665    }
2666}
2667
2668#[stable(feature = "rchunks", since = "1.31.0")]
2669#[cfg(not(feature = "ferrocene_subset"))]
2670impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
2671    #[inline]
2672    fn next_back(&mut self) -> Option<&'a mut [T]> {
2673        if self.v.is_empty() {
2674            None
2675        } else {
2676            let remainder = self.v.len() % self.chunk_size;
2677            let sz = if remainder != 0 { remainder } else { self.chunk_size };
2678            // SAFETY: Similar to `Chunks::next_back`
2679            let (head, tail) = unsafe { self.v.split_at_mut_unchecked(sz) };
2680            self.v = tail;
2681            // SAFETY: Nothing else points to or will point to the contents of this slice.
2682            Some(unsafe { &mut *head })
2683        }
2684    }
2685
2686    #[inline]
2687    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2688        let len = self.len();
2689        if n < len {
2690            // can't underflow because `n < len`
2691            let offset_from_end = (len - 1 - n) * self.chunk_size;
2692            let end = self.v.len() - offset_from_end;
2693            let start = end.saturating_sub(self.chunk_size);
2694            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2695            let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
2696            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2697            let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
2698            self.v = tail;
2699            // SAFETY: Nothing else points to or will point to the contents of this slice.
2700            Some(unsafe { &mut *nth_back })
2701        } else {
2702            self.v = &mut [];
2703            None
2704        }
2705    }
2706}
2707
2708#[stable(feature = "rchunks", since = "1.31.0")]
2709#[cfg(not(feature = "ferrocene_subset"))]
2710impl<T> ExactSizeIterator for RChunksMut<'_, T> {}
2711
2712#[unstable(feature = "trusted_len", issue = "37572")]
2713#[cfg(not(feature = "ferrocene_subset"))]
2714unsafe impl<T> TrustedLen for RChunksMut<'_, T> {}
2715
2716#[stable(feature = "rchunks", since = "1.31.0")]
2717#[cfg(not(feature = "ferrocene_subset"))]
2718impl<T> FusedIterator for RChunksMut<'_, T> {}
2719
2720#[doc(hidden)]
2721#[unstable(feature = "trusted_random_access", issue = "none")]
2722#[cfg(not(feature = "ferrocene_subset"))]
2723unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {}
2724
2725#[doc(hidden)]
2726#[unstable(feature = "trusted_random_access", issue = "none")]
2727#[cfg(not(feature = "ferrocene_subset"))]
2728unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksMut<'a, T> {
2729    const MAY_HAVE_SIDE_EFFECT: bool = false;
2730}
2731
2732#[stable(feature = "rchunks", since = "1.31.0")]
2733#[cfg(not(feature = "ferrocene_subset"))]
2734unsafe impl<T> Send for RChunksMut<'_, T> where T: Send {}
2735
2736#[stable(feature = "rchunks", since = "1.31.0")]
2737#[cfg(not(feature = "ferrocene_subset"))]
2738unsafe impl<T> Sync for RChunksMut<'_, T> where T: Sync {}
2739
2740/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a
2741/// time), starting at the end of the slice.
2742///
2743/// When the slice len is not evenly divided by the chunk size, the last
2744/// up to `chunk_size-1` elements will be omitted but can be retrieved from
2745/// the [`remainder`] function from the iterator.
2746///
2747/// This struct is created by the [`rchunks_exact`] method on [slices].
2748///
2749/// # Example
2750///
2751/// ```
2752/// let slice = ['l', 'o', 'r', 'e', 'm'];
2753/// let mut iter = slice.rchunks_exact(2);
2754/// assert_eq!(iter.next(), Some(&['e', 'm'][..]));
2755/// assert_eq!(iter.next(), Some(&['o', 'r'][..]));
2756/// assert_eq!(iter.next(), None);
2757/// ```
2758///
2759/// [`rchunks_exact`]: slice::rchunks_exact
2760/// [`remainder`]: RChunksExact::remainder
2761/// [slices]: slice
2762#[derive(Debug)]
2763#[stable(feature = "rchunks", since = "1.31.0")]
2764#[must_use = "iterators are lazy and do nothing unless consumed"]
2765#[cfg(not(feature = "ferrocene_subset"))]
2766pub struct RChunksExact<'a, T: 'a> {
2767    v: &'a [T],
2768    rem: &'a [T],
2769    chunk_size: usize,
2770}
2771
2772#[cfg(not(feature = "ferrocene_subset"))]
2773impl<'a, T> RChunksExact<'a, T> {
2774    #[inline]
2775    pub(super) const fn new(slice: &'a [T], chunk_size: usize) -> Self {
2776        let rem = slice.len() % chunk_size;
2777        // SAFETY: 0 <= rem <= slice.len() by construction above
2778        let (fst, snd) = unsafe { slice.split_at_unchecked(rem) };
2779        Self { v: snd, rem: fst, chunk_size }
2780    }
2781
2782    /// Returns the remainder of the original slice that is not going to be
2783    /// returned by the iterator. The returned slice has at most `chunk_size-1`
2784    /// elements.
2785    ///
2786    /// # Example
2787    ///
2788    /// ```
2789    /// let slice = ['l', 'o', 'r', 'e', 'm'];
2790    /// let mut iter = slice.rchunks_exact(2);
2791    /// assert_eq!(iter.remainder(), &['l'][..]);
2792    /// assert_eq!(iter.next(), Some(&['e', 'm'][..]));
2793    /// assert_eq!(iter.remainder(), &['l'][..]);
2794    /// assert_eq!(iter.next(), Some(&['o', 'r'][..]));
2795    /// assert_eq!(iter.remainder(), &['l'][..]);
2796    /// assert_eq!(iter.next(), None);
2797    /// assert_eq!(iter.remainder(), &['l'][..]);
2798    /// ```
2799    #[must_use]
2800    #[stable(feature = "rchunks", since = "1.31.0")]
2801    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
2802    pub const fn remainder(&self) -> &'a [T] {
2803        self.rem
2804    }
2805}
2806
2807// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2808#[stable(feature = "rchunks", since = "1.31.0")]
2809#[cfg(not(feature = "ferrocene_subset"))]
2810impl<'a, T> Clone for RChunksExact<'a, T> {
2811    fn clone(&self) -> RChunksExact<'a, T> {
2812        RChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size }
2813    }
2814}
2815
2816#[stable(feature = "rchunks", since = "1.31.0")]
2817#[cfg(not(feature = "ferrocene_subset"))]
2818impl<'a, T> Iterator for RChunksExact<'a, T> {
2819    type Item = &'a [T];
2820
2821    #[inline]
2822    fn next(&mut self) -> Option<&'a [T]> {
2823        if self.v.len() < self.chunk_size {
2824            None
2825        } else {
2826            let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size);
2827            self.v = fst;
2828            Some(snd)
2829        }
2830    }
2831
2832    #[inline]
2833    fn size_hint(&self) -> (usize, Option<usize>) {
2834        let n = self.v.len() / self.chunk_size;
2835        (n, Some(n))
2836    }
2837
2838    #[inline]
2839    fn count(self) -> usize {
2840        self.len()
2841    }
2842
2843    #[inline]
2844    fn nth(&mut self, n: usize) -> Option<Self::Item> {
2845        if let Some(end) = n.checked_mul(self.chunk_size)
2846            && end < self.v.len()
2847        {
2848            self.v = &self.v[..self.v.len() - end];
2849            self.next()
2850        } else {
2851            self.v = &self.v[..0]; // cheaper than &[]
2852            None
2853        }
2854    }
2855
2856    #[inline]
2857    fn last(mut self) -> Option<Self::Item> {
2858        self.next_back()
2859    }
2860
2861    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
2862        let end = self.v.len() - idx * self.chunk_size;
2863        let start = end - self.chunk_size;
2864        // SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
2865        unsafe { from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) }
2866    }
2867}
2868
2869#[stable(feature = "rchunks", since = "1.31.0")]
2870#[cfg(not(feature = "ferrocene_subset"))]
2871impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
2872    #[inline]
2873    fn next_back(&mut self) -> Option<&'a [T]> {
2874        if self.v.len() < self.chunk_size {
2875            None
2876        } else {
2877            let (fst, snd) = self.v.split_at(self.chunk_size);
2878            self.v = snd;
2879            Some(fst)
2880        }
2881    }
2882
2883    #[inline]
2884    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
2885        let len = self.len();
2886        if n < len {
2887            // now that we know that `n` corresponds to a chunk,
2888            // none of these operations can underflow/overflow
2889            let offset = (len - n) * self.chunk_size;
2890            let start = self.v.len() - offset;
2891            let end = start + self.chunk_size;
2892            let nth_back = &self.v[start..end];
2893            self.v = &self.v[end..];
2894            Some(nth_back)
2895        } else {
2896            self.v = &self.v[..0]; // cheaper than &[]
2897            None
2898        }
2899    }
2900}
2901
2902#[stable(feature = "rchunks", since = "1.31.0")]
2903#[cfg(not(feature = "ferrocene_subset"))]
2904impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
2905    fn is_empty(&self) -> bool {
2906        self.v.is_empty()
2907    }
2908}
2909
2910#[unstable(feature = "trusted_len", issue = "37572")]
2911#[cfg(not(feature = "ferrocene_subset"))]
2912unsafe impl<T> TrustedLen for RChunksExact<'_, T> {}
2913
2914#[stable(feature = "rchunks", since = "1.31.0")]
2915#[cfg(not(feature = "ferrocene_subset"))]
2916impl<T> FusedIterator for RChunksExact<'_, T> {}
2917
2918#[doc(hidden)]
2919#[unstable(feature = "trusted_random_access", issue = "none")]
2920#[cfg(not(feature = "ferrocene_subset"))]
2921unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {}
2922
2923#[doc(hidden)]
2924#[unstable(feature = "trusted_random_access", issue = "none")]
2925#[cfg(not(feature = "ferrocene_subset"))]
2926unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExact<'a, T> {
2927    const MAY_HAVE_SIDE_EFFECT: bool = false;
2928}
2929
2930/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size`
2931/// elements at a time), starting at the end of the slice.
2932///
2933/// When the slice len is not evenly divided by the chunk size, the last up to
2934/// `chunk_size-1` elements will be omitted but can be retrieved from the
2935/// [`into_remainder`] function from the iterator.
2936///
2937/// This struct is created by the [`rchunks_exact_mut`] method on [slices].
2938///
2939/// # Example
2940///
2941/// ```
2942/// let mut slice = ['l', 'o', 'r', 'e', 'm'];
2943/// let iter = slice.rchunks_exact_mut(2);
2944/// ```
2945///
2946/// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
2947/// [`into_remainder`]: RChunksExactMut::into_remainder
2948/// [slices]: slice
2949#[derive(Debug)]
2950#[stable(feature = "rchunks", since = "1.31.0")]
2951#[must_use = "iterators are lazy and do nothing unless consumed"]
2952#[cfg(not(feature = "ferrocene_subset"))]
2953pub struct RChunksExactMut<'a, T: 'a> {
2954    /// # Safety
2955    /// This slice pointer must point at a valid region of `T` with at least length `v.len()`. Normally,
2956    /// those requirements would mean that we could instead use a `&mut [T]` here, but we cannot
2957    /// because `__iterator_get_unchecked` needs to return `&mut [T]`, which guarantees certain aliasing
2958    /// properties that we cannot uphold if we hold on to the full original `&mut [T]`. Wrapping a raw
2959    /// slice instead lets us hand out non-overlapping `&mut [T]` subslices of the slice we wrap.
2960    v: *mut [T],
2961    rem: &'a mut [T],
2962    chunk_size: usize,
2963}
2964
2965#[cfg(not(feature = "ferrocene_subset"))]
2966impl<'a, T> RChunksExactMut<'a, T> {
2967    #[inline]
2968    pub(super) const fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
2969        let rem = slice.len() % chunk_size;
2970        // SAFETY: 0 <= rem <= slice.len() by construction above
2971        let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) };
2972        Self { v: snd, rem: fst, chunk_size }
2973    }
2974
2975    /// Returns the remainder of the original slice that is not going to be
2976    /// returned by the iterator. The returned slice has at most `chunk_size-1`
2977    /// elements.
2978    #[must_use = "`self` will be dropped if the result is not used"]
2979    #[stable(feature = "rchunks", since = "1.31.0")]
2980    #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
2981    pub const fn into_remainder(self) -> &'a mut [T] {
2982        self.rem
2983    }
2984}
2985
2986#[stable(feature = "rchunks", since = "1.31.0")]
2987#[cfg(not(feature = "ferrocene_subset"))]
2988impl<'a, T> Iterator for RChunksExactMut<'a, T> {
2989    type Item = &'a mut [T];
2990
2991    #[inline]
2992    fn next(&mut self) -> Option<&'a mut [T]> {
2993        if self.v.len() < self.chunk_size {
2994            None
2995        } else {
2996            let len = self.v.len();
2997            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2998            let (head, tail) = unsafe { self.v.split_at_mut(len - self.chunk_size) };
2999            self.v = head;
3000            // SAFETY: Nothing else points to or will point to the contents of this slice.
3001            Some(unsafe { &mut *tail })
3002        }
3003    }
3004
3005    #[inline]
3006    fn size_hint(&self) -> (usize, Option<usize>) {
3007        let n = self.v.len() / self.chunk_size;
3008        (n, Some(n))
3009    }
3010
3011    #[inline]
3012    fn count(self) -> usize {
3013        self.len()
3014    }
3015
3016    #[inline]
3017    fn nth(&mut self, n: usize) -> Option<&'a mut [T]> {
3018        if let Some(end) = n.checked_mul(self.chunk_size)
3019            && end < self.v.len()
3020        {
3021            let idx = self.v.len() - end;
3022            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3023            let (fst, _) = unsafe { self.v.split_at_mut(idx) };
3024            self.v = fst;
3025            self.next()
3026        } else {
3027            self.v = &mut [];
3028            None
3029        }
3030    }
3031
3032    #[inline]
3033    fn last(mut self) -> Option<Self::Item> {
3034        self.next_back()
3035    }
3036
3037    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
3038        let end = self.v.len() - idx * self.chunk_size;
3039        let start = end - self.chunk_size;
3040        // SAFETY: see comments for `RChunksMut::__iterator_get_unchecked` and `self.v`.
3041        unsafe { from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) }
3042    }
3043}
3044
3045#[stable(feature = "rchunks", since = "1.31.0")]
3046#[cfg(not(feature = "ferrocene_subset"))]
3047impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
3048    #[inline]
3049    fn next_back(&mut self) -> Option<&'a mut [T]> {
3050        if self.v.len() < self.chunk_size {
3051            None
3052        } else {
3053            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3054            let (head, tail) = unsafe { self.v.split_at_mut(self.chunk_size) };
3055            self.v = tail;
3056            // SAFETY: Nothing else points to or will point to the contents of this slice.
3057            Some(unsafe { &mut *head })
3058        }
3059    }
3060
3061    #[inline]
3062    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
3063        let len = self.len();
3064        if n < len {
3065            // now that we know that `n` corresponds to a chunk,
3066            // none of these operations can underflow/overflow
3067            let offset = (len - n) * self.chunk_size;
3068            let start = self.v.len() - offset;
3069            let end = start + self.chunk_size;
3070            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3071            let (tmp, tail) = unsafe { self.v.split_at_mut(end) };
3072            // SAFETY: The self.v contract ensures that any split_at_mut is valid.
3073            let (_, nth_back) = unsafe { tmp.split_at_mut(start) };
3074            self.v = tail;
3075            // SAFETY: Nothing else points to or will point to the contents of this slice.
3076            Some(unsafe { &mut *nth_back })
3077        } else {
3078            self.v = &mut [];
3079            None
3080        }
3081    }
3082}
3083
3084#[stable(feature = "rchunks", since = "1.31.0")]
3085#[cfg(not(feature = "ferrocene_subset"))]
3086impl<T> ExactSizeIterator for RChunksExactMut<'_, T> {
3087    fn is_empty(&self) -> bool {
3088        self.v.is_empty()
3089    }
3090}
3091
3092#[unstable(feature = "trusted_len", issue = "37572")]
3093#[cfg(not(feature = "ferrocene_subset"))]
3094unsafe impl<T> TrustedLen for RChunksExactMut<'_, T> {}
3095
3096#[stable(feature = "rchunks", since = "1.31.0")]
3097#[cfg(not(feature = "ferrocene_subset"))]
3098impl<T> FusedIterator for RChunksExactMut<'_, T> {}
3099
3100#[doc(hidden)]
3101#[unstable(feature = "trusted_random_access", issue = "none")]
3102#[cfg(not(feature = "ferrocene_subset"))]
3103unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {}
3104
3105#[doc(hidden)]
3106#[unstable(feature = "trusted_random_access", issue = "none")]
3107#[cfg(not(feature = "ferrocene_subset"))]
3108unsafe impl<'a, T> TrustedRandomAccessNoCoerce for RChunksExactMut<'a, T> {
3109    const MAY_HAVE_SIDE_EFFECT: bool = false;
3110}
3111
3112#[stable(feature = "rchunks", since = "1.31.0")]
3113#[cfg(not(feature = "ferrocene_subset"))]
3114unsafe impl<T> Send for RChunksExactMut<'_, T> where T: Send {}
3115
3116#[stable(feature = "rchunks", since = "1.31.0")]
3117#[cfg(not(feature = "ferrocene_subset"))]
3118unsafe impl<T> Sync for RChunksExactMut<'_, T> where T: Sync {}
3119
3120#[doc(hidden)]
3121#[unstable(feature = "trusted_random_access", issue = "none")]
3122#[cfg(not(feature = "ferrocene_subset"))]
3123unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {}
3124
3125#[doc(hidden)]
3126#[unstable(feature = "trusted_random_access", issue = "none")]
3127#[cfg(not(feature = "ferrocene_subset"))]
3128unsafe impl<'a, T> TrustedRandomAccessNoCoerce for Iter<'a, T> {
3129    const MAY_HAVE_SIDE_EFFECT: bool = false;
3130}
3131
3132#[doc(hidden)]
3133#[unstable(feature = "trusted_random_access", issue = "none")]
3134#[cfg(not(feature = "ferrocene_subset"))]
3135unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {}
3136
3137#[doc(hidden)]
3138#[unstable(feature = "trusted_random_access", issue = "none")]
3139#[cfg(not(feature = "ferrocene_subset"))]
3140unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {
3141    const MAY_HAVE_SIDE_EFFECT: bool = false;
3142}
3143
3144/// An iterator over slice in (non-overlapping) chunks separated by a predicate.
3145///
3146/// This struct is created by the [`chunk_by`] method on [slices].
3147///
3148/// [`chunk_by`]: slice::chunk_by
3149/// [slices]: slice
3150#[stable(feature = "slice_group_by", since = "1.77.0")]
3151#[must_use = "iterators are lazy and do nothing unless consumed"]
3152#[cfg(not(feature = "ferrocene_subset"))]
3153pub struct ChunkBy<'a, T: 'a, P> {
3154    slice: &'a [T],
3155    predicate: P,
3156}
3157
3158#[stable(feature = "slice_group_by", since = "1.77.0")]
3159#[cfg(not(feature = "ferrocene_subset"))]
3160impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
3161    pub(super) const fn new(slice: &'a [T], predicate: P) -> Self {
3162        ChunkBy { slice, predicate }
3163    }
3164}
3165
3166#[stable(feature = "slice_group_by", since = "1.77.0")]
3167#[cfg(not(feature = "ferrocene_subset"))]
3168impl<'a, T: 'a, P> Iterator for ChunkBy<'a, T, P>
3169where
3170    P: FnMut(&T, &T) -> bool,
3171{
3172    type Item = &'a [T];
3173
3174    #[inline]
3175    fn next(&mut self) -> Option<Self::Item> {
3176        if self.slice.is_empty() {
3177            None
3178        } else {
3179            let mut len = 1;
3180            let mut iter = self.slice.windows(2);
3181            while let Some([l, r]) = iter.next() {
3182                if (self.predicate)(l, r) { len += 1 } else { break }
3183            }
3184            let (head, tail) = self.slice.split_at(len);
3185            self.slice = tail;
3186            Some(head)
3187        }
3188    }
3189
3190    #[inline]
3191    fn size_hint(&self) -> (usize, Option<usize>) {
3192        if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) }
3193    }
3194
3195    #[inline]
3196    fn last(mut self) -> Option<Self::Item> {
3197        self.next_back()
3198    }
3199}
3200
3201#[stable(feature = "slice_group_by", since = "1.77.0")]
3202#[cfg(not(feature = "ferrocene_subset"))]
3203impl<'a, T: 'a, P> DoubleEndedIterator for ChunkBy<'a, T, P>
3204where
3205    P: FnMut(&T, &T) -> bool,
3206{
3207    #[inline]
3208    fn next_back(&mut self) -> Option<Self::Item> {
3209        if self.slice.is_empty() {
3210            None
3211        } else {
3212            let mut len = 1;
3213            let mut iter = self.slice.windows(2);
3214            while let Some([l, r]) = iter.next_back() {
3215                if (self.predicate)(l, r) { len += 1 } else { break }
3216            }
3217            let (head, tail) = self.slice.split_at(self.slice.len() - len);
3218            self.slice = head;
3219            Some(tail)
3220        }
3221    }
3222}
3223
3224#[stable(feature = "slice_group_by", since = "1.77.0")]
3225#[cfg(not(feature = "ferrocene_subset"))]
3226impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
3227
3228#[stable(feature = "slice_group_by_clone", since = "1.89.0")]
3229#[cfg(not(feature = "ferrocene_subset"))]
3230impl<'a, T: 'a, P: Clone> Clone for ChunkBy<'a, T, P> {
3231    fn clone(&self) -> Self {
3232        Self { slice: self.slice, predicate: self.predicate.clone() }
3233    }
3234}
3235
3236#[stable(feature = "slice_group_by", since = "1.77.0")]
3237#[cfg(not(feature = "ferrocene_subset"))]
3238impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
3239    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3240        f.debug_struct("ChunkBy").field("slice", &self.slice).finish()
3241    }
3242}
3243
3244/// An iterator over slice in (non-overlapping) mutable chunks separated
3245/// by a predicate.
3246///
3247/// This struct is created by the [`chunk_by_mut`] method on [slices].
3248///
3249/// [`chunk_by_mut`]: slice::chunk_by_mut
3250/// [slices]: slice
3251#[stable(feature = "slice_group_by", since = "1.77.0")]
3252#[must_use = "iterators are lazy and do nothing unless consumed"]
3253#[cfg(not(feature = "ferrocene_subset"))]
3254pub struct ChunkByMut<'a, T: 'a, P> {
3255    slice: &'a mut [T],
3256    predicate: P,
3257}
3258
3259#[stable(feature = "slice_group_by", since = "1.77.0")]
3260#[cfg(not(feature = "ferrocene_subset"))]
3261impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
3262    pub(super) const fn new(slice: &'a mut [T], predicate: P) -> Self {
3263        ChunkByMut { slice, predicate }
3264    }
3265}
3266
3267#[stable(feature = "slice_group_by", since = "1.77.0")]
3268#[cfg(not(feature = "ferrocene_subset"))]
3269impl<'a, T: 'a, P> Iterator for ChunkByMut<'a, T, P>
3270where
3271    P: FnMut(&T, &T) -> bool,
3272{
3273    type Item = &'a mut [T];
3274
3275    #[inline]
3276    fn next(&mut self) -> Option<Self::Item> {
3277        if self.slice.is_empty() {
3278            None
3279        } else {
3280            let mut len = 1;
3281            let mut iter = self.slice.windows(2);
3282            while let Some([l, r]) = iter.next() {
3283                if (self.predicate)(l, r) { len += 1 } else { break }
3284            }
3285            let slice = mem::take(&mut self.slice);
3286            let (head, tail) = slice.split_at_mut(len);
3287            self.slice = tail;
3288            Some(head)
3289        }
3290    }
3291
3292    #[inline]
3293    fn size_hint(&self) -> (usize, Option<usize>) {
3294        if self.slice.is_empty() { (0, Some(0)) } else { (1, Some(self.slice.len())) }
3295    }
3296
3297    #[inline]
3298    fn last(mut self) -> Option<Self::Item> {
3299        self.next_back()
3300    }
3301}
3302
3303#[stable(feature = "slice_group_by", since = "1.77.0")]
3304#[cfg(not(feature = "ferrocene_subset"))]
3305impl<'a, T: 'a, P> DoubleEndedIterator for ChunkByMut<'a, T, P>
3306where
3307    P: FnMut(&T, &T) -> bool,
3308{
3309    #[inline]
3310    fn next_back(&mut self) -> Option<Self::Item> {
3311        if self.slice.is_empty() {
3312            None
3313        } else {
3314            let mut len = 1;
3315            let mut iter = self.slice.windows(2);
3316            while let Some([l, r]) = iter.next_back() {
3317                if (self.predicate)(l, r) { len += 1 } else { break }
3318            }
3319            let slice = mem::take(&mut self.slice);
3320            let (head, tail) = slice.split_at_mut(slice.len() - len);
3321            self.slice = head;
3322            Some(tail)
3323        }
3324    }
3325}
3326
3327#[stable(feature = "slice_group_by", since = "1.77.0")]
3328#[cfg(not(feature = "ferrocene_subset"))]
3329impl<'a, T: 'a, P> FusedIterator for ChunkByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
3330
3331#[stable(feature = "slice_group_by", since = "1.77.0")]
3332#[cfg(not(feature = "ferrocene_subset"))]
3333impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkByMut<'a, T, P> {
3334    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3335        f.debug_struct("ChunkByMut").field("slice", &self.slice).finish()
3336    }
3337}