Skip to main content

core/slice/
iter.rs

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