11use alloc:: boxed:: Box ;
22use alloc:: vec:: Vec ;
33use std:: fmt;
4- use std:: iter:: once;
54use std:: iter:: FusedIterator ;
65
76use super :: lazy_buffer:: LazyBuffer ;
@@ -39,7 +38,8 @@ enum PermutationState<Idx: PoolIndex> {
3938 /// All values from the iterator are known so `n` is known.
4039 Loaded {
4140 indices : Box < [ usize ] > ,
42- cycles : Box < [ usize ] > ,
41+ cycles : Box < [ usize ] > , // TODO Should be Idx::Item<usize>
42+ k : Idx :: Length , // TODO Should be inferred from cycles
4343 } ,
4444 /// No permutation left to generate.
4545 End ,
6666 I : Iterator ,
6767 I :: Item : Clone ,
6868{
69- type Item = Vec < I :: Item > ;
69+ type Item = Idx :: Item < I :: Item > ;
7070
7171 fn next ( & mut self ) -> Option < Self :: Item > {
7272 let Self { vals, state } = self ;
@@ -82,14 +82,18 @@ where
8282 }
8383 * state = PermutationState :: Buffered { k, min_n : k. value ( ) } ;
8484 }
85- Some ( vals[ 0 ..k . value ( ) ] . to_vec ( ) )
85+ Some ( Idx :: from_fn ( k , |i| vals[ i ] . clone ( ) ) )
8686 }
87- PermutationState :: Buffered { ref k, min_n } => {
87+ PermutationState :: Buffered { k, min_n } => {
8888 if vals. get_next ( ) {
89- let item = ( 0 ..k. value ( ) - 1 )
90- . chain ( once ( * min_n) )
91- . map ( |i| vals[ i] . clone ( ) )
92- . collect ( ) ;
89+ // TODO This is ugly. Maybe working on indices is better?
90+ let item = Idx :: from_fn ( * k, |i| {
91+ vals[ if i==k. value ( ) -1 {
92+ * min_n
93+ } else {
94+ i
95+ } ] . clone ( )
96+ } ) ;
9397 * min_n += 1 ;
9498 Some ( item)
9599 } else {
@@ -104,18 +108,17 @@ where
104108 return None ;
105109 }
106110 }
107- let item = vals . get_at ( & indices[ 0 ..k . value ( ) ] ) ;
108- * state = PermutationState :: Loaded { indices, cycles } ;
111+ let item = Idx :: from_fn ( * k , |i| vals [ indices[ i ] ] . clone ( ) ) ;
112+ * state = PermutationState :: Loaded { indices, cycles, k : * k } ;
109113 Some ( item)
110114 }
111115 }
112- PermutationState :: Loaded { indices, cycles } => {
116+ PermutationState :: Loaded { indices, cycles, k } => {
113117 if advance ( indices, cycles) {
114118 * state = PermutationState :: End ;
115119 return None ;
116120 }
117- let k = cycles. len ( ) ;
118- Some ( vals. get_at ( & indices[ 0 ..k] ) )
121+ Some ( Idx :: from_fn ( * k, |i| vals[ indices[ i] ] . clone ( ) ) )
119122 }
120123 PermutationState :: End => None ,
121124 }
@@ -178,6 +181,7 @@ impl<Idx: PoolIndex> PermutationState<Idx> {
178181 Self :: Loaded {
179182 ref indices,
180183 ref cycles,
184+ k : _,
181185 } => {
182186 let count = cycles. iter ( ) . enumerate ( ) . try_fold ( 0usize , |acc, ( i, & c) | {
183187 acc. checked_mul ( indices. len ( ) - i)
0 commit comments