1
1
use core:: array;
2
- use core:: ops :: IndexMut ;
2
+ use core:: borrow :: BorrowMut ;
3
3
use std:: fmt;
4
4
use std:: iter:: FusedIterator ;
5
5
@@ -39,50 +39,42 @@ pub struct CombinationsGeneric<I: Iterator, Idx> {
39
39
first : bool ,
40
40
}
41
41
42
- pub trait PoolIndex < T > : IndexMut < usize , Output = usize > {
42
+ pub trait PoolIndex < T > : BorrowMut < [ usize ] > {
43
43
type Item ;
44
44
45
- fn len ( & self ) -> usize ;
46
45
fn extract_item < I : Iterator < Item = T > > ( & self , pool : & LazyBuffer < I > ) -> Self :: Item
47
46
where
48
47
T : Clone ;
49
- fn as_slice ( & self ) -> & [ usize ] ;
48
+
49
+ #[ inline]
50
+ fn len ( & self ) -> usize {
51
+ self . borrow ( ) . len ( )
52
+ }
50
53
}
51
54
52
55
impl < T > PoolIndex < T > for Vec < usize > {
53
56
type Item = Vec < T > ;
54
57
55
- fn len ( & self ) -> usize {
56
- self . len ( )
57
- }
58
58
fn extract_item < I : Iterator < Item = T > > ( & self , pool : & LazyBuffer < I > ) -> Vec < T >
59
59
where
60
60
T : Clone ,
61
61
{
62
62
pool. get_at ( self )
63
63
}
64
-
65
- fn as_slice ( & self ) -> & [ usize ] {
66
- self
67
- }
68
64
}
69
65
70
66
impl < T , const K : usize > PoolIndex < T > for [ usize ; K ] {
71
67
type Item = [ T ; K ] ;
72
68
73
- fn len ( & self ) -> usize {
74
- K
75
- }
76
-
77
69
fn extract_item < I : Iterator < Item = T > > ( & self , pool : & LazyBuffer < I > ) -> [ T ; K ]
78
70
where
79
71
T : Clone ,
80
72
{
81
73
pool. get_array ( * self )
82
74
}
83
75
84
- fn as_slice ( & self ) -> & [ usize ] {
85
- self
76
+ fn len ( & self ) -> usize {
77
+ K
86
78
}
87
79
}
88
80
@@ -142,7 +134,7 @@ impl<I: Iterator, Idx: PoolIndex<I::Item>> CombinationsGeneric<I, Idx> {
142
134
} = self ;
143
135
{
144
136
let n = pool. count ( ) ;
145
- ( n, remaining_for ( n, first, indices. as_slice ( ) ) . unwrap ( ) )
137
+ ( n, remaining_for ( n, first, indices. borrow ( ) ) . unwrap ( ) )
146
138
}
147
139
}
148
140
@@ -164,19 +156,21 @@ impl<I: Iterator, Idx: PoolIndex<I::Item>> CombinationsGeneric<I, Idx> {
164
156
///
165
157
/// Returns true if we've run out of combinations, false otherwise.
166
158
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 ( ) {
168
163
return true ; // Done
169
164
}
170
-
171
165
// 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 ;
173
167
174
168
// 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 {
176
170
self . pool . get_next ( ) ; // may change pool size
177
171
}
178
172
179
- while self . indices [ i] == i + self . pool . len ( ) - self . indices . len ( ) {
173
+ while indices[ i] == i + self . pool . len ( ) - indices. len ( ) {
180
174
if i > 0 {
181
175
i -= 1 ;
182
176
} else {
@@ -186,11 +180,10 @@ impl<I: Iterator, Idx: PoolIndex<I::Item>> CombinationsGeneric<I, Idx> {
186
180
}
187
181
188
182
// 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 ;
192
186
}
193
-
194
187
// If we've made it this far, we haven't run out of combos
195
188
false
196
189
}
@@ -245,8 +238,8 @@ where
245
238
246
239
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
247
240
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 ( ) ) ) ;
250
243
( low, upp)
251
244
}
252
245
0 commit comments