diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 84fa34c75e3..546edef7f57 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -8,7 +8,7 @@ use crate::cmp::Ordering; use crate::fmt; use crate::intrinsics::{assume, exact_div, unchecked_sub}; use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess}; -use crate::marker::{self, Send, Sized, Sync}; +use crate::marker::{PhantomData, Send, Sized, Sync}; use crate::mem; use crate::ptr::NonNull; @@ -62,11 +62,11 @@ fn size_from_ptr(_: *const T) -> usize { /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T: 'a> { - pub(super) ptr: NonNull, - pub(super) end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that + ptr: NonNull, + end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that // ptr == end is a quick test for the Iterator being empty, that works // for both ZST and non-ZST. - pub(super) _marker: marker::PhantomData<&'a T>, + _marker: PhantomData<&'a T>, } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -82,6 +82,23 @@ unsafe impl Sync for Iter<'_, T> {} unsafe impl Send for Iter<'_, T> {} impl<'a, T> Iter<'a, T> { + #[inline] + pub(super) fn new(slice: &'a [T]) -> Self { + let ptr = slice.as_ptr(); + // SAFETY: Similar to `IterMut::new`. + unsafe { + assume(!ptr.is_null()); + + let end = if mem::size_of::() == 0 { + (ptr as *const u8).wrapping_add(slice.len()) as *const T + } else { + ptr.add(slice.len()) + }; + + Self { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: PhantomData } + } + } + /// Views the underlying data as a subslice of the original data. /// /// This has the same lifetime as the original slice, and so the @@ -164,11 +181,11 @@ impl AsRef<[T]> for Iter<'_, T> { /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T: 'a> { - pub(super) ptr: NonNull, - pub(super) end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that + ptr: NonNull, + end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that // ptr == end is a quick test for the Iterator being empty, that works // for both ZST and non-ZST. - pub(super) _marker: marker::PhantomData<&'a mut T>, + _marker: PhantomData<&'a mut T>, } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -184,6 +201,38 @@ unsafe impl Sync for IterMut<'_, T> {} unsafe impl Send for IterMut<'_, T> {} impl<'a, T> IterMut<'a, T> { + #[inline] + pub(super) fn new(slice: &'a mut [T]) -> Self { + let ptr = slice.as_mut_ptr(); + // SAFETY: There are several things here: + // + // `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid + // reference thus it is non-NUL and safe to use and pass to + // `NonNull::new_unchecked` . + // + // Adding `slice.len()` to the starting pointer gives a pointer + // at the end of `slice`. `end` will never be dereferenced, only checked + // for direct pointer equality with `ptr` to check if the iterator is + // done. + // + // In the case of a ZST, the end pointer is just the start pointer plus + // the length, to also allows for the fast `ptr == end` check. + // + // See the `next_unchecked!` and `is_empty!` macros as well as the + // `post_inc_start` method for more informations. + unsafe { + assume(!ptr.is_null()); + + let end = if mem::size_of::() == 0 { + (ptr as *mut u8).wrapping_add(slice.len()) as *mut T + } else { + ptr.add(slice.len()) + }; + + Self { ptr: NonNull::new_unchecked(ptr), end, _marker: PhantomData } + } + } + /// Views the underlying data as a subslice of the original data. /// /// To avoid creating `&mut` references that alias, this is forced @@ -277,9 +326,16 @@ pub struct Split<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) v: &'a [T], - pub(super) pred: P, - pub(super) finished: bool, + v: &'a [T], + pred: P, + finished: bool, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> { + #[inline] + pub(super) fn new(slice: &'a [T], pred: P) -> Self { + Self { v: slice, pred, finished: false } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -385,9 +441,16 @@ pub struct SplitInclusive<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) v: &'a [T], - pub(super) pred: P, - pub(super) finished: bool, + v: &'a [T], + pred: P, + finished: bool, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> { + #[inline] + pub(super) fn new(slice: &'a [T], pred: P) -> Self { + Self { v: slice, pred, finished: false } + } } #[unstable(feature = "split_inclusive", issue = "72360")] @@ -483,9 +546,16 @@ pub struct SplitMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) v: &'a mut [T], - pub(super) pred: P, - pub(super) finished: bool, + v: &'a mut [T], + pred: P, + finished: bool, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitMut<'a, T, P> { + #[inline] + pub(super) fn new(slice: &'a mut [T], pred: P) -> Self { + Self { v: slice, pred, finished: false } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -598,9 +668,16 @@ pub struct SplitInclusiveMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) v: &'a mut [T], - pub(super) pred: P, - pub(super) finished: bool, + v: &'a mut [T], + pred: P, + finished: bool, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> { + #[inline] + pub(super) fn new(slice: &'a mut [T], pred: P) -> Self { + Self { v: slice, pred, finished: false } + } } #[unstable(feature = "split_inclusive", issue = "72360")] @@ -706,7 +783,14 @@ pub struct RSplit<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) inner: Split<'a, T, P>, + inner: Split<'a, T, P>, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplit<'a, T, P> { + #[inline] + pub(super) fn new(slice: &'a [T], pred: P) -> Self { + Self { inner: Split::new(slice, pred) } + } } #[stable(feature = "slice_rsplit", since = "1.27.0")] @@ -777,7 +861,14 @@ pub struct RSplitMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) inner: SplitMut<'a, T, P>, + inner: SplitMut<'a, T, P>, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitMut<'a, T, P> { + #[inline] + pub(super) fn new(slice: &'a mut [T], pred: P) -> Self { + Self { inner: SplitMut::new(slice, pred) } + } } #[stable(feature = "slice_rsplit", since = "1.27.0")] @@ -840,9 +931,9 @@ impl FusedIterator for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {} /// match a predicate function, splitting at most a fixed number of /// times. #[derive(Debug)] -pub(super) struct GenericSplitN { - pub(super) iter: I, - pub(super) count: usize, +struct GenericSplitN { + iter: I, + count: usize, } impl> Iterator for GenericSplitN { @@ -882,7 +973,14 @@ pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) inner: GenericSplitN>, + inner: GenericSplitN>, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitN<'a, T, P> { + #[inline] + pub(super) fn new(s: Split<'a, T, P>, n: usize) -> Self { + Self { inner: GenericSplitN { iter: s, count: n } } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -908,7 +1006,14 @@ pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) inner: GenericSplitN>, + inner: GenericSplitN>, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitN<'a, T, P> { + #[inline] + pub(super) fn new(s: RSplit<'a, T, P>, n: usize) -> Self { + Self { inner: GenericSplitN { iter: s, count: n } } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -933,7 +1038,14 @@ pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) inner: GenericSplitN>, + inner: GenericSplitN>, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitNMut<'a, T, P> { + #[inline] + pub(super) fn new(s: SplitMut<'a, T, P>, n: usize) -> Self { + Self { inner: GenericSplitN { iter: s, count: n } } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -959,7 +1071,14 @@ pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - pub(super) inner: GenericSplitN>, + inner: GenericSplitN>, +} + +impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitNMut<'a, T, P> { + #[inline] + pub(super) fn new(s: RSplitMut<'a, T, P>, n: usize) -> Self { + Self { inner: GenericSplitN { iter: s, count: n } } + } } #[stable(feature = "core_impl_debug", since = "1.9.0")] @@ -986,8 +1105,15 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] } #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Windows<'a, T: 'a> { - pub(super) v: &'a [T], - pub(super) size: usize, + v: &'a [T], + size: usize, +} + +impl<'a, T: 'a> Windows<'a, T> { + #[inline] + pub(super) fn new(slice: &'a [T], size: usize) -> Self { + Self { v: slice, size } + } } // FIXME(#26925) Remove in favor of `#[derive(Clone)]` @@ -1118,8 +1244,15 @@ unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> { #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chunks<'a, T: 'a> { - pub(super) v: &'a [T], - pub(super) chunk_size: usize, + v: &'a [T], + chunk_size: usize, +} + +impl<'a, T: 'a> Chunks<'a, T> { + #[inline] + pub(super) fn new(slice: &'a [T], size: usize) -> Self { + Self { v: slice, chunk_size: size } + } } // FIXME(#26925) Remove in favor of `#[derive(Clone)]` @@ -1272,8 +1405,15 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> { #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct ChunksMut<'a, T: 'a> { - pub(super) v: &'a mut [T], - pub(super) chunk_size: usize, + v: &'a mut [T], + chunk_size: usize, +} + +impl<'a, T: 'a> ChunksMut<'a, T> { + #[inline] + pub(super) fn new(slice: &'a mut [T], size: usize) -> Self { + Self { v: slice, chunk_size: size } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1425,12 +1565,21 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> { #[derive(Debug)] #[stable(feature = "chunks_exact", since = "1.31.0")] pub struct ChunksExact<'a, T: 'a> { - pub(super) v: &'a [T], - pub(super) rem: &'a [T], - pub(super) chunk_size: usize, + v: &'a [T], + rem: &'a [T], + chunk_size: usize, } impl<'a, T> ChunksExact<'a, T> { + #[inline] + pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self { + let rem = slice.len() % chunk_size; + let fst_len = slice.len() - rem; + // SAFETY: 0 <= fst_len <= slice.len() by construction above + let (fst, snd) = unsafe { slice.split_at_unchecked(fst_len) }; + Self { v: fst, rem: snd, chunk_size } + } + /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` /// elements. @@ -1565,12 +1714,21 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> { #[derive(Debug)] #[stable(feature = "chunks_exact", since = "1.31.0")] pub struct ChunksExactMut<'a, T: 'a> { - pub(super) v: &'a mut [T], - pub(super) rem: &'a mut [T], - pub(super) chunk_size: usize, + v: &'a mut [T], + rem: &'a mut [T], + chunk_size: usize, } impl<'a, T> ChunksExactMut<'a, T> { + #[inline] + pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self { + let rem = slice.len() % chunk_size; + let fst_len = slice.len() - rem; + // SAFETY: 0 <= fst_len <= slice.len() by construction above + let (fst, snd) = unsafe { slice.split_at_mut_unchecked(fst_len) }; + Self { v: fst, rem: snd, chunk_size } + } + /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` /// elements. @@ -1697,9 +1855,17 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> { #[derive(Debug, Clone, Copy)] #[unstable(feature = "array_windows", issue = "75027")] pub struct ArrayWindows<'a, T: 'a, const N: usize> { - pub(crate) slice_head: *const T, - pub(crate) num: usize, - pub(crate) marker: marker::PhantomData<&'a [T; N]>, + slice_head: *const T, + num: usize, + marker: PhantomData<&'a [T; N]>, +} + +impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> { + #[inline] + pub(super) fn new(slice: &'a [T]) -> Self { + let num_windows = slice.len().saturating_sub(N - 1); + Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData } + } } #[unstable(feature = "array_windows", issue = "75027")] @@ -1802,11 +1968,22 @@ impl ExactSizeIterator for ArrayWindows<'_, T, N> { #[derive(Debug)] #[unstable(feature = "array_chunks", issue = "74985")] pub struct ArrayChunks<'a, T: 'a, const N: usize> { - pub(super) iter: Iter<'a, [T; N]>, - pub(super) rem: &'a [T], + iter: Iter<'a, [T; N]>, + rem: &'a [T], } impl<'a, T, const N: usize> ArrayChunks<'a, T, N> { + #[inline] + pub(super) fn new(slice: &'a [T]) -> Self { + let len = slice.len() / N; + let (fst, snd) = slice.split_at(len * N); + // SAFETY: We cast a slice of `len * N` elements into + // a slice of `len` many `N` elements chunks. + let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) }; + + Self { iter: array_slice.iter(), rem: snd } + } + /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `N-1` /// elements. @@ -1909,11 +2086,23 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N> #[derive(Debug)] #[unstable(feature = "array_chunks", issue = "74985")] pub struct ArrayChunksMut<'a, T: 'a, const N: usize> { - pub(super) iter: IterMut<'a, [T; N]>, - pub(super) rem: &'a mut [T], + iter: IterMut<'a, [T; N]>, + rem: &'a mut [T], } impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> { + #[inline] + pub(super) fn new(slice: &'a mut [T]) -> Self { + let len = slice.len() / N; + let (fst, snd) = slice.split_at_mut(len * N); + // SAFETY: We cast a slice of `len * N` elements into + // a slice of `len` many `N` elements chunks. + unsafe { + let array_slice: &mut [[T; N]] = from_raw_parts_mut(fst.as_mut_ptr().cast(), len); + Self { iter: array_slice.iter_mut(), rem: snd } + } + } + /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `N-1` /// elements. @@ -2006,8 +2195,15 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunksMut<'a, T, #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] pub struct RChunks<'a, T: 'a> { - pub(super) v: &'a [T], - pub(super) chunk_size: usize, + v: &'a [T], + chunk_size: usize, +} + +impl<'a, T: 'a> RChunks<'a, T> { + #[inline] + pub(super) fn new(slice: &'a [T], size: usize) -> Self { + Self { v: slice, chunk_size: size } + } } // FIXME(#26925) Remove in favor of `#[derive(Clone)]` @@ -2156,8 +2352,15 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> { #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] pub struct RChunksMut<'a, T: 'a> { - pub(super) v: &'a mut [T], - pub(super) chunk_size: usize, + v: &'a mut [T], + chunk_size: usize, +} + +impl<'a, T: 'a> RChunksMut<'a, T> { + #[inline] + pub(super) fn new(slice: &'a mut [T], size: usize) -> Self { + Self { v: slice, chunk_size: size } + } } #[stable(feature = "rchunks", since = "1.31.0")] @@ -2306,12 +2509,20 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> { #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] pub struct RChunksExact<'a, T: 'a> { - pub(super) v: &'a [T], - pub(super) rem: &'a [T], - pub(super) chunk_size: usize, + v: &'a [T], + rem: &'a [T], + chunk_size: usize, } impl<'a, T> RChunksExact<'a, T> { + #[inline] + pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self { + let rem = slice.len() % chunk_size; + // SAFETY: 0 <= rem <= slice.len() by construction above + let (fst, snd) = unsafe { slice.split_at_unchecked(rem) }; + Self { v: snd, rem: fst, chunk_size } + } + /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` /// elements. @@ -2451,12 +2662,20 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> { #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] pub struct RChunksExactMut<'a, T: 'a> { - pub(super) v: &'a mut [T], - pub(super) rem: &'a mut [T], - pub(super) chunk_size: usize, + v: &'a mut [T], + rem: &'a mut [T], + chunk_size: usize, } impl<'a, T> RChunksExactMut<'a, T> { + #[inline] + pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self { + let rem = slice.len() % chunk_size; + // SAFETY: 0 <= rem <= slice.len() by construction above + let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) }; + Self { v: snd, rem: fst, chunk_size } + } + /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` /// elements. diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 8e9d1eb98a8..fd98f60c3dd 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -9,13 +9,12 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::cmp::Ordering::{self, Equal, Greater, Less}; -use crate::intrinsics::assume; -use crate::marker::{self, Copy}; +use crate::marker::Copy; use crate::mem; use crate::ops::{FnMut, Range, RangeBounds}; use crate::option::Option; use crate::option::Option::{None, Some}; -use crate::ptr::{self, NonNull}; +use crate::ptr; use crate::result::Result; use crate::result::Result::{Err, Ok}; @@ -35,8 +34,6 @@ mod raw; mod rotate; mod sort; -use iter::GenericSplitN; - #[stable(feature = "rust1", since = "1.0.0")] pub use iter::{Chunks, ChunksMut, Windows}; #[stable(feature = "rust1", since = "1.0.0")] @@ -681,34 +678,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn iter(&self) -> Iter<'_, T> { - let ptr = self.as_ptr(); - // SAFETY: There are several things here: - // - // `ptr` has been obtained by `self.as_ptr()` where `self` is a valid - // reference thus it is non-NUL and safe to use and pass to - // `NonNull::new_unchecked` . - // - // Adding `self.len()` to the starting pointer gives a pointer - // at the end of `self`. `end` will never be dereferenced, only checked - // for direct pointer equality with `ptr` to check if the iterator is - // done. - // - // In the case of a ZST, the end pointer is just the start pointer plus - // the length, to also allows for the fast `ptr == end` check. - // - // See the `next_unchecked!` and `is_empty!` macros as well as the - // `post_inc_start` method for more informations. - unsafe { - assume(!ptr.is_null()); - - let end = if mem::size_of::() == 0 { - (ptr as *const u8).wrapping_add(self.len()) as *const T - } else { - ptr.add(self.len()) - }; - - Iter { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: marker::PhantomData } - } + Iter::new(self) } /// Returns an iterator that allows modifying each value. @@ -725,34 +695,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn iter_mut(&mut self) -> IterMut<'_, T> { - let ptr = self.as_mut_ptr(); - // SAFETY: There are several things here: - // - // `ptr` has been obtained by `self.as_ptr()` where `self` is a valid - // reference thus it is non-NUL and safe to use and pass to - // `NonNull::new_unchecked` . - // - // Adding `self.len()` to the starting pointer gives a pointer - // at the end of `self`. `end` will never be dereferenced, only checked - // for direct pointer equality with `ptr` to check if the iterator is - // done. - // - // In the case of a ZST, the end pointer is just the start pointer plus - // the length, to also allows for the fast `ptr == end` check. - // - // See the `next_unchecked!` and `is_empty!` macros as well as the - // `post_inc_start` method for more informations. - unsafe { - assume(!ptr.is_null()); - - let end = if mem::size_of::() == 0 { - (ptr as *mut u8).wrapping_add(self.len()) as *mut T - } else { - ptr.add(self.len()) - }; - - IterMut { ptr: NonNull::new_unchecked(ptr), end, _marker: marker::PhantomData } - } + IterMut::new(self) } /// Returns an iterator over all contiguous windows of length @@ -785,7 +728,7 @@ impl [T] { #[inline] pub fn windows(&self, size: usize) -> Windows<'_, T> { assert_ne!(size, 0); - Windows { v: self, size } + Windows::new(self, size) } /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the @@ -819,7 +762,7 @@ impl [T] { #[inline] pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> { assert_ne!(chunk_size, 0); - Chunks { v: self, chunk_size } + Chunks::new(self, chunk_size) } /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the @@ -857,7 +800,7 @@ impl [T] { #[inline] pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> { assert_ne!(chunk_size, 0); - ChunksMut { v: self, chunk_size } + ChunksMut::new(self, chunk_size) } /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the @@ -894,11 +837,7 @@ impl [T] { #[inline] pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> { assert_ne!(chunk_size, 0); - let rem = self.len() % chunk_size; - let fst_len = self.len() - rem; - // SAFETY: 0 <= fst_len <= self.len() by construction above - let (fst, snd) = unsafe { self.split_at_unchecked(fst_len) }; - ChunksExact { v: fst, rem: snd, chunk_size } + ChunksExact::new(self, chunk_size) } /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the @@ -940,11 +879,7 @@ impl [T] { #[inline] pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> { assert_ne!(chunk_size, 0); - let rem = self.len() % chunk_size; - let fst_len = self.len() - rem; - // SAFETY: 0 <= fst_len <= self.len() by construction above - let (fst, snd) = unsafe { self.split_at_mut_unchecked(fst_len) }; - ChunksExactMut { v: fst, rem: snd, chunk_size } + ChunksExactMut::new(self, chunk_size) } /// Returns an iterator over `N` elements of the slice at a time, starting at the @@ -978,12 +913,7 @@ impl [T] { #[inline] pub fn array_chunks(&self) -> ArrayChunks<'_, T, N> { assert_ne!(N, 0); - let len = self.len() / N; - let (fst, snd) = self.split_at(len * N); - // SAFETY: We cast a slice of `len * N` elements into - // a slice of `len` many `N` elements chunks. - let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) }; - ArrayChunks { iter: array_slice.iter(), rem: snd } + ArrayChunks::new(self) } /// Returns an iterator over `N` elements of the slice at a time, starting at the @@ -1019,14 +949,7 @@ impl [T] { #[inline] pub fn array_chunks_mut(&mut self) -> ArrayChunksMut<'_, T, N> { assert_ne!(N, 0); - let len = self.len() / N; - let (fst, snd) = self.split_at_mut(len * N); - // SAFETY: We cast a slice of `len * N` elements into - // a slice of `len` many `N` elements chunks. - unsafe { - let array_slice: &mut [[T; N]] = from_raw_parts_mut(fst.as_mut_ptr().cast(), len); - ArrayChunksMut { iter: array_slice.iter_mut(), rem: snd } - } + ArrayChunksMut::new(self) } /// Returns an iterator over overlapping windows of `N` elements of a slice, @@ -1058,9 +981,7 @@ impl [T] { #[inline] pub fn array_windows(&self) -> ArrayWindows<'_, T, N> { assert_ne!(N, 0); - - let num_windows = self.len().saturating_sub(N - 1); - ArrayWindows { slice_head: self.as_ptr(), num: num_windows, marker: marker::PhantomData } + ArrayWindows::new(self) } /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end @@ -1094,7 +1015,7 @@ impl [T] { #[inline] pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> { assert!(chunk_size != 0); - RChunks { v: self, chunk_size } + RChunks::new(self, chunk_size) } /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end @@ -1132,7 +1053,7 @@ impl [T] { #[inline] pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> { assert!(chunk_size != 0); - RChunksMut { v: self, chunk_size } + RChunksMut::new(self, chunk_size) } /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the @@ -1171,10 +1092,7 @@ impl [T] { #[inline] pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> { assert!(chunk_size != 0); - let rem = self.len() % chunk_size; - // SAFETY: 0 <= rem <= self.len() by construction above - let (fst, snd) = unsafe { self.split_at_unchecked(rem) }; - RChunksExact { v: snd, rem: fst, chunk_size } + RChunksExact::new(self, chunk_size) } /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end @@ -1217,10 +1135,7 @@ impl [T] { #[inline] pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> { assert!(chunk_size != 0); - let rem = self.len() % chunk_size; - // SAFETY: 0 <= rem <= self.len() by construction above - let (fst, snd) = unsafe { self.split_at_mut_unchecked(rem) }; - RChunksExactMut { v: snd, rem: fst, chunk_size } + RChunksExactMut::new(self, chunk_size) } /// Divides one slice into two at an index. @@ -1439,7 +1354,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - Split { v: self, pred, finished: false } + Split::new(self, pred) } /// Returns an iterator over mutable subslices separated by elements that @@ -1461,7 +1376,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - SplitMut { v: self, pred, finished: false } + SplitMut::new(self, pred) } /// Returns an iterator over subslices separated by elements that match @@ -1499,7 +1414,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - SplitInclusive { v: self, pred, finished: false } + SplitInclusive::new(self, pred) } /// Returns an iterator over mutable subslices separated by elements that @@ -1524,7 +1439,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - SplitInclusiveMut { v: self, pred, finished: false } + SplitInclusiveMut::new(self, pred) } /// Returns an iterator over subslices separated by elements that match @@ -1560,7 +1475,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - RSplit { inner: self.split(pred) } + RSplit::new(self, pred) } /// Returns an iterator over mutable subslices separated by elements that @@ -1586,7 +1501,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - RSplitMut { inner: self.split_mut(pred) } + RSplitMut::new(self, pred) } /// Returns an iterator over subslices separated by elements that match @@ -1614,7 +1529,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - SplitN { inner: GenericSplitN { iter: self.split(pred), count: n } } + SplitN::new(self.split(pred), n) } /// Returns an iterator over subslices separated by elements that match @@ -1640,7 +1555,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - SplitNMut { inner: GenericSplitN { iter: self.split_mut(pred), count: n } } + SplitNMut::new(self.split_mut(pred), n) } /// Returns an iterator over subslices separated by elements that match @@ -1669,7 +1584,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - RSplitN { inner: GenericSplitN { iter: self.rsplit(pred), count: n } } + RSplitN::new(self.rsplit(pred), n) } /// Returns an iterator over subslices separated by elements that match @@ -1696,7 +1611,7 @@ impl [T] { where F: FnMut(&T) -> bool, { - RSplitNMut { inner: GenericSplitN { iter: self.rsplit_mut(pred), count: n } } + RSplitNMut::new(self.rsplit_mut(pred), n) } /// Returns `true` if the slice contains an element with the given value.