13
13
I : Iterator ,
14
14
I :: Item : Clone ,
15
15
{
16
- pow : usize ,
16
+ pow : u32 ,
17
17
iter : Option < I > , // Inner iterator. Forget once consumed after 'base' iterations.
18
18
items : Option < Vec < I :: Item > > , // Fill from iter. Final length is 'base'.
19
19
// None means that collection has not started yet.
30
30
}
31
31
32
32
/// Create a new `CartesianPower` from an iterator of clonables.
33
- pub fn cartesian_power < I > ( iter : I , pow : usize ) -> CartesianPower < I >
33
+ pub fn cartesian_power < I > ( iter : I , pow : u32 ) -> CartesianPower < I >
34
34
where
35
35
I : Iterator ,
36
36
I :: Item : Clone ,
@@ -62,14 +62,11 @@ where
62
62
items,
63
63
indices,
64
64
} = self ;
65
- println ! (
66
- "^{pow}: {} {indices:?}\t \t {:?}" ,
67
- if iter. is_some( ) { 'S' } else { 'N' } ,
68
- items. as_ref( ) . map( Vec :: len)
69
- ) ;
65
+
66
+ let pow = * pow as usize ;
70
67
71
68
// (weird 'items @' bindings circumvent NLL limitations, unneeded with polonius)
72
- match ( * pow, iter, & mut * items) {
69
+ match ( pow, iter, & mut * items) {
73
70
// First iteration with degenerated 0th power.
74
71
( 0 , Some ( _) , items @ None ) => {
75
72
self . iter = None ; // Forget about underlying iteration immediately.
@@ -197,7 +194,9 @@ where
197
194
indices,
198
195
} = self ;
199
196
200
- match ( * pow, iter, & mut * items, n) {
197
+ let pow = * pow as usize ;
198
+
199
+ match ( pow, iter, & mut * items, n) {
201
200
// First iteration with degenerated 0th power.
202
201
( 0 , Some ( _) , items @ None , 0 ) => {
203
202
// Same as .next().
@@ -213,9 +212,7 @@ where
213
212
214
213
// Subsequent degenerated 0th power iteration.
215
214
// Same as `.next()`.
216
- ( 0 , None , items @ None , 0 ) => {
217
- Some ( ( indices, items. insert ( Vec :: new ( ) ) ) )
218
- }
215
+ ( 0 , None , items @ None , 0 ) => Some ( ( indices, items. insert ( Vec :: new ( ) ) ) ) ,
219
216
// Saturate.
220
217
( 0 , None , items, _) => {
221
218
* items = None ;
@@ -264,9 +261,7 @@ where
264
261
}
265
262
266
263
// Stable iteration in the degenerated case 'base = 0'.
267
- ( _, None , None , _) => {
268
- None
269
- }
264
+ ( _, None , None , _) => None ,
270
265
271
266
// Subsequent iteration in the general case.
272
267
// Again, immediate saturation is an option.
@@ -348,7 +343,77 @@ where
348
343
}
349
344
350
345
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
351
- todo ! ( )
346
+ let Self {
347
+ pow,
348
+ iter,
349
+ items,
350
+ indices,
351
+ } = self ;
352
+
353
+ // The following case analysis matches implementation of `.next()`.
354
+ match ( * pow, iter, items) {
355
+ // First iteration with degenerated 0th power.
356
+ ( 0 , Some ( _) , None ) => ( 1 , Some ( 1 ) ) ,
357
+
358
+ // Subsequent degenerated 0th power iteration.
359
+ // Alternating for cycling behaviour.
360
+ ( 0 , None , Some ( _) ) => ( 0 , Some ( 0 ) ) ,
361
+ ( 0 , None , None ) => ( 1 , Some ( 1 ) ) ,
362
+
363
+ // First iteration in the general case.
364
+ ( pow, Some ( it) , None ) => {
365
+ let ( a, b) = it. size_hint ( ) ;
366
+ (
367
+ a. checked_pow ( pow) . unwrap_or ( usize:: MAX ) ,
368
+ b. map ( |b| b. checked_pow ( pow) ) . flatten ( ) ,
369
+ )
370
+ }
371
+
372
+ // Stable iteration in the degenerated case 'base = 0'.
373
+ ( _, None , None ) => ( 0 , Some ( 0 ) ) ,
374
+
375
+ // Subsequent iteration in the general case.
376
+ ( pow, Some ( it) , Some ( items) ) => {
377
+ let already = items. len ( ) ;
378
+ let minus_already = |total| total - already;
379
+ let ( a, b) = it. size_hint ( ) ;
380
+ (
381
+ ( a + already)
382
+ . checked_pow ( pow)
383
+ . map ( minus_already)
384
+ . unwrap_or ( usize:: MAX ) ,
385
+ b. map ( |b| ( b + already) . checked_pow ( pow) . map ( minus_already) )
386
+ . flatten ( ) ,
387
+ )
388
+ }
389
+
390
+ // Subsequent iteration in the general case after all items have been collected.
391
+ ( pow, None , Some ( items) ) => {
392
+ let base = items. len ( ) ;
393
+ if indices[ 0 ] == base {
394
+ // Fresh re-start.
395
+ let r = base. checked_pow ( pow) ;
396
+ return ( r. unwrap_or ( usize:: MAX ) , r) ;
397
+ }
398
+ // Count what's left from current indices.
399
+ // This is subtracting the current iteration number base^pow,
400
+ // using the complement method.
401
+ let calc = || -> Option < usize > {
402
+ // (closure-wrap to ease interruption on overflow with ?-operator)
403
+ let comp = base - 1 ;
404
+ let mut r = 1usize ;
405
+ for ( & i, rank) in indices. iter ( ) . rev ( ) . zip ( 0u32 ..) {
406
+ let increment = ( comp - i) . checked_pow ( rank) ?;
407
+ r = r. checked_add ( increment) ?;
408
+ }
409
+ Some ( r)
410
+ } ;
411
+ let Some ( r) = calc ( ) else {
412
+ return ( usize:: MAX , None ) ;
413
+ } ;
414
+ ( r, Some ( r) )
415
+ }
416
+ }
352
417
}
353
418
354
419
fn count ( self ) -> usize {
@@ -378,19 +443,19 @@ where
378
443
}
379
444
}
380
445
446
+ /// Use chars and string to ease testing of every yielded iterator values.
381
447
#[ cfg( test) ]
382
448
mod tests {
383
- //! Use chars and string to ease testing of every yielded iterator values.
384
449
385
- use super :: CartesianPower ;
386
450
use crate :: Itertools ;
387
- use core:: str:: Chars ;
388
451
389
452
#[ test]
390
453
fn basic ( ) {
391
- fn check ( origin : & str , pow : usize , expected : & [ & str ] ) {
454
+ fn check ( origin : & str , pow : u32 , expected : & [ & str ] ) {
392
455
println ! ( "================== ({origin:?}^{pow})" ) ;
393
456
let mut it_act = origin. chars ( ) . cartesian_power ( pow) ;
457
+ // Check size_hint on the fly.
458
+ let e_hint = expected. len ( ) ; // HERE: do.
394
459
// Check thrice that it's cycling.
395
460
for r in 1 ..=3 {
396
461
println ! ( "- - {r} - - - - - -" ) ;
@@ -473,7 +538,7 @@ mod tests {
473
538
474
539
#[ test]
475
540
fn nth ( ) {
476
- fn check ( origin : & str , pow : usize , expected : & [ ( usize , Option < & str > ) ] ) {
541
+ fn check ( origin : & str , pow : u32 , expected : & [ ( usize , Option < & str > ) ] ) {
477
542
println ! ( "================== ({origin:?}^{pow})" ) ;
478
543
let mut it = origin. chars ( ) . cartesian_power ( pow) ;
479
544
let mut total_n = Vec :: new ( ) ;
0 commit comments