11use core:: array;
2- use core:: ops :: IndexMut ;
2+ use core:: borrow :: BorrowMut ;
33use std:: fmt;
44use std:: iter:: FusedIterator ;
55
@@ -39,50 +39,42 @@ pub struct CombinationsGeneric<I: Iterator, Idx> {
3939 first : bool ,
4040}
4141
42- pub trait PoolIndex < T > : IndexMut < usize , Output = usize > {
42+ pub trait PoolIndex < T > : BorrowMut < [ usize ] > {
4343 type Item ;
4444
45- fn len ( & self ) -> usize ;
4645 fn extract_item < I : Iterator < Item = T > > ( & self , pool : & LazyBuffer < I > ) -> Self :: Item
4746 where
4847 T : Clone ;
49- fn as_slice ( & self ) -> & [ usize ] ;
48+
49+ #[ inline]
50+ fn len ( & self ) -> usize {
51+ self . borrow ( ) . len ( )
52+ }
5053}
5154
5255impl < T > PoolIndex < T > for Vec < usize > {
5356 type Item = Vec < T > ;
5457
55- fn len ( & self ) -> usize {
56- self . len ( )
57- }
5858 fn extract_item < I : Iterator < Item = T > > ( & self , pool : & LazyBuffer < I > ) -> Vec < T >
5959 where
6060 T : Clone ,
6161 {
6262 pool. get_at ( self )
6363 }
64-
65- fn as_slice ( & self ) -> & [ usize ] {
66- self
67- }
6864}
6965
7066impl < T , const K : usize > PoolIndex < T > for [ usize ; K ] {
7167 type Item = [ T ; K ] ;
7268
73- fn len ( & self ) -> usize {
74- K
75- }
76-
7769 fn extract_item < I : Iterator < Item = T > > ( & self , pool : & LazyBuffer < I > ) -> [ T ; K ]
7870 where
7971 T : Clone ,
8072 {
8173 pool. get_array ( * self )
8274 }
8375
84- fn as_slice ( & self ) -> & [ usize ] {
85- self
76+ fn len ( & self ) -> usize {
77+ K
8678 }
8779}
8880
@@ -142,7 +134,7 @@ impl<I: Iterator, Idx: PoolIndex<I::Item>> CombinationsGeneric<I, Idx> {
142134 } = self ;
143135 {
144136 let n = pool. count ( ) ;
145- ( n, remaining_for ( n, first, indices. as_slice ( ) ) . unwrap ( ) )
137+ ( n, remaining_for ( n, first, indices. borrow ( ) ) . unwrap ( ) )
146138 }
147139 }
148140
@@ -164,19 +156,21 @@ impl<I: Iterator, Idx: PoolIndex<I::Item>> CombinationsGeneric<I, Idx> {
164156 ///
165157 /// Returns true if we've run out of combinations, false otherwise.
166158 fn increment_indices ( & mut self ) -> bool {
167- if self . indices . len ( ) == 0 {
159+ // Borrow once instead of noise each time it's indexed
160+ let indices = self . indices . borrow_mut ( ) ;
161+
162+ if indices. is_empty ( ) {
168163 return true ; // Done
169164 }
170-
171165 // Scan from the end, looking for an index to increment
172- let mut i: usize = self . indices . len ( ) - 1 ;
166+ let mut i: usize = indices. len ( ) - 1 ;
173167
174168 // Check if we need to consume more from the iterator
175- if self . indices [ i] == self . pool . len ( ) - 1 {
169+ if indices[ i] == self . pool . len ( ) - 1 {
176170 self . pool . get_next ( ) ; // may change pool size
177171 }
178172
179- while self . indices [ i] == i + self . pool . len ( ) - self . indices . len ( ) {
173+ while indices[ i] == i + self . pool . len ( ) - indices. len ( ) {
180174 if i > 0 {
181175 i -= 1 ;
182176 } else {
@@ -186,11 +180,10 @@ impl<I: Iterator, Idx: PoolIndex<I::Item>> CombinationsGeneric<I, Idx> {
186180 }
187181
188182 // Increment index, and reset the ones to its right
189- self . indices [ i] += 1 ;
190- for j in i + 1 ..self . indices . len ( ) {
191- self . indices [ j] = self . indices [ j - 1 ] + 1 ;
183+ indices[ i] += 1 ;
184+ for j in i + 1 ..indices. len ( ) {
185+ indices[ j] = indices[ j - 1 ] + 1 ;
192186 }
193-
194187 // If we've made it this far, we haven't run out of combos
195188 false
196189 }
@@ -245,8 +238,8 @@ where
245238
246239 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
247240 let ( mut low, mut upp) = self . pool . size_hint ( ) ;
248- low = remaining_for ( low, self . first , self . indices . as_slice ( ) ) . unwrap_or ( usize:: MAX ) ;
249- upp = upp. and_then ( |upp| remaining_for ( upp, self . first , self . indices . as_slice ( ) ) ) ;
241+ low = remaining_for ( low, self . first , self . indices . borrow ( ) ) . unwrap_or ( usize:: MAX ) ;
242+ upp = upp. and_then ( |upp| remaining_for ( upp, self . first , self . indices . borrow ( ) ) ) ;
250243 ( low, upp)
251244 }
252245
0 commit comments