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