1
1
use alloc:: vec:: Vec ;
2
2
use std:: fmt;
3
- use std:: iter:: FusedIterator ;
3
+
4
+ // (base: 0) pow: 0
5
+ // iter indices items
6
+ // init S · N
7
+ // next(C) N 🗙 · [] -> []
8
+ // next(K) N · N -> None
9
+ // next(L) N · [] -> []
10
+
11
+ // (base: 2) pow: 0
12
+ // iter indices items
13
+ // init S · N
14
+ // next(C) N 🗙 · [] -> []
15
+ // next(K) N · N -> None
16
+ // next(L) N · [] -> []
17
+
18
+ // (base: 0) pow: 2
19
+ // iter indices items
20
+ // init S · N
21
+ // next(D) N! · N -> None
22
+ // next(B) N · N -> None
23
+ // next(B) N · N -> None
24
+
25
+ // (base: 1) pow: 1
26
+ // iter indices items
27
+ // init S · N
28
+ // next(D) S 0 a -> [a]
29
+ // next(E) N! 1 ! a -> None
30
+ // next(G) N 0 a -> [a]
31
+ // next(G) N 1 ! a -> None
32
+
33
+ // (base: 2) pow: 1
34
+ // iter indices items
35
+ // init S · N
36
+ // next(D) S 0 a -> [a]
37
+ // next(E) S 1 a b -> [b]
38
+ // next(E) N! 2 ! a b -> None
39
+ // next(G) N 0 a b -> [a]
40
+ // next(G) N 1 a b -> [b]
41
+ // next(G) N 2 ! a b -> None
42
+
43
+ // (base: 2) pow: 3
44
+ // iter indices items
45
+ // init S · N
46
+ // next(D) S 0 0 0 a -> [a, a, a]
47
+ // next(E) S 0 0 1 a b -> [a, a, b]
48
+ // next(E) N! 0 1 0 a b -> [a, b, a]
49
+ // next(G) N 0 1 1 a b -> [a, b, b]
50
+ // next(G) N 1 0 0 a b -> [b, a, a]
51
+ // next(G) N 1 0 1 a b -> [b, a, b]
52
+ // next(G) N 1 1 0 a b -> [b, b, a]
53
+ // next(G) N 1 1 1 a b -> [b, b, b]
54
+ // next(G) N 2 0 0 ! a b -> None
55
+ // next(G) N 0 0 0 a b -> [a, a, a]
4
56
5
57
/// An adaptor iterating through all the ordered `n`-length lists of items
6
58
/// yielded by the underlying iterator, including repetitions.
15
67
I :: Item : Clone ,
16
68
{
17
69
pow : usize ,
18
- iter : Option < I > , // Inner iterator. Forget once consumed after 'base' iterations.
19
- items : Vec < I :: Item > , // Fill from iter. Clear once adaptor is exhausted. Final length is 'base'.
20
- indices : Vec < usize > , // Indices just yielded. Clear once adaptor is exhausted. Length is 'pow'.
70
+ iter : Option < I > , // Inner iterator. Forget once consumed after 'base' iterations.
71
+ items : Option < Vec < I :: Item > > , // Fill from iter. Final length is 'base'.
72
+ // None means that collection has not started yet.
73
+ // Some(empty) means that collection would have started but pow = 0.
74
+
75
+ // Indices just yielded. Length is 'pow'.
76
+ // 0 0 .. 0 0 means that the first combination has been yielded.
77
+ // 0 0 .. 0 1 means that the second combination has been yielded.
78
+ // m m .. m m means that the last combination has just been yielded (m = base - 1).
79
+ // b 0 .. 0 0 means that 'None' has just been yielded (b = base).
80
+ // The latter is a special value marking the renewal of the iterator,
81
+ // which can cycle again through another full round, ad libitum.
82
+ indices : Vec < usize > ,
21
83
}
22
84
23
85
/// Create a new `CartesianPower` from an iterator of clonables.
29
91
CartesianPower {
30
92
pow,
31
93
iter : Some ( iter) ,
32
- items : Vec :: new ( ) ,
94
+ items : None ,
33
95
indices : Vec :: new ( ) ,
34
96
}
35
97
}
@@ -53,35 +115,63 @@ where
53
115
items,
54
116
indices,
55
117
} = self ;
56
- match ( * pow, iter, items. len ( ) ) {
57
- // Final stable state: underlying iterator and items forgotten.
58
- ( _, None , 0 ) => None ,
118
+ println ! (
119
+ "^{pow}: {indices:?}\t {}\t {:?}" ,
120
+ if iter. is_some( ) { 'S' } else { 'N' } ,
121
+ items. as_ref( ) . map( |v| v. len( ) )
122
+ ) ;
123
+ match ( * pow, iter, items) {
124
+ // BBBBBBBBBBBB
125
+ // Stable degenerated state: 0^pow with pow > 0;
126
+ ( _, None , None ) => None ,
59
127
128
+ // CCCCCCCCCCCC
60
129
// Degenerated 0th power iteration.
61
- ( 0 , Some ( _) , _) => {
62
- self . iter = None ; // Forget without even consuming.
63
- Some ( ( indices, items) )
130
+ ( 0 , Some ( _) , None ) => {
131
+ self . iter = None ; // Forget about underlying iteration immediately.
132
+ * items = Some ( Vec :: new ( ) ) ; // Raise this value as a boolean flag.
133
+ Some ( ( indices, & [ ] ) ) // Yield empty list.
64
134
}
65
135
66
- ( pow, Some ( it) , 0 ) => {
136
+ // KKKKKKKKKKKK
137
+ // Degenerated 0th power iteration, after the dummy item was collected.
138
+ // Use the Some<(empty)Vec> as a flag to alternate between yielding [] or None.
139
+ ( 0 , None , Some ( _) ) => {
140
+ * items = None ;
141
+ None
142
+ }
143
+ // LLLLLLLLLLLL
144
+ ( 0 , None , None ) => {
145
+ * items = Some ( Vec :: new ( ) ) ;
146
+ Some ( ( indices, & [ ] ) )
147
+ }
148
+
149
+ // DDDDDDDDDDDD
150
+ // First iteration.
151
+ ( pow, Some ( it) , None ) => {
67
152
// Check whether there is at least one element in the iterator.
68
153
if let Some ( first) = it. next ( ) {
69
154
// Allocate buffer to hold items about to be yielded.
70
- items. reserve_exact ( it. size_hint ( ) . 0 ) ;
71
- items. push ( first) ;
155
+ * items = Some ( {
156
+ let mut v = Vec :: with_capacity ( it. size_hint ( ) . 0 ) ;
157
+ v. push ( first) ;
158
+ v
159
+ } ) ;
72
160
// Same for indices to be yielded.
73
161
indices. reserve_exact ( pow) ;
74
162
for _ in 0 ..pow {
75
163
indices. push ( 0 ) ;
76
164
}
77
- return Some ( ( indices, items) ) ;
165
+ Some ( ( indices, & items. unwrap ( ) ) ) // HERE: can I rebase to get a smarter borrowck?
166
+ } else {
167
+ // Degenerated iteration over an empty set, yet with non-null power.
168
+ self . iter = None ;
169
+ None
78
170
}
79
- // Degenerated iteration over an empty set, yet with non-null power.
80
- self . iter = None ;
81
- None
82
171
}
83
172
84
- ( pow, Some ( it) , base) => {
173
+ // EEEEEEEEEEEE
174
+ ( pow, Some ( it) , Some ( items) ) => {
85
175
// We are still unsure whether all items have been collected.
86
176
// As a consequence, 'base' is still uncertain,
87
177
// but then we know that indices haven't started wrapping around yet.
@@ -91,32 +181,55 @@ where
91
181
return Some ( ( indices, items) ) ;
92
182
}
93
183
94
- // All items have just been collected .
95
- self . iter = None ;
96
- if base == 1 || pow == 1 {
184
+ // The item collected on previous call was the last one .
185
+ self . iter = None ; // Forget about the underlying iterator.
186
+ if pow == 1 {
97
187
// End of iteration.
98
- items. clear ( ) ;
99
- indices. clear ( ) ;
188
+ let base = items. len ( ) ;
189
+ indices[ 0 ] = base ; // Mark to cycle again on next iteration.
100
190
return None ;
101
191
}
102
192
103
193
// First wrap around.
104
194
indices[ pow - 1 ] = 0 ;
105
- indices[ pow - 2 ] + = 1 ;
195
+ indices[ pow - 2 ] = 1 ;
106
196
Some ( ( indices, items) )
107
197
}
108
198
109
- ( _, None , b) => {
199
+ // // FFFFFFFFFFFF
200
+ // (_, None, 1) => {
201
+ // // Flip the only indice to keep cycling.
202
+ // let ind = &mut indices[0];
203
+ // if *ind == 1 {
204
+ // *ind = 0;
205
+ // Some((indices, items))
206
+ // } else {
207
+ // *ind = 1;
208
+ // None
209
+ // }
210
+ // }
211
+
212
+ // GGGGGGGGGGGG
213
+ ( _, None , Some ( items) ) => {
214
+ let base = items. len ( ) ;
215
+ if indices[ 0 ] == base {
216
+ // Special marker that iteration can start over for a new round.
217
+ indices[ 0 ] = 0 ;
218
+ return Some ( ( indices, items) ) ;
219
+ }
110
220
// Keep yielding items list, incrementing indices rightmost first.
111
221
for index in indices. iter_mut ( ) . rev ( ) {
112
222
* index += 1 ;
113
- if * index < b {
223
+ if * index < base {
114
224
return Some ( ( indices, items) ) ;
115
225
}
116
226
* index = 0 ; // Wrap and increment left.
117
227
}
118
- items. clear ( ) ;
119
- indices. clear ( ) ;
228
+ // Iteration is over.
229
+ // But don't clear the collected items,
230
+ // and mark a special index value to not fuse the iterator
231
+ // but make it possibly cycle through all again.
232
+ indices[ 0 ] = base;
120
233
None
121
234
}
122
235
}
@@ -187,13 +300,6 @@ where
187
300
}
188
301
}
189
302
190
- impl < I > FusedIterator for CartesianPower < I >
191
- where
192
- I : Iterator ,
193
- I :: Item : Clone ,
194
- {
195
- }
196
-
197
303
#[ cfg( test) ]
198
304
mod tests {
199
305
//! Use chars and string to ease testing of every yielded iterator values.
@@ -202,37 +308,46 @@ mod tests {
202
308
use crate :: Itertools ;
203
309
use core:: str:: Chars ;
204
310
205
- fn check_fused ( mut exhausted_it : CartesianPower < Chars > , context : String ) {
206
- for i in 0 ..100 {
207
- let act = exhausted_it. next ( ) ;
208
- assert ! (
209
- act. is_none( ) ,
210
- "Iteration {} after expected exhaustion of {} \
211
- yielded {:?} instead of None. ",
212
- i,
213
- context,
214
- act,
215
- ) ;
216
- }
217
- }
218
-
219
311
#[ test]
220
312
fn basic ( ) {
221
313
fn check ( origin : & str , pow : usize , expected : & [ & str ] ) {
222
- let mut it = origin. chars ( ) . cartesian_power ( pow) ;
223
- let mut i = 0 ;
224
- for exp in expected {
225
- let act = it. next ( ) ;
226
- if act != Some ( exp. chars ( ) . collect ( ) ) {
227
- panic ! (
228
- "Failed iteration {} for {:?}^{}. \
229
- Expected {:?}, got {:?} instead.",
230
- i, origin, pow, exp, act,
231
- ) ;
314
+ println ! ( "================== ({origin:?}^{pow})" ) ;
315
+ let mut it_act = origin. chars ( ) . cartesian_power ( pow) ;
316
+ // Check thrice that it's cycling.
317
+ for r in 1 ..=3 {
318
+ println ! ( "- - {r} - - - - - -" ) ;
319
+ let mut it_exp = expected. iter ( ) ;
320
+ let mut i = 0 ;
321
+ loop {
322
+ match ( it_exp. next ( ) , it_act. next ( ) ) {
323
+ ( Some ( exp) , Some ( act) ) => {
324
+ if act != exp. chars ( ) . collect :: < Vec < _ > > ( ) {
325
+ panic ! (
326
+ "Failed iteration {} (repetition {}) for {:?}^{}. \
327
+ Expected {:?}, got {:?} instead.",
328
+ i, r, origin, pow, exp, act,
329
+ ) ;
330
+ }
331
+ i += 1 ;
332
+ }
333
+ ( None , Some ( act) ) => {
334
+ panic ! (
335
+ "Failed iteration {} (repetition {}) for {:?}^{}. \
336
+ Expected None, got {:?} instead.",
337
+ i, r, origin, pow, act,
338
+ ) ;
339
+ }
340
+ ( Some ( exp) , None ) => {
341
+ panic ! (
342
+ "Failed iteration {} (repetition {}) for {:?}^{}. \
343
+ Expected {:?}, got None instead.",
344
+ i, r, origin, pow, exp,
345
+ ) ;
346
+ }
347
+ ( None , None ) => break ,
348
+ }
232
349
}
233
- i += 1 ;
234
350
}
235
- check_fused ( it, format ! ( "iteration {} or {:?}^{}" , i, origin, pow) ) ;
236
351
}
237
352
238
353
// Empty underlying iterator.
@@ -281,38 +396,28 @@ mod tests {
281
396
fn check ( origin : & str , pow : usize , expected : & [ ( usize , Option < & str > ) ] ) {
282
397
let mut it = origin. chars ( ) . cartesian_power ( pow) ;
283
398
let mut total_n = Vec :: new ( ) ;
284
- for & ( n, exp) in expected {
285
- let act = it. nth ( n) ;
286
- total_n. push ( n) ;
287
- if act != exp. map ( |s| s. chars ( ) . collect :: < Vec < _ > > ( ) ) {
288
- panic ! (
289
- "Failed nth({}) iteration for {:?}^{}. \
290
- Expected {:?}, got {:?} instead.",
291
- total_n
292
- . iter( )
293
- . map( ToString :: to_string)
294
- . collect:: <Vec <_>>( )
295
- . join( ", " ) ,
296
- origin,
297
- pow,
298
- exp,
299
- act,
300
- ) ;
399
+ for r in 1 ..=3 {
400
+ for & ( n, exp) in expected {
401
+ let act = it. nth ( n) ;
402
+ total_n. push ( n) ;
403
+ if act != exp. map ( |s| s. chars ( ) . collect :: < Vec < _ > > ( ) ) {
404
+ panic ! (
405
+ "Failed nth({}) iteration (repetition {}) for {:?}^{}. \
406
+ Expected {:?}, got {:?} instead.",
407
+ total_n
408
+ . iter( )
409
+ . map( ToString :: to_string)
410
+ . collect:: <Vec <_>>( )
411
+ . join( ", " ) ,
412
+ r,
413
+ origin,
414
+ pow,
415
+ exp,
416
+ act
417
+ ) ;
418
+ }
301
419
}
302
420
}
303
- check_fused (
304
- it,
305
- format ! (
306
- "nth({}) iteration of {:?}^{}" ,
307
- total_n
308
- . iter( )
309
- . map( ToString :: to_string)
310
- . collect:: <Vec <_>>( )
311
- . join( ", " ) ,
312
- origin,
313
- pow
314
- ) ,
315
- ) ;
316
421
}
317
422
318
423
// HERE: make it work with the new implementation.
0 commit comments