@@ -303,17 +303,15 @@ impl FixedBitSet
303303 match self . as_slice ( ) . split_first ( ) {
304304 Some ( ( & block, rem) ) => {
305305 Ones {
306- current_bit_idx : 0 ,
307- current_block_idx : 0 ,
308- current_block : block,
306+ bitset : block,
307+ block_idx : 0 ,
309308 remaining_blocks : rem
310309 }
311310 }
312311 None => {
313312 Ones {
314- current_bit_idx : 0 ,
315- current_block_idx : 0 ,
316- current_block : 0 ,
313+ bitset : 0 ,
314+ block_idx : 0 ,
317315 remaining_blocks : & [ ]
318316 }
319317 }
@@ -594,49 +592,28 @@ impl Iterator for Masks {
594592///
595593/// This struct is created by the [`FixedBitSet::ones`] method.
596594pub struct Ones < ' a > {
597- current_bit_idx : usize ,
598- current_block_idx : usize ,
595+ bitset : Block ,
596+ block_idx : usize ,
599597 remaining_blocks : & ' a [ Block ] ,
600- current_block : Block
601598}
602599
603600impl < ' a > Iterator for Ones < ' a > {
604601 type Item = usize ; // the bit position of the '1'
605602
606603 #[ inline]
607604 fn next ( & mut self ) -> Option < Self :: Item > {
608- let mut block = self . current_block ;
609- let mut idx = self . current_bit_idx ;
610-
611- loop {
612- loop {
613- if ( block & 1 ) == 1 {
614- self . current_block = block >> 1 ;
615- self . current_bit_idx = idx + 1 ;
616- return Some ( idx) ;
617- }
618- // reordering the two lines below makes a huge (2x) difference in performance!
619- block = block >> 1 ;
620- idx += 1 ;
621- if block == 0 {
622- break ;
623- }
624- }
625-
626- // go to next block
627- match self . remaining_blocks . split_first ( ) {
628- Some ( ( & next_block, rest) ) => {
629- self . remaining_blocks = rest;
630- self . current_block_idx += 1 ;
631- idx = self . current_block_idx * BITS ;
632- block = next_block;
633- }
634- None => {
635- // last block => done
636- return None ;
637- }
605+ while self . bitset == 0 {
606+ if self . remaining_blocks . is_empty ( ) {
607+ return None ;
638608 }
609+ self . bitset = self . remaining_blocks [ 0 ] ;
610+ self . remaining_blocks = & self . remaining_blocks [ 1 ..] ;
611+ self . block_idx += 1 ;
639612 }
613+ let t = self . bitset & ( 0 as Block ) . wrapping_sub ( self . bitset ) ;
614+ let r = self . bitset . trailing_zeros ( ) as usize ;
615+ self . bitset ^= t;
616+ Some ( self . block_idx * BITS + r)
640617 }
641618}
642619
0 commit comments