Skip to content

Commit 1fd3a4b

Browse files
committed
allow empty windows
1 parent 7f3dc04 commit 1fd3a4b

File tree

3 files changed

+36
-29
lines changed

3 files changed

+36
-29
lines changed

library/core/src/slice/iter.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::intrinsics::{assume, exact_div, unchecked_sub};
1111
use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
1212
use crate::marker::{PhantomData, Send, Sized, Sync};
1313
use crate::mem;
14-
use crate::num::NonZeroUsize;
1514
use crate::ptr::NonNull;
1615

1716
use super::{from_raw_parts, from_raw_parts_mut};
@@ -1193,12 +1192,12 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] }
11931192
#[stable(feature = "rust1", since = "1.0.0")]
11941193
pub struct Windows<'a, T: 'a> {
11951194
v: &'a [T],
1196-
size: NonZeroUsize,
1195+
size: usize,
11971196
}
11981197

11991198
impl<'a, T: 'a> Windows<'a, T> {
12001199
#[inline]
1201-
pub(super) fn new(slice: &'a [T], size: NonZeroUsize) -> Self {
1200+
pub(super) fn new(slice: &'a [T], size: usize) -> Self {
12021201
Self { v: slice, size }
12031202
}
12041203
}
@@ -1217,21 +1216,21 @@ impl<'a, T> Iterator for Windows<'a, T> {
12171216

12181217
#[inline]
12191218
fn next(&mut self) -> Option<&'a [T]> {
1220-
if self.size.get() > self.v.len() {
1219+
if self.size > self.v.len() {
12211220
None
12221221
} else {
1223-
let ret = Some(&self.v[..self.size.get()]);
1222+
let ret = Some(&self.v[..self.size]);
12241223
self.v = &self.v[1..];
12251224
ret
12261225
}
12271226
}
12281227

12291228
#[inline]
12301229
fn size_hint(&self) -> (usize, Option<usize>) {
1231-
if self.size.get() > self.v.len() {
1230+
if self.size > self.v.len() {
12321231
(0, Some(0))
12331232
} else {
1234-
let size = self.v.len() - self.size.get() + 1;
1233+
let size = self.v.len() - self.size + 1;
12351234
(size, Some(size))
12361235
}
12371236
}
@@ -1243,7 +1242,7 @@ impl<'a, T> Iterator for Windows<'a, T> {
12431242

12441243
#[inline]
12451244
fn nth(&mut self, n: usize) -> Option<Self::Item> {
1246-
let (end, overflow) = self.size.get().overflowing_add(n);
1245+
let (end, overflow) = self.size.overflowing_add(n);
12471246
if end > self.v.len() || overflow {
12481247
self.v = &[];
12491248
None
@@ -1256,10 +1255,10 @@ impl<'a, T> Iterator for Windows<'a, T> {
12561255

12571256
#[inline]
12581257
fn last(self) -> Option<Self::Item> {
1259-
if self.size.get() > self.v.len() {
1258+
if self.size > self.v.len() {
12601259
None
12611260
} else {
1262-
let start = self.v.len() - self.size.get();
1261+
let start = self.v.len() - self.size;
12631262
Some(&self.v[start..])
12641263
}
12651264
}
@@ -1270,18 +1269,18 @@ impl<'a, T> Iterator for Windows<'a, T> {
12701269
// which means that `i` cannot overflow an `isize`, and the
12711270
// slice created by `from_raw_parts` is a subslice of `self.v`
12721271
// thus is guaranteed to be valid for the lifetime `'a` of `self.v`.
1273-
unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size.get()) }
1272+
unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size) }
12741273
}
12751274
}
12761275

12771276
#[stable(feature = "rust1", since = "1.0.0")]
12781277
impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
12791278
#[inline]
12801279
fn next_back(&mut self) -> Option<&'a [T]> {
1281-
if self.size.get() > self.v.len() {
1280+
if self.size > self.v.len() {
12821281
None
12831282
} else {
1284-
let ret = Some(&self.v[self.v.len() - self.size.get()..]);
1283+
let ret = Some(&self.v[self.v.len() - self.size..]);
12851284
self.v = &self.v[..self.v.len() - 1];
12861285
ret
12871286
}
@@ -1290,11 +1289,11 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
12901289
#[inline]
12911290
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
12921291
let (end, overflow) = self.v.len().overflowing_sub(n);
1293-
if end < self.size.get() || overflow {
1292+
if end < self.size || overflow {
12941293
self.v = &[];
12951294
None
12961295
} else {
1297-
let ret = &self.v[end - self.size.get()..end];
1296+
let ret = &self.v[end - self.size..end];
12981297
self.v = &self.v[..end - 1];
12991298
Some(ret)
13001299
}
@@ -1995,7 +1994,7 @@ pub struct ArrayWindows<'a, T: 'a, const N: usize> {
19951994
impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
19961995
#[inline]
19971996
pub(super) fn new(slice: &'a [T]) -> Self {
1998-
let num_windows = slice.len().saturating_sub(N - 1);
1997+
let num_windows = (slice.len() + 1).saturating_sub(N);
19991998
Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData }
20001999
}
20012000
}

library/core/src/slice/mod.rs

+1-13
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use crate::cmp::Ordering::{self, Greater, Less};
1212
use crate::marker::Copy;
1313
use crate::mem;
14-
use crate::num::NonZeroUsize;
1514
use crate::ops::{FnMut, Range, RangeBounds};
1615
use crate::option::Option;
1716
use crate::option::Option::{None, Some};
@@ -725,13 +724,9 @@ impl<T> [T] {
725724
}
726725

727726
/// Returns an iterator over all contiguous windows of length
728-
/// `size`. The windows overlap. If the slice is shorter than
727+
/// `size`. The windows may overlap. If the slice is shorter than
729728
/// `size`, the iterator returns no values.
730729
///
731-
/// # Panics
732-
///
733-
/// Panics if `size` is 0.
734-
///
735730
/// # Examples
736731
///
737732
/// ```
@@ -753,7 +748,6 @@ impl<T> [T] {
753748
#[stable(feature = "rust1", since = "1.0.0")]
754749
#[inline]
755750
pub fn windows(&self, size: usize) -> Windows<'_, T> {
756-
let size = NonZeroUsize::new(size).expect("size is zero");
757751
Windows::new(self, size)
758752
}
759753

@@ -1199,11 +1193,6 @@ impl<T> [T] {
11991193
///
12001194
/// If `N` is greater than the size of the slice, it will return no windows.
12011195
///
1202-
/// # Panics
1203-
///
1204-
/// Panics if `N` is 0. This check will most probably get changed to a compile time
1205-
/// error before this method gets stabilized.
1206-
///
12071196
/// # Examples
12081197
///
12091198
/// ```
@@ -1220,7 +1209,6 @@ impl<T> [T] {
12201209
#[unstable(feature = "array_windows", issue = "75027")]
12211210
#[inline]
12221211
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
1223-
assert_ne!(N, 0);
12241212
ArrayWindows::new(self)
12251213
}
12261214

library/core/tests/slice.rs

+20
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,18 @@ fn test_array_windows_infer() {
726726
assert_eq!(total, 3 + 6 + 9 + 12 + 15);
727727
}
728728

729+
#[test]
730+
fn test_array_windows_zero() {
731+
let v: &[i32] = &[0, 1, 2];
732+
let mut iter = v.array_windows::<0>();
733+
734+
assert_eq!(iter.next(), Some(&[]));
735+
assert_eq!(iter.next(), Some(&[]));
736+
assert_eq!(iter.next(), Some(&[]));
737+
assert_eq!(iter.next(), Some(&[]));
738+
assert_eq!(iter.next(), None);
739+
}
740+
729741
#[test]
730742
fn test_array_windows_count() {
731743
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
@@ -739,6 +751,10 @@ fn test_array_windows_count() {
739751
let v3: &[i32] = &[];
740752
let c3 = v3.array_windows::<2>();
741753
assert_eq!(c3.count(), 0);
754+
755+
let v4: &[i32] = &[0, 1, 2];
756+
let c4 = v4.array_windows::<0>();
757+
assert_eq!(c4.count(), 4);
742758
}
743759

744760
#[test]
@@ -1050,6 +1066,10 @@ fn test_windows_count() {
10501066
let v3: &[i32] = &[];
10511067
let c3 = v3.windows(2);
10521068
assert_eq!(c3.count(), 0);
1069+
1070+
let v4: &[i32] = &[0, 1, 2, 3, 4];
1071+
let c4 = v4.windows(0);
1072+
assert_eq!(c4.count(), 6);
10531073
}
10541074

10551075
#[test]

0 commit comments

Comments
 (0)