@@ -34,7 +34,7 @@ use std::fmt::{Binary, Display, Error, Formatter};
3434
3535pub use range:: IndexRange ;
3636use std:: cmp:: { Ord , Ordering } ;
37- use std:: iter:: { Chain , FromIterator } ;
37+ use std:: iter:: { Chain , FromIterator , FusedIterator } ;
3838use std:: ops:: { BitAnd , BitAndAssign , BitOr , BitOrAssign , BitXor , BitXorAssign , Index } ;
3939
4040const BITS : usize = std:: mem:: size_of :: < Block > ( ) * 8 ;
@@ -403,6 +403,27 @@ impl FixedBitSet {
403403 }
404404 }
405405
406+ /// Iterates over all disabled bits.
407+ ///
408+ /// Iterator element is the index of the `0` bit, type `usize`.
409+ #[ inline]
410+ pub fn zeroes ( & self ) -> Zeroes {
411+ match self . as_slice ( ) . split_first ( ) {
412+ Some ( ( & block, rem) ) => Zeroes {
413+ bitset : !block,
414+ block_idx : 0 ,
415+ len : self . len ( ) ,
416+ remaining_blocks : rem. iter ( ) ,
417+ } ,
418+ None => Zeroes {
419+ bitset : !0 ,
420+ block_idx : 0 ,
421+ len : self . len ( ) ,
422+ remaining_blocks : [ ] . iter ( ) ,
423+ } ,
424+ }
425+ }
426+
406427 /// Returns a lazy iterator over the intersection of two `FixedBitSet`s
407428 pub fn intersection < ' a > ( & ' a self , other : & ' a FixedBitSet ) -> Intersection < ' a > {
408429 Intersection {
@@ -700,6 +721,46 @@ impl<'a> Iterator for Ones<'a> {
700721 }
701722}
702723
724+ /// An iterator producing the indices of the set bit in a set.
725+ ///
726+ /// This struct is created by the [`FixedBitSet::ones`] method.
727+ pub struct Zeroes < ' a > {
728+ bitset : Block ,
729+ block_idx : usize ,
730+ len : usize ,
731+ remaining_blocks : std:: slice:: Iter < ' a , Block > ,
732+ }
733+
734+ impl < ' a > Iterator for Zeroes < ' a > {
735+ type Item = usize ; // the bit position of the '1'
736+
737+ #[ inline]
738+ fn next ( & mut self ) -> Option < Self :: Item > {
739+ while self . bitset == 0 {
740+ self . bitset = !* self . remaining_blocks . next ( ) ?;
741+ self . block_idx += BITS ;
742+ }
743+ let t = self . bitset & ( 0 as Block ) . wrapping_sub ( self . bitset ) ;
744+ let r = self . bitset . trailing_zeros ( ) as usize ;
745+ self . bitset ^= t;
746+ let bit = self . block_idx + r;
747+ // The remaining zeroes beyond the length of the bitset must be excluded.
748+ if bit < self . len {
749+ Some ( bit)
750+ } else {
751+ None
752+ }
753+ }
754+
755+ #[ inline]
756+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
757+ ( 0 , Some ( self . len ) )
758+ }
759+ }
760+
761+ // Zeroes will stop returning Some when exhausted.
762+ impl < ' a > FusedIterator for Zeroes < ' a > { }
763+
703764impl Clone for FixedBitSet {
704765 #[ inline]
705766 fn clone ( & self ) -> Self {
@@ -1638,6 +1699,34 @@ mod tests {
16381699 ) ;
16391700 }
16401701
1702+ #[ test]
1703+ fn zeroes ( ) {
1704+ let len = 232 ;
1705+ let mut fb = FixedBitSet :: with_capacity ( len) ;
1706+ for i in ( 0 ..len) . filter ( |i| i % 7 == 0 ) {
1707+ fb. insert ( i) ;
1708+ }
1709+ let zeroes = fb. zeroes ( ) . collect :: < Vec < usize > > ( ) ;
1710+
1711+ assert_eq ! (
1712+ zeroes,
1713+ vec![
1714+ 1 , 2 , 3 , 4 , 5 , 6 , 8 , 9 , 10 , 11 , 12 , 13 , 15 , 16 , 17 , 18 , 19 , 20 , 22 , 23 , 24 , 25 , 26 ,
1715+ 27 , 29 , 30 , 31 , 32 , 33 , 34 , 36 , 37 , 38 , 39 , 40 , 41 , 43 , 44 , 45 , 46 , 47 , 48 , 50 , 51 ,
1716+ 52 , 53 , 54 , 55 , 57 , 58 , 59 , 60 , 61 , 62 , 64 , 65 , 66 , 67 , 68 , 69 , 71 , 72 , 73 , 74 , 75 ,
1717+ 76 , 78 , 79 , 80 , 81 , 82 , 83 , 85 , 86 , 87 , 88 , 89 , 90 , 92 , 93 , 94 , 95 , 96 , 97 , 99 ,
1718+ 100 , 101 , 102 , 103 , 104 , 106 , 107 , 108 , 109 , 110 , 111 , 113 , 114 , 115 , 116 , 117 ,
1719+ 118 , 120 , 121 , 122 , 123 , 124 , 125 , 127 , 128 , 129 , 130 , 131 , 132 , 134 , 135 , 136 ,
1720+ 137 , 138 , 139 , 141 , 142 , 143 , 144 , 145 , 146 , 148 , 149 , 150 , 151 , 152 , 153 , 155 ,
1721+ 156 , 157 , 158 , 159 , 160 , 162 , 163 , 164 , 165 , 166 , 167 , 169 , 170 , 171 , 172 , 173 ,
1722+ 174 , 176 , 177 , 178 , 179 , 180 , 181 , 183 , 184 , 185 , 186 , 187 , 188 , 190 , 191 , 192 ,
1723+ 193 , 194 , 195 , 197 , 198 , 199 , 200 , 201 , 202 , 204 , 205 , 206 , 207 , 208 , 209 , 211 ,
1724+ 212 , 213 , 214 , 215 , 216 , 218 , 219 , 220 , 221 , 222 , 223 , 225 , 226 , 227 , 228 , 229 ,
1725+ 230
1726+ ]
1727+ ) ;
1728+ }
1729+
16411730 #[ cfg( feature = "std" ) ]
16421731 #[ test]
16431732 fn binary_trait ( ) {
0 commit comments