specialize zip: Use associated type for specialized zip struct data

The associated type must be 'static to avoid dropck related errors.
This commit is contained in:
Ulrik Sverdrup 2016-04-22 18:47:42 +02:00
parent 85cd49fc39
commit 5df05c6e22

View File

@ -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<A, B> DoubleEndedIterator for Chain<A, B> where
pub struct Zip<A, B> {
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<A, B> {
B: DoubleEndedIterator + ExactSizeIterator;
}
// Zip specialization data members
#[doc(hidden)]
trait ZipImplData {
type Data: 'static + Clone + Default + fmt::Debug;
}
#[doc(hidden)]
impl<T> ZipImplData for T {
default type Data = ();
}
// General Zip impl
#[doc(hidden)]
impl<A, B> ZipImpl<A, B> for Zip<A, B>
@ -677,8 +688,7 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
Zip {
a: a,
b: b,
index: 0, // not used in general case
len: 0,
spec: Default::default(), // unused
}
}
@ -731,6 +741,20 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
}
}
#[doc(hidden)]
#[derive(Default, Debug, Clone)]
struct ZipImplFields {
index: usize,
len: usize,
}
#[doc(hidden)]
impl<A, B> ZipImplData for (A, B)
where A: TrustedRandomAccess, B: TrustedRandomAccess
{
type Data = ZipImplFields;
}
#[doc(hidden)]
impl<A, B> ZipImpl<A, B> for Zip<A, B>
where A: TrustedRandomAccess, B: TrustedRandomAccess
@ -740,16 +764,18 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
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<A, B> ZipImpl<A, B> for Zip<A, B>
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len - self.index;
let len = self.spec.len - self.spec.index;
(len, Some(len))
}
@ -769,9 +795,9 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
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)))
}