1
1
use alloc:: vec:: Vec ;
2
2
use std:: fmt;
3
- use std:: iter:: FusedIterator ;
3
+
4
+ // (base: 0) pow: 0
5
+ // indices iter items
6
+ // init · S ·
7
+ // next(C) N 🗙 dot // HERE should not behave the same as right below.
8
+
9
+ // (base: 2) pow: 0
10
+ // indices iter items
11
+ // init · S ·
12
+ // next(C) · N 🗙 · -> None
13
+ // next(C) · N · -> None
14
+
15
+ // (base: 1) pow: 1
16
+ // indices iter items
17
+ // init · S ·
18
+ // next(D) 0 S a -> [a]
19
+ // next(E) 1 ! N! a -> None
20
+ // next(G) 0 N a -> [a]
21
+ // next(G) 1 ! N a -> None
22
+
23
+ // (base: 2) pow: 1
24
+ // indices iter items
25
+ // init · S ·
26
+ // next(D) 0 S a -> [a]
27
+ // next(E) 1 S a b -> [b]
28
+ // next(E) 2 ! N! a b -> None
29
+ // next(G) 0 N a b -> [a]
30
+ // next(G) 1 N a b -> [b]
31
+ // next(G) 2 ! N a b -> None
32
+
33
+ // (base: 2) pow: 3
34
+ // indices iter items
35
+ // init · S ·
36
+ // next(D) 0 0 0 S a -> [a, a, a]
37
+ // next(E) 0 0 1 S a b -> [a, a, b]
38
+ // next(E) 0 1 0 N! a b -> [a, b, a]
39
+ // next(G) 0 1 1 N a b -> [a, b, b]
40
+ // next(G) 1 0 0 N a b -> [b, a, a]
41
+ // next(G) 1 0 1 N a b -> [b, a, b]
42
+ // next(G) 1 1 0 N a b -> [b, b, a]
43
+ // next(G) 1 1 1 N a b -> [b, b, b]
44
+ // next(G) 2 0 0 ! N a b -> None
45
+ // next(G) 0 0 0 N a b -> [a, a, a]
4
46
5
47
/// An adaptor iterating through all the ordered `n`-length lists of items
6
48
/// yielded by the underlying iterator, including repetitions.
15
57
I :: Item : Clone ,
16
58
{
17
59
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'.
60
+ iter : Option < I > , // Inner iterator. Forget once consumed after 'base' iterations.
61
+ items : Vec < I :: Item > , // Fill from iter. Final length is 'base'.
62
+
63
+ // Indices just yielded. Length is 'pow'.
64
+ // 0 0 .. 0 0 means that the first combination has been yielded.
65
+ // 0 0 .. 0 1 means that the second combination has been yielded.
66
+ // m m .. m m means that the last combination has just been yielded (m = base - 1).
67
+ // b 0 .. 0 0 means that 'None' has just been yielded (b = base).
68
+ // The latter is a special value marking the renewal of the iterator,
69
+ // which can cycle again through another full round etc.
70
+ indices : Vec < usize > ,
21
71
}
22
72
23
73
/// Create a new `CartesianPower` from an iterator of clonables.
@@ -53,16 +103,28 @@ where
53
103
items,
54
104
indices,
55
105
} = self ;
106
+ println ! (
107
+ "^{pow}: {indices:?}\t {}\t {}" ,
108
+ if iter. is_some( ) { 'S' } else { 'N' } ,
109
+ items. len( )
110
+ ) ;
56
111
match ( * pow, iter, items. len ( ) ) {
57
- // Final stable state: underlying iterator and items forgotten.
112
+ // AAAAAAAAAAAA
113
+ ( 0 , None , 0 ) => Some ( ( indices, items) ) ,
114
+
115
+ // BBBBBBBBBBBB
116
+ // Stable degenerated state.
58
117
( _, None , 0 ) => None ,
59
118
119
+ // CCCCCCCCCCCC
60
120
// Degenerated 0th power iteration.
61
121
( 0 , Some ( _) , _) => {
62
122
self . iter = None ; // Forget without even consuming.
63
123
Some ( ( indices, items) )
64
124
}
65
125
126
+ // DDDDDDDDDDDD
127
+ // First iteration.
66
128
( pow, Some ( it) , 0 ) => {
67
129
// Check whether there is at least one element in the iterator.
68
130
if let Some ( first) = it. next ( ) {
@@ -74,13 +136,15 @@ where
74
136
for _ in 0 ..pow {
75
137
indices. push ( 0 ) ;
76
138
}
77
- return Some ( ( indices, items) ) ;
139
+ Some ( ( indices, items) )
140
+ } else {
141
+ // Degenerated iteration over an empty set, yet with non-null power.
142
+ self . iter = None ;
143
+ None
78
144
}
79
- // Degenerated iteration over an empty set, yet with non-null power.
80
- self . iter = None ;
81
- None
82
145
}
83
146
147
+ // EEEEEEEEEEEE
84
148
( pow, Some ( it) , base) => {
85
149
// We are still unsure whether all items have been collected.
86
150
// As a consequence, 'base' is still uncertain,
@@ -92,31 +156,52 @@ where
92
156
}
93
157
94
158
// All items have just been collected.
95
- self . iter = None ;
96
- if base == 1 || pow == 1 {
159
+ self . iter = None ; // Forget about the underlying iterator.
160
+ if pow == 1 {
97
161
// End of iteration.
98
- items. clear ( ) ;
99
- indices. clear ( ) ;
162
+ indices[ 0 ] = base; // Mark to cycle again on next iteration.
100
163
return None ;
101
164
}
102
165
103
166
// First wrap around.
104
167
indices[ pow - 1 ] = 0 ;
105
- indices[ pow - 2 ] + = 1 ;
168
+ indices[ pow - 2 ] = 1 ;
106
169
Some ( ( indices, items) )
107
170
}
108
171
109
- ( _, None , b) => {
172
+ // FFFFFFFFFFFF
173
+ ( _, None , 1 ) => {
174
+ // Flip the only indice to keep cycling.
175
+ let ind = & mut indices[ 0 ] ;
176
+ if * ind == 1 {
177
+ * ind = 0 ;
178
+ Some ( ( indices, items) )
179
+ } else {
180
+ * ind = 1 ;
181
+ None
182
+ }
183
+ }
184
+
185
+ // GGGGGGGGGGGG
186
+ ( _, None , base) => {
187
+ if indices[ 0 ] == base {
188
+ // Special marker that iteration can start over for a new round.
189
+ indices[ 0 ] = 0 ;
190
+ return Some ( ( indices, items) ) ;
191
+ }
110
192
// Keep yielding items list, incrementing indices rightmost first.
111
193
for index in indices. iter_mut ( ) . rev ( ) {
112
194
* index += 1 ;
113
- if * index < b {
195
+ if * index < base {
114
196
return Some ( ( indices, items) ) ;
115
197
}
116
198
* index = 0 ; // Wrap and increment left.
117
199
}
118
- items. clear ( ) ;
119
- indices. clear ( ) ;
200
+ // Iteration is over.
201
+ // But don't clear the collected items,
202
+ // and mark a special index value to not fuse the iterator
203
+ // but make it possibly cycle through all again.
204
+ indices[ 0 ] = base;
120
205
None
121
206
}
122
207
}
@@ -187,13 +272,6 @@ where
187
272
}
188
273
}
189
274
190
- impl < I > FusedIterator for CartesianPower < I >
191
- where
192
- I : Iterator ,
193
- I :: Item : Clone ,
194
- {
195
- }
196
-
197
275
#[ cfg( test) ]
198
276
mod tests {
199
277
//! Use chars and string to ease testing of every yielded iterator values.
@@ -202,37 +280,46 @@ mod tests {
202
280
use crate :: Itertools ;
203
281
use core:: str:: Chars ;
204
282
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
283
#[ test]
220
284
fn basic ( ) {
221
285
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
- ) ;
286
+ println ! ( "================== ({origin:?}^{pow})" ) ;
287
+ let mut it_act = origin. chars ( ) . cartesian_power ( pow) ;
288
+ // Check thrice that it's cycling.
289
+ for r in 1 ..=3 {
290
+ println ! ( "- - {r} - - - - - -" ) ;
291
+ let mut it_exp = expected. iter ( ) ;
292
+ let mut i = 0 ;
293
+ loop {
294
+ match ( it_exp. next ( ) , it_act. next ( ) ) {
295
+ ( Some ( exp) , Some ( act) ) => {
296
+ if act != exp. chars ( ) . collect :: < Vec < _ > > ( ) {
297
+ panic ! (
298
+ "Failed iteration {} (repetition {}) for {:?}^{}. \
299
+ Expected {:?}, got {:?} instead.",
300
+ i, r, origin, pow, exp, act,
301
+ ) ;
302
+ }
303
+ i += 1 ;
304
+ }
305
+ ( None , Some ( act) ) => {
306
+ panic ! (
307
+ "Failed iteration {} (repetition {}) for {:?}^{}. \
308
+ Expected None, got {:?} instead.",
309
+ i, r, origin, pow, act,
310
+ ) ;
311
+ }
312
+ ( Some ( exp) , None ) => {
313
+ panic ! (
314
+ "Failed iteration {} (repetition {}) for {:?}^{}. \
315
+ Expected {:?}, got None instead.",
316
+ i, r, origin, pow, exp,
317
+ ) ;
318
+ }
319
+ ( None , None ) => break ,
320
+ }
232
321
}
233
- i += 1 ;
234
322
}
235
- check_fused ( it, format ! ( "iteration {} or {:?}^{}" , i, origin, pow) ) ;
236
323
}
237
324
238
325
// Empty underlying iterator.
@@ -281,38 +368,28 @@ mod tests {
281
368
fn check ( origin : & str , pow : usize , expected : & [ ( usize , Option < & str > ) ] ) {
282
369
let mut it = origin. chars ( ) . cartesian_power ( pow) ;
283
370
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
- ) ;
371
+ for r in 1 ..=3 {
372
+ for & ( n, exp) in expected {
373
+ let act = it. nth ( n) ;
374
+ total_n. push ( n) ;
375
+ if act != exp. map ( |s| s. chars ( ) . collect :: < Vec < _ > > ( ) ) {
376
+ panic ! (
377
+ "Failed nth({}) iteration (repetition {}) for {:?}^{}. \
378
+ Expected {:?}, got {:?} instead.",
379
+ total_n
380
+ . iter( )
381
+ . map( ToString :: to_string)
382
+ . collect:: <Vec <_>>( )
383
+ . join( ", " ) ,
384
+ r,
385
+ origin,
386
+ pow,
387
+ exp,
388
+ act
389
+ ) ;
390
+ }
301
391
}
302
392
}
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
393
}
317
394
318
395
// HERE: make it work with the new implementation.
0 commit comments