diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 1a2d8e57e8684..b866655bbd53d 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -301,6 +301,7 @@ use clone::Clone; use cmp; +use default::Default; use fmt; use iter_private::TrustedRandomAccess; use ops::FnMut; @@ -624,8 +625,7 @@ impl DoubleEndedIterator for Chain where pub struct Zip { a: A, b: B, - index: usize, - len: usize, + spec: <(A, B) as ZipImplData>::Data, } #[stable(feature = "rust1", since = "1.0.0")] @@ -667,6 +667,17 @@ trait ZipImpl { B: DoubleEndedIterator + ExactSizeIterator; } +// Zip specialization data members +#[doc(hidden)] +trait ZipImplData { + type Data: 'static + Clone + Default + fmt::Debug; +} + +#[doc(hidden)] +impl ZipImplData for T { + default type Data = (); +} + // General Zip impl #[doc(hidden)] impl ZipImpl for Zip @@ -677,8 +688,7 @@ impl ZipImpl for Zip Zip { a: a, b: b, - index: 0, // not used in general case - len: 0, + spec: Default::default(), // unused } } @@ -731,6 +741,20 @@ impl ZipImpl for Zip } } +#[doc(hidden)] +#[derive(Default, Debug, Clone)] +struct ZipImplFields { + index: usize, + len: usize, +} + +#[doc(hidden)] +impl ZipImplData for (A, B) + where A: TrustedRandomAccess, B: TrustedRandomAccess +{ + type Data = ZipImplFields; +} + #[doc(hidden)] impl ZipImpl for Zip where A: TrustedRandomAccess, B: TrustedRandomAccess @@ -740,16 +764,18 @@ impl ZipImpl for Zip Zip { a: a, b: b, - index: 0, - len: len, + spec: ZipImplFields { + index: 0, + len: len, + } } } #[inline] fn next(&mut self) -> Option<(A::Item, B::Item)> { - if self.index < self.len { - let i = self.index; - self.index += 1; + if self.spec.index < self.spec.len { + let i = self.spec.index; + self.spec.index += 1; unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) } @@ -760,7 +786,7 @@ impl ZipImpl for Zip #[inline] fn size_hint(&self) -> (usize, Option) { - let len = self.len - self.index; + let len = self.spec.len - self.spec.index; (len, Some(len)) } @@ -769,9 +795,9 @@ impl ZipImpl for Zip where A: DoubleEndedIterator + ExactSizeIterator, B: DoubleEndedIterator + ExactSizeIterator { - if self.index < self.len { - self.len -= 1; - let i = self.len; + if self.spec.index < self.spec.len { + self.spec.len -= 1; + let i = self.spec.len; unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) }