@@ -102,10 +102,13 @@ where
102
102
type Item = Vec < I :: Item > ;
103
103
104
104
fn next ( & mut self ) -> Option < Self :: Item > {
105
+ // This fuses the iterator.
105
106
let inner = self . 0 . as_mut ( ) ?;
106
107
match & mut inner. cur {
107
108
Some ( values) => {
108
109
debug_assert ! ( !inner. iters. is_empty( ) ) ;
110
+ // Find (from the right) a non-finished iterator and
111
+ // reset the finished ones encountered.
109
112
for ( iter, item) in inner. iters . iter_mut ( ) . zip ( values. iter_mut ( ) ) . rev ( ) {
110
113
if let Some ( new) = iter. iter . next ( ) {
111
114
* item = new;
@@ -136,9 +139,12 @@ where
136
139
137
140
fn count ( self ) -> usize {
138
141
match self . 0 {
139
- None => 0 ,
142
+ None => 0 , // The cartesian product has ended.
140
143
Some ( MultiProductInner { iters, cur } ) => {
141
144
if cur. is_none ( ) {
145
+ // The iterator is fresh so the count is the product of the length of each iterator:
146
+ // - If one of them is empty, stop counting.
147
+ // - Less `count()` calls than the general case.
142
148
iters
143
149
. into_iter ( )
144
150
. map ( |iter| iter. iter_orig . count ( ) )
@@ -151,6 +157,7 @@ where
151
157
} )
152
158
. unwrap_or_default ( )
153
159
} else {
160
+ // The general case.
154
161
iters. into_iter ( ) . fold ( 0 , |mut acc, iter| {
155
162
if acc != 0 {
156
163
acc *= iter. iter_orig . count ( ) ;
@@ -164,7 +171,7 @@ where
164
171
165
172
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
166
173
match & self . 0 {
167
- None => ( 0 , Some ( 0 ) ) ,
174
+ None => ( 0 , Some ( 0 ) ) , // The cartesian product has ended.
168
175
Some ( MultiProductInner { iters, cur } ) => {
169
176
if cur. is_none ( ) {
170
177
iters
@@ -186,13 +193,15 @@ where
186
193
187
194
fn last ( self ) -> Option < Self :: Item > {
188
195
let MultiProductInner { iters, cur } = self . 0 ?;
196
+ // Collect the last item of each iterator of the product.
189
197
if let Some ( values) = cur {
190
198
let mut count = iters. len ( ) ;
191
199
let last = iters
192
200
. into_iter ( )
193
201
. zip ( values)
194
202
. map ( |( i, value) | {
195
203
i. iter . last ( ) . unwrap_or_else ( || {
204
+ // The iterator is empty, use its current `value`.
196
205
count -= 1 ;
197
206
value
198
207
} )
0 commit comments