@@ -410,14 +410,21 @@ impl FixedBitSet {
410410 #[ inline]
411411 pub fn ones ( & self ) -> Ones {
412412 match self . as_slice ( ) . split_first ( ) {
413- Some ( ( & block, rem) ) => Ones {
414- bitset : block,
415- block_idx : 0 ,
416- remaining_blocks : rem. iter ( ) ,
417- } ,
413+ Some ( ( & first_block, rem) ) => {
414+ let ( & last_block, rem) = rem. split_last ( ) . unwrap_or ( ( & 0 , rem) ) ;
415+ Ones {
416+ bitset_front : first_block,
417+ bitset_back : last_block,
418+ block_idx_front : 0 ,
419+ block_idx_back : ( 1 + rem. len ( ) ) * BITS ,
420+ remaining_blocks : rem. iter ( ) ,
421+ }
422+ }
418423 None => Ones {
419- bitset : 0 ,
420- block_idx : 0 ,
424+ bitset_front : 0 ,
425+ bitset_back : 0 ,
426+ block_idx_front : 0 ,
427+ block_idx_back : 0 ,
421428 remaining_blocks : [ ] . iter ( ) ,
422429 } ,
423430 }
@@ -764,29 +771,109 @@ impl ExactSizeIterator for Masks {}
764771///
765772/// This struct is created by the [`FixedBitSet::ones`] method.
766773pub struct Ones < ' a > {
767- bitset : Block ,
768- block_idx : usize ,
774+ bitset_front : Block ,
775+ bitset_back : Block ,
776+ block_idx_front : usize ,
777+ block_idx_back : usize ,
769778 remaining_blocks : std:: slice:: Iter < ' a , Block > ,
770779}
771780
781+ impl < ' a > Ones < ' a > {
782+ #[ inline]
783+ pub fn last_positive_bit_and_unset ( n : & mut Block ) -> usize {
784+ // Find the last set bit using x & -x
785+ let last_bit = * n & n. wrapping_neg ( ) ;
786+
787+ // Find the position of the last set bit
788+ let position = last_bit. trailing_zeros ( ) ;
789+
790+ // Unset the last set bit
791+ * n &= * n - 1 ;
792+
793+ position as usize
794+ }
795+
796+ #[ inline]
797+ fn first_positive_bit_and_unset ( n : & mut Block ) -> usize {
798+ /* Identify the first non zero bit */
799+ let bit_idx = n. leading_zeros ( ) ;
800+
801+ /* set that bit to zero */
802+ let mask = !( ( 1 as Block ) << ( BITS as u32 - bit_idx - 1 ) ) ;
803+ n. bitand_assign ( mask) ;
804+
805+ bit_idx as usize
806+ }
807+ }
808+
809+ impl < ' a > DoubleEndedIterator for Ones < ' a > {
810+ fn next_back ( & mut self ) -> Option < Self :: Item > {
811+ while self . bitset_back == 0 {
812+ match self . remaining_blocks . next_back ( ) {
813+ None => {
814+ if self . bitset_front != 0 {
815+ self . bitset_back = 0 ;
816+ self . block_idx_back = self . block_idx_front ;
817+ return Some (
818+ self . block_idx_front + BITS
819+ - Self :: first_positive_bit_and_unset ( & mut self . bitset_front )
820+ - 1 ,
821+ ) ;
822+ } else {
823+ return None ;
824+ }
825+ }
826+ Some ( next_block) => {
827+ self . bitset_back = * next_block;
828+ self . block_idx_back -= BITS ;
829+ }
830+ } ;
831+ }
832+
833+ Some (
834+ self . block_idx_back - Self :: first_positive_bit_and_unset ( & mut self . bitset_back ) + BITS
835+ - 1 ,
836+ )
837+ }
838+ }
839+
772840impl < ' a > Iterator for Ones < ' a > {
773841 type Item = usize ; // the bit position of the '1'
774842
775843 #[ inline]
776844 fn next ( & mut self ) -> Option < Self :: Item > {
777- while self . bitset == 0 {
778- self . bitset = * self . remaining_blocks . next ( ) ?;
779- self . block_idx += BITS ;
845+ while self . bitset_front == 0 {
846+ match self . remaining_blocks . next ( ) {
847+ Some ( next_block) => {
848+ self . bitset_front = * next_block;
849+ self . block_idx_front += BITS ;
850+ }
851+ None => {
852+ if self . bitset_back != 0 {
853+ // not needed for iteration, but for size_hint
854+ self . block_idx_front = self . block_idx_back ;
855+ self . bitset_front = 0 ;
856+
857+ return Some (
858+ self . block_idx_back
859+ + Self :: last_positive_bit_and_unset ( & mut self . bitset_back ) ,
860+ ) ;
861+ } else {
862+ return None ;
863+ }
864+ }
865+ } ;
780866 }
781- let t = self . bitset & ( 0 as Block ) . wrapping_sub ( self . bitset ) ;
782- let r = self . bitset . trailing_zeros ( ) as usize ;
783- self . bitset ^= t;
784- Some ( self . block_idx + r)
867+
868+ Some ( self . block_idx_front + Self :: last_positive_bit_and_unset ( & mut self . bitset_front ) )
785869 }
786870
787871 #[ inline]
788872 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
789- ( 0 , Some ( self . remaining_blocks . as_slice ( ) . len ( ) * BITS ) )
873+ (
874+ 0 ,
875+ ( Some ( self . block_idx_back - self . block_idx_front + 2 * BITS ) ) ,
876+ )
790877 }
791878}
792879
@@ -1015,6 +1102,12 @@ mod tests {
10151102
10161103 let ones: Vec < _ > = fb. ones ( ) . collect ( ) ;
10171104 assert_eq ! ( ones. len( ) , 1 ) ;
1105+
1106+ let ones: Vec < _ > = fb. ones ( ) . rev ( ) . collect ( ) ;
1107+ assert_eq ! ( ones. len( ) , 1 ) ;
1108+
1109+ let ones: Vec < _ > = fb. ones ( ) . rev ( ) . alternate ( ) . collect ( ) ;
1110+ assert_eq ! ( ones. len( ) , 1 ) ;
10181111 }
10191112
10201113 #[ test]
@@ -1133,6 +1226,43 @@ mod tests {
11331226 assert_eq ! ( fb. count_ones( 8 ..) , 8 ) ;
11341227 }
11351228
1229+ /* Helper for testing double ended iterator */
1230+ #[ cfg( test) ]
1231+ struct Alternating < I > {
1232+ iter : I ,
1233+ front : bool ,
1234+ }
1235+
1236+ #[ cfg( test) ]
1237+ impl < I : Iterator + DoubleEndedIterator > Iterator for Alternating < I > {
1238+ type Item = I :: Item ;
1239+
1240+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1241+ self . iter . size_hint ( )
1242+ }
1243+ fn next ( & mut self ) -> Option < Self :: Item > {
1244+ if self . front {
1245+ self . front = false ;
1246+ self . iter . next ( )
1247+ } else {
1248+ self . front = true ;
1249+ self . iter . next_back ( )
1250+ }
1251+ }
1252+ }
1253+ #[ cfg( test) ]
1254+ trait AlternatingExt : Iterator + DoubleEndedIterator + Sized {
1255+ fn alternate ( self ) -> Alternating < Self > {
1256+ Alternating {
1257+ iter : self ,
1258+ front : true ,
1259+ }
1260+ }
1261+ }
1262+
1263+ #[ cfg( test) ]
1264+ impl < I : Iterator + DoubleEndedIterator > AlternatingExt for I { }
1265+
11361266 #[ test]
11371267 fn ones ( ) {
11381268 let mut fb = FixedBitSet :: with_capacity ( 100 ) ;
@@ -1147,8 +1277,60 @@ mod tests {
11471277 fb. set ( 99 , true ) ;
11481278
11491279 let ones: Vec < _ > = fb. ones ( ) . collect ( ) ;
1280+ let ones_rev: Vec < _ > = fb. ones ( ) . rev ( ) . collect ( ) ;
1281+ let ones_alternating: Vec < _ > = fb. ones ( ) . alternate ( ) . collect ( ) ;
1282+
1283+ let mut known_result = vec ! [ 7 , 11 , 12 , 35 , 40 , 50 , 77 , 95 , 99 ] ;
1284+
1285+ assert_eq ! ( known_result, ones) ;
1286+ known_result. reverse ( ) ;
1287+ assert_eq ! ( known_result, ones_rev) ;
1288+ let known_result: Vec < _ > = known_result. into_iter ( ) . rev ( ) . alternate ( ) . collect ( ) ;
1289+ assert_eq ! ( known_result, ones_alternating) ;
1290+ }
1291+
1292+ #[ test]
1293+ fn size_hint ( ) {
1294+ for s in 0 ..1000 {
1295+ let mut bitset = FixedBitSet :: with_capacity ( s) ;
1296+ bitset. insert_range ( ..) ;
1297+ let mut t = s;
1298+ let mut iter = bitset. ones ( ) . rev ( ) ;
1299+ loop {
1300+ match iter. next ( ) {
1301+ None => break ,
1302+ Some ( _) => {
1303+ t -= 1 ;
1304+ assert ! ( iter. size_hint( ) . 1 . unwrap( ) >= t) ;
1305+ // factor two, because we have first block and last block
1306+ assert ! ( iter. size_hint( ) . 1 . unwrap( ) <= t + 2 * BITS ) ;
1307+ }
1308+ }
1309+ }
1310+ assert_eq ! ( t, 0 ) ;
1311+ }
1312+ }
11501313
1151- assert_eq ! ( vec![ 7 , 11 , 12 , 35 , 40 , 50 , 77 , 95 , 99 ] , ones) ;
1314+ #[ test]
1315+ fn size_hint_alternate ( ) {
1316+ for s in 0 ..1000 {
1317+ let mut bitset = FixedBitSet :: with_capacity ( s) ;
1318+ bitset. insert_range ( ..) ;
1319+ let mut t = s;
1320+ let mut iter = bitset. ones ( ) . alternate ( ) ;
1321+ loop {
1322+ match iter. next ( ) {
1323+ None => break ,
1324+ Some ( _) => {
1325+ t -= 1 ;
1326+ //println!("{:?} < {}", iter.size_hint(), t);
1327+ assert ! ( iter. size_hint( ) . 1 . unwrap( ) >= t) ;
1328+ assert ! ( iter. size_hint( ) . 1 . unwrap( ) <= t + 3 * BITS ) ;
1329+ }
1330+ }
1331+ }
1332+ assert_eq ! ( t, 0 ) ;
1333+ }
11521334 }
11531335
11541336 #[ test]
@@ -1161,7 +1343,13 @@ mod tests {
11611343 }
11621344 let ones: Vec < _ > = fb. ones ( ) . collect ( ) ;
11631345 let expected: Vec < _ > = ( from..to) . collect ( ) ;
1346+ let ones_rev: Vec < _ > = fb. ones ( ) . rev ( ) . collect ( ) ;
1347+ let expected_rev: Vec < _ > = ( from..to) . rev ( ) . collect ( ) ;
1348+ let ones_rev_alt: Vec < _ > = fb. ones ( ) . rev ( ) . alternate ( ) . collect ( ) ;
1349+ let expected_rev_alt: Vec < _ > = ( from..to) . rev ( ) . alternate ( ) . collect ( ) ;
11641350 assert_eq ! ( expected, ones) ;
1351+ assert_eq ! ( expected_rev, ones_rev) ;
1352+ assert_eq ! ( expected_rev_alt, ones_rev_alt) ;
11651353 }
11661354
11671355 for i in 0 ..100 {
@@ -1631,7 +1819,7 @@ mod tests {
16311819 let b = b_ones. iter ( ) . cloned ( ) . collect :: < FixedBitSet > ( ) ;
16321820 a |= b;
16331821 let res = a. ones ( ) . collect :: < Vec < usize > > ( ) ;
1634- assert ! ( res == a_or_b) ;
1822+ assert_eq ! ( res, a_or_b) ;
16351823 }
16361824
16371825 #[ test]
@@ -1750,7 +1938,7 @@ mod tests {
17501938 tmp
17511939 } ;
17521940
1753- assert ! ( ones == expected) ;
1941+ assert_eq ! ( ones, expected) ;
17541942 }
17551943
17561944 #[ test]
0 commit comments