1
1
#![ cfg( feature = "use_std" ) ]
2
2
3
+ use std:: iter:: FromIterator ;
4
+ use std:: marker:: PhantomData ;
3
5
use size_hint;
4
- use Itertools ;
5
6
6
7
#[ derive( Clone ) ]
7
8
/// An iterator adaptor that iterates over the cartesian product of
8
9
/// multiple iterators of type `I`.
9
10
///
10
- /// An iterator element type is `Vec<I>`.
11
+ /// An iterator element type is `T<I>`, which defaults to ` Vec<I>`.
11
12
///
12
13
/// See [`.multi_cartesian_product()`](../trait.Itertools.html#method.multi_cartesian_product)
13
14
/// for more information.
14
15
#[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
15
- pub struct MultiProduct < I > ( Vec < MultiProductIter < I > > )
16
+ pub struct MultiProduct < I , T = Vec < < I as Iterator > :: Item > > ( Vec < MultiProductIter < I > > , PhantomData < T > )
16
17
where I : Iterator + Clone ,
17
- I :: Item : Clone ;
18
+ I :: Item : Clone ,
19
+ T : FromIterator < I :: Item > ;
18
20
19
21
/// Create a new cartesian product iterator over an arbitrary number
20
22
/// of iterators of the same type.
21
23
///
22
- /// Iterator element is of type `Vec <H::Item::Item>`.
23
- pub fn multi_cartesian_product < H > ( iters : H ) -> MultiProduct < <H :: Item as IntoIterator >:: IntoIter >
24
+ /// Iterator element is of type `T <H::Item::Item>`.
25
+ pub fn multi_cartesian_product < H , T > ( iters : H ) -> MultiProduct < <H :: Item as IntoIterator >:: IntoIter , T >
24
26
where H : Iterator ,
25
27
H :: Item : IntoIterator ,
26
28
<H :: Item as IntoIterator >:: IntoIter : Clone ,
27
- <H :: Item as IntoIterator >:: Item : Clone
29
+ <H :: Item as IntoIterator >:: Item : Clone ,
30
+ T : FromIterator < <H :: Item as IntoIterator >:: Item >
28
31
{
29
- MultiProduct ( iters. map ( |i| MultiProductIter :: new ( i. into_iter ( ) ) ) . collect ( ) )
32
+ MultiProduct ( iters. map ( |i| MultiProductIter :: new ( i. into_iter ( ) ) ) . collect ( ) , PhantomData )
30
33
}
31
34
32
35
#[ derive( Clone , Debug ) ]
@@ -47,9 +50,10 @@ enum MultiProductIterState {
47
50
MidIter { on_first_iter : bool } ,
48
51
}
49
52
50
- impl < I > MultiProduct < I >
53
+ impl < I , T > MultiProduct < I , T >
51
54
where I : Iterator + Clone ,
52
- I :: Item : Clone
55
+ I :: Item : Clone ,
56
+ T : FromIterator < I :: Item >
53
57
{
54
58
/// Iterates the rightmost iterator, then recursively iterates iterators
55
59
/// to the left if necessary.
@@ -77,7 +81,7 @@ impl<I> MultiProduct<I>
77
81
78
82
if last. in_progress ( ) {
79
83
true
80
- } else if MultiProduct :: iterate_last ( rest, state) {
84
+ } else if Self :: iterate_last ( rest, state) {
81
85
last. reset ( ) ;
82
86
last. iterate ( ) ;
83
87
// If iterator is None twice consecutively, then iterator is
@@ -97,7 +101,7 @@ impl<I> MultiProduct<I>
97
101
}
98
102
99
103
/// Returns the unwrapped value of the next iteration.
100
- fn curr_iterator ( & self ) -> Vec < I :: Item > {
104
+ fn curr_iterator ( & self ) -> T {
101
105
self . 0 . iter ( ) . map ( |multi_iter| {
102
106
multi_iter. cur . clone ( ) . unwrap ( )
103
107
} ) . collect ( )
@@ -143,14 +147,15 @@ impl<I> MultiProductIter<I>
143
147
}
144
148
}
145
149
146
- impl < I > Iterator for MultiProduct < I >
150
+ impl < I , T > Iterator for MultiProduct < I , T >
147
151
where I : Iterator + Clone ,
148
- I :: Item : Clone
152
+ I :: Item : Clone ,
153
+ T : FromIterator < I :: Item >
149
154
{
150
- type Item = Vec < I :: Item > ;
155
+ type Item = T ;
151
156
152
157
fn next ( & mut self ) -> Option < Self :: Item > {
153
- if MultiProduct :: iterate_last (
158
+ if Self :: iterate_last (
154
159
& mut self . 0 ,
155
160
MultiProductIterState :: StartOfIter
156
161
) {
@@ -204,17 +209,8 @@ impl<I> Iterator for MultiProduct<I>
204
209
}
205
210
206
211
fn last ( self ) -> Option < Self :: Item > {
207
- let iter_count = self . 0 . len ( ) ;
208
-
209
- let lasts: Self :: Item = self . 0 . into_iter ( )
212
+ self . 0 . into_iter ( )
210
213
. map ( |multi_iter| multi_iter. iter . last ( ) )
211
- . while_some ( )
212
- . collect ( ) ;
213
-
214
- if lasts. len ( ) == iter_count {
215
- Some ( lasts)
216
- } else {
217
- None
218
- }
214
+ . collect ( )
219
215
}
220
216
}
0 commit comments