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:
parent
85cd49fc39
commit
5df05c6e22
@ -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)))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user