Skip to content

Commit ce7a1ee

Browse files
committed
Specialize GenericSequence and zip
1 parent c16b587 commit ce7a1ee

File tree

3 files changed

+60
-16
lines changed

3 files changed

+60
-16
lines changed

src/functional.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ pub unsafe trait FunctionalSequence<T>: GenericSequence<T> {
5050
fn zip<B, Rhs, U, F>(self, rhs: Rhs, mut f: F) -> MappedSequence<Self, T, U>
5151
where
5252
Self: MappedGenericSequence<T, U>,
53+
Rhs: MappedGenericSequence<B, U, Mapped=MappedSequence<Self, T, U>>,
5354
Self::Length: ArrayLength<B> + ArrayLength<U>,
54-
Rhs: GenericSequence<B>,
55+
Rhs: GenericSequence<B, Length=Self::Length>,
5556
F: FnMut(SequenceItem<Self>, SequenceItem<Rhs>) -> U,
5657
{
5758
FromIterator::from_iter(self.into_iter().zip(rhs.into_iter()).map(|(l, r)| f(l, r) ))

src/lib.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ fn from_iter_length_fail(length: usize, expected: usize) -> ! {
277277
unsafe impl<T, N> GenericSequence<T> for GenericArray<T, N>
278278
where
279279
N: ArrayLength<T>,
280+
Self: IntoIterator<Item=T>,
280281
{
281282
type Length = N;
282283
type Sequence = Self;
@@ -297,6 +298,32 @@ where
297298

298299
destination.into_inner()
299300
}
301+
302+
fn inverted_zip<B, U, F>(self, lhs: GenericArray<B, Self::Length>, mut f: F) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
303+
where
304+
GenericArray<B, Self::Length>:
305+
GenericSequence<B, Length=Self::Length> +
306+
MappedGenericSequence<B, U>,
307+
Self: MappedGenericSequence<T, U>,
308+
Self::Length: ArrayLength<B> + ArrayLength<U>,
309+
F: FnMut(B, Self::Item) -> U
310+
{
311+
let mut left = ArrayConsumer::new(lhs);
312+
let mut right = ArrayConsumer::new(self);
313+
314+
let ArrayConsumer { array: ref left_array, position: ref mut left_position } = left;
315+
let ArrayConsumer { array: ref right_array, position: ref mut right_position } = right;
316+
317+
FromIterator::from_iter(left_array.iter().zip(right_array.iter()).map(|(l, r)| {
318+
let left_value = unsafe { ptr::read(l) };
319+
let right_value = unsafe { ptr::read(r) };
320+
321+
*left_position += 1;
322+
*right_position += 1;
323+
324+
f(left_value, right_value)
325+
}))
326+
}
300327
}
301328

302329
unsafe impl<T, U, N> MappedGenericSequence<T, U> for GenericArray<T, N>
@@ -310,7 +337,7 @@ where
310337
unsafe impl<T, N> FunctionalSequence<T> for GenericArray<T, N>
311338
where
312339
N: ArrayLength<T>,
313-
Self: GenericSequence<T, Item=T>
340+
Self: GenericSequence<T, Item=T, Length=N>
314341
{
315342
fn map<U, F>(self, mut f: F) -> MappedSequence<Self, T, U>
316343
where
@@ -331,24 +358,16 @@ where
331358
}))
332359
}
333360

334-
fn zip<B, Rhs, U, F>(self, rhs: Rhs, mut f: F) -> MappedSequence<Self, T, U>
361+
#[inline]
362+
fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U>
335363
where
336364
Self: MappedGenericSequence<T, U>,
365+
Rhs: MappedGenericSequence<B, U, Mapped=MappedSequence<Self, T, U>>,
337366
Self::Length: ArrayLength<B> + ArrayLength<U>,
338-
Rhs: GenericSequence<B>,
367+
Rhs: GenericSequence<B, Length=Self::Length>,
339368
F: FnMut(T, SequenceItem<Rhs>) -> U,
340369
{
341-
let mut left = ArrayConsumer::new(self);
342-
343-
let ArrayConsumer { ref array, ref mut position } = left;
344-
345-
FromIterator::from_iter(array.iter().zip(rhs.into_iter()).map(|(l, right_value)| {
346-
let left_value = unsafe { ptr::read(l) };
347-
348-
*position += 1;
349-
350-
f(left_value, right_value)
351-
}))
370+
rhs.inverted_zip(self, f)
352371
}
353372
}
354373

@@ -489,7 +508,7 @@ mod test {
489508
let a = black_box(arr![i32; 1, 3, 5, 7]);
490509
let b = black_box(arr![i32; 2, 4, 6, 8]);
491510

492-
let c = a.zip(&b, |l: i32, r: &i32| l + r);
511+
let c = a.zip(b, |l, r| l + r);
493512

494513
assert_eq!(c, arr![i32; 3, 7, 11, 15]);
495514
}

src/sequence.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,30 @@ pub unsafe trait GenericSequence<T>: Sized + IntoIterator {
2121
/// any already initialized elements will be dropped.
2222
fn generate<F>(f: F) -> Self::Sequence
2323
where F: FnMut(usize) -> T;
24+
25+
#[doc(hidden)]
26+
fn inverted_zip<B, U, F>(self, lhs: GenericArray<B, Self::Length>, mut f: F) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
27+
where
28+
GenericArray<B, Self::Length>:
29+
GenericSequence<B, Length=Self::Length> +
30+
MappedGenericSequence<B, U>,
31+
Self: MappedGenericSequence<T, U>,
32+
Self::Length: ArrayLength<B> + ArrayLength<U>,
33+
F: FnMut(B, Self::Item) -> U
34+
{
35+
36+
let mut left = ArrayConsumer::new(lhs);
37+
38+
let ArrayConsumer { array: ref left_array, position: ref mut left_position } = left;
39+
40+
FromIterator::from_iter(left_array.iter().zip(self.into_iter()).map(|(l, right_value)| {
41+
let left_value = unsafe { ptr::read(l) };
42+
43+
*left_position += 1;
44+
45+
f(left_value, right_value)
46+
}))
47+
}
2448
}
2549

2650
/// Accessor type for iteration items from `GenericSequence`

0 commit comments

Comments
 (0)