@@ -373,19 +373,24 @@ pub enum Power<I>
373
373
where
374
374
I : Iterator ,
375
375
{
376
- /// The adaptor is empty if either:
377
- /// - pow is 0
378
- /// - the original iterator is empty
379
- /// - the adaptor is exhausted
376
+ /// The adaptor is 'Empty' if either:
377
+ /// - The original iterator is empty.
378
+ /// - The adaptor is exhausted.
380
379
Empty ,
381
- /// Otherwise, there will be items yielded.
380
+ /// The adaptor is 'Degenerated' if the given pow == 0.
381
+ /// In this case, it yields 1 empty item before switching to Empty itself.
382
+ /// This ensures that cartesian_power(it, n).count() == it.count().pow(n) for all n.
383
+ /// In the case it.is_empty() && n == 0, we choose convention 0^0=1.
384
+ Degenerated ,
385
+ /// In any other case, there will be non-empty items yielded.
382
386
Filled {
383
387
/// Copy of the original iterator, never consumed.
384
388
original : I ,
385
- /// Clones of the original iterator, scrolled at various speeds
389
+ /// Clones of the original iterator,
390
+ /// scrolled at various speeds from left to right
386
391
/// and regularly replaced by fresh clones once exhausted.
387
392
clones : Vec < I > ,
388
- /// Current state of the iterator: the next item to be yielded.
393
+ /// Current state of the iterator: the next non-empty item to be yielded.
389
394
state : Vec < I :: Item > ,
390
395
} ,
391
396
}
@@ -399,14 +404,13 @@ where
399
404
I :: Item : Clone ,
400
405
{
401
406
match pow {
402
- // Trivial case.
403
- 0 => Power :: Empty ,
407
+ 0 => Power :: Degenerated ,
404
408
pow => {
405
409
// Test one clone first to determine whether
406
410
// some values are actually yielded by the given iterator.
407
411
let mut first_clone = it. clone ( ) ;
408
412
match first_clone. next ( ) {
409
- // New trivial case: the given iterator is empty.
413
+ // No item will be yielded if the iterator is empty.
410
414
None => Power :: Empty ,
411
415
Some ( first_state) => {
412
416
// Produce other clones until we have `pow` of them.
@@ -471,13 +475,19 @@ where
471
475
}
472
476
Some ( res)
473
477
}
474
- // Check trivial case last as it should be less frequent .
478
+ // Check les frequent cases last .
475
479
Power :: Empty => None ,
480
+ Power :: Degenerated => {
481
+ // Yield One empty item and get exhausted.
482
+ * self = Power :: Empty ;
483
+ Some ( Vec :: new ( ) )
484
+ }
476
485
}
477
486
}
478
487
479
488
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
480
489
match self {
490
+ Power :: Degenerated => ( 1 , Some ( 1 ) ) ,
481
491
Power :: Empty => ( 0 , Some ( 0 ) ) ,
482
492
Power :: Filled {
483
493
original, clones, ..
0 commit comments