Rollup merge of #75026 - JulianKnodt:array_windows, r=Amanieu

Add array_windows fn

This mimicks the functionality added by array_chunks, and implements a const-generic form of
`windows`. It makes egregious use of `unsafe`, but by necessity because the array must be
re-interpreted as a slice of arrays, and unlike array_chunks this cannot be done by casting the
original array once, since each time the index is advanced it needs to move one element, not
`N`.

I'm planning on adding more tests, but this should be good enough as a premise for the functionality.
Notably: should there be more functions overwritten for the iterator implementation/in general?

~~I've marked the issue as #74985 as there is no corresponding exact issue for `array_windows`, but it's based of off `array_chunks`.~~

Edit: See Issue #75027 created by @lcnr for tracking issue

~~Do not merge until I add more tests, please.~~

r? @lcnr
This commit is contained in:
Tyler Mandry 2020-09-16 12:24:03 -07:00 committed by GitHub
commit 23a677787e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 196 additions and 6 deletions

View file

@ -5,21 +5,21 @@
#![cfg_attr(min, feature(min_const_generics))]
trait SliceExt<T: Clone> {
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>;
fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N>;
}
impl <T: Clone> SliceExt<T> for [T] {
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N> {
ArrayWindows{ idx: 0, slice: &self }
fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N> {
ArrayWindowsExample{ idx: 0, slice: &self }
}
}
struct ArrayWindows<'a, T, const N: usize> {
struct ArrayWindowsExample<'a, T, const N: usize> {
slice: &'a [T],
idx: usize,
}
impl <'a, T: Clone, const N: usize> Iterator for ArrayWindows<'a, T, N> {
impl <'a, T: Clone, const N: usize> Iterator for ArrayWindowsExample<'a, T, N> {
type Item = [T; N];
fn next(&mut self) -> Option<Self::Item> {
// Note: this is unsound for some `T` and not meant as an example
@ -45,7 +45,7 @@ const FOUR: usize = 4;
fn main() {
let v: Vec<usize> = vec![0; 100];
for array in v.as_slice().array_windows::<FOUR>() {
for array in v.as_slice().array_windows_example::<FOUR>() {
assert_eq!(array, [0, 0, 0, 0])
}
}