diff --git a/src/array_impl.rs b/src/array_impl.rs index f22739213..c2e93e755 100644 --- a/src/array_impl.rs +++ b/src/array_impl.rs @@ -1,4 +1,4 @@ -use crate::Itertools; +use crate::{size_hint, Itertools}; use std::iter::Fuse; /// An iterator over all contiguous windows of the input iterator, @@ -76,6 +76,19 @@ where }, } } + + fn size_hint(&self) -> (usize, Option) { + let inner_sh = self.iter.size_hint(); + if self.inner.is_none() { + if N == 0 { + size_hint::add_scalar(inner_sh, 1) + } else { + size_hint::sub_scalar(inner_sh, N - 1) + } + } else { + inner_sh + } + } } pub fn array_windows(iter: I) -> ArrayWindows @@ -89,6 +102,17 @@ where } } +macro_rules! array_windows_exact_size { + ($($n: literal),*) => { + $( + impl> ExactSizeIterator for ArrayWindows {} + )* + }; +} + +// cannot be implemented for `N == 0` since it increases the length +array_windows_exact_size!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); + /// An iterator over all windows, wrapping back to the first elements when the /// window would otherwise exceed the length of the iterator, producing arrays /// of a specific size. diff --git a/tests/quick.rs b/tests/quick.rs index b4129a305..f5978606a 100644 --- a/tests/quick.rs +++ b/tests/quick.rs @@ -1337,6 +1337,15 @@ quickcheck! { true } + fn array_windows_exact_size_1(a: Vec) -> bool { + exact_size(a.iter().array_windows::<1>()) + } + + fn array_windows_exact_size_4(a: Vec) -> bool { + exact_size(a.iter().array_windows::<4>()) + } + + fn equal_circular_array_windows_0(a: Vec) -> bool { let x = a.iter().map(|_| [&0u8; 0] ); let y = a.iter().circular_array_windows::<0>();