@@ -168,11 +168,7 @@ impl<T: Idx> BitSet<T> {
168168 /// Iterates over the indices of set bits in a sorted order.
169169 #[ inline]
170170 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 )
176172 }
177173
178174 /// Duplicates the set as a hybrid set.
@@ -291,26 +287,55 @@ impl<T: Idx> ToString for BitSet<T> {
291287}
292288
293289pub 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+
296301 marker : PhantomData < T >
297302}
298303
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+
299321impl < ' a , T : Idx > Iterator for BitIter < ' a , T > {
300322 type Item = T ;
301323 fn next ( & mut self ) -> Option < T > {
302324 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 ) )
310332 }
311333
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 ) ;
314339 }
315340 }
316341}
@@ -851,11 +876,7 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
851876 pub fn iter ( & self , row : R ) -> BitIter < ' _ , C > {
852877 assert ! ( row. index( ) < self . num_rows) ;
853878 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] )
859880 }
860881
861882 /// Returns the number of elements in `row`.
0 commit comments