Rollup merge of #147204 - camsteffen:array-windows-ref, r=joboet
Refactor ArrayWindows to use a slice [Tracking issue](https://github.com/rust-lang/rust/issues/75027)
This commit is contained in:
commit
4b905f9cb0
1 changed files with 22 additions and 47 deletions
|
|
@ -2203,16 +2203,13 @@ unsafe impl<T> Sync for ChunksExactMut<'_, T> where T: Sync {}
|
|||
#[unstable(feature = "array_windows", issue = "75027")]
|
||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
pub struct ArrayWindows<'a, T: 'a, const N: usize> {
|
||||
slice_head: *const T,
|
||||
num: usize,
|
||||
marker: PhantomData<&'a [T; N]>,
|
||||
v: &'a [T],
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
|
||||
#[inline]
|
||||
pub(super) const 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 }
|
||||
Self { v: slice }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2222,49 +2219,34 @@ impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
|
|||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.num == 0 {
|
||||
return None;
|
||||
let ret = self.v.first_chunk();
|
||||
if ret.is_some() {
|
||||
self.v = &self.v[1..];
|
||||
}
|
||||
// SAFETY:
|
||||
// This is safe because it's indexing into a slice guaranteed to be length > N.
|
||||
let ret = unsafe { &*self.slice_head.cast::<[T; N]>() };
|
||||
// SAFETY: Guaranteed that there are at least 1 item remaining otherwise
|
||||
// earlier branch would've been hit
|
||||
self.slice_head = unsafe { self.slice_head.add(1) };
|
||||
|
||||
self.num -= 1;
|
||||
Some(ret)
|
||||
ret
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(self.num, Some(self.num))
|
||||
let size = self.v.len().saturating_sub(N - 1);
|
||||
(size, Some(size))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn count(self) -> usize {
|
||||
self.num
|
||||
self.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
if self.num <= n {
|
||||
self.num = 0;
|
||||
return None;
|
||||
}
|
||||
// SAFETY:
|
||||
// This is safe because it's indexing into a slice guaranteed to be length > N.
|
||||
let ret = unsafe { &*self.slice_head.add(n).cast::<[T; N]>() };
|
||||
// SAFETY: Guaranteed that there are at least n items remaining
|
||||
self.slice_head = unsafe { self.slice_head.add(n + 1) };
|
||||
|
||||
self.num -= n + 1;
|
||||
Some(ret)
|
||||
let idx = n.min(self.v.len());
|
||||
self.v = &self.v[idx..];
|
||||
self.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last(mut self) -> Option<Self::Item> {
|
||||
self.nth(self.num.checked_sub(1)?)
|
||||
fn last(self) -> Option<Self::Item> {
|
||||
self.v.last_chunk()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2272,32 +2254,25 @@ impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
|
|||
impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a [T; N]> {
|
||||
if self.num == 0 {
|
||||
return None;
|
||||
let ret = self.v.last_chunk();
|
||||
if ret.is_some() {
|
||||
self.v = &self.v[..self.v.len() - 1];
|
||||
}
|
||||
// SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
|
||||
let ret = unsafe { &*self.slice_head.add(self.num - 1).cast::<[T; N]>() };
|
||||
self.num -= 1;
|
||||
Some(ret)
|
||||
ret
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
|
||||
if self.num <= n {
|
||||
self.num = 0;
|
||||
return None;
|
||||
}
|
||||
// SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
|
||||
let ret = unsafe { &*self.slice_head.add(self.num - (n + 1)).cast::<[T; N]>() };
|
||||
self.num -= n + 1;
|
||||
Some(ret)
|
||||
let idx = self.v.len().saturating_sub(n);
|
||||
self.v = &self.v[..idx];
|
||||
self.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "array_windows", issue = "75027")]
|
||||
impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.num == 0
|
||||
self.v.len() < N
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue