@@ -168,11 +168,7 @@ impl<T: Idx> BitSet<T> {
168
168
/// Iterates over the indices of set bits in a sorted order.
169
169
#[ inline]
170
170
pub fn iter ( & self ) -> BitIter < ' _ , T > {
171
- BitIter {
172
- cur : None ,
173
- iter : self . words . iter ( ) . enumerate ( ) ,
174
- marker : PhantomData ,
175
- }
171
+ BitIter :: new ( & self . words )
176
172
}
177
173
178
174
/// Duplicates the set as a hybrid set.
@@ -291,26 +287,55 @@ impl<T: Idx> ToString for BitSet<T> {
291
287
}
292
288
293
289
pub struct BitIter < ' a , T : Idx > {
294
- cur : Option < ( Word , usize ) > ,
295
- iter : iter:: Enumerate < slice:: Iter < ' a , Word > > ,
290
+ /// A copy of the current word, but with any already-visited bits cleared.
291
+ /// (This lets us use `trailing_zeros()` to find the next set bit.) When it
292
+ /// is reduced to 0, we move onto the next word.
293
+ word : Word ,
294
+
295
+ /// The offset (measured in bits) of the current word.
296
+ offset : usize ,
297
+
298
+ /// Underlying iterator over the words.
299
+ iter : slice:: Iter < ' a , Word > ,
300
+
296
301
marker : PhantomData < T >
297
302
}
298
303
304
+ impl < ' a , T : Idx > BitIter < ' a , T > {
305
+ #[ inline]
306
+ fn new ( words : & ' a [ Word ] ) -> BitIter < ' a , T > {
307
+ // We initialize `word` and `offset` to degenerate values. On the first
308
+ // call to `next()` we will fall through to getting the first word from
309
+ // `iter`, which sets `word` to the first word (if there is one) and
310
+ // `offset` to 0. Doing it this way saves us from having to maintain
311
+ // additional state about whether we have started.
312
+ BitIter {
313
+ word : 0 ,
314
+ offset : std:: usize:: MAX - ( WORD_BITS - 1 ) ,
315
+ iter : words. iter ( ) ,
316
+ marker : PhantomData ,
317
+ }
318
+ }
319
+ }
320
+
299
321
impl < ' a , T : Idx > Iterator for BitIter < ' a , T > {
300
322
type Item = T ;
301
323
fn next ( & mut self ) -> Option < T > {
302
324
loop {
303
- if let Some ( ( ref mut word, offset ) ) = self . cur {
304
- let bit_pos = word . trailing_zeros ( ) as usize ;
305
- if bit_pos != WORD_BITS {
306
- let bit = 1 << bit_pos ;
307
- * word ^= bit ;
308
- return Some ( T :: new ( bit_pos + offset ) )
309
- }
325
+ if self . word != 0 {
326
+ // Get the position of the next set bit in the current word,
327
+ // then clear the bit.
328
+ let bit_pos = self . word . trailing_zeros ( ) as usize ;
329
+ let bit = 1 << bit_pos ;
330
+ self . word ^= bit ;
331
+ return Some ( T :: new ( bit_pos + self . offset ) )
310
332
}
311
333
312
- let ( i, word) = self . iter . next ( ) ?;
313
- self . cur = Some ( ( * word, WORD_BITS * i) ) ;
334
+ // Move onto the next word. `wrapping_add()` is needed to handle
335
+ // the degenerate initial value given to `offset` in `new()`.
336
+ let word = self . iter . next ( ) ?;
337
+ self . word = * word;
338
+ self . offset = self . offset . wrapping_add ( WORD_BITS ) ;
314
339
}
315
340
}
316
341
}
@@ -851,11 +876,7 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
851
876
pub fn iter ( & self , row : R ) -> BitIter < ' _ , C > {
852
877
assert ! ( row. index( ) < self . num_rows) ;
853
878
let ( start, end) = self . range ( row) ;
854
- BitIter {
855
- cur : None ,
856
- iter : self . words [ start..end] . iter ( ) . enumerate ( ) ,
857
- marker : PhantomData ,
858
- }
879
+ BitIter :: new ( & self . words [ start..end] )
859
880
}
860
881
861
882
/// Returns the number of elements in `row`.
0 commit comments