@@ -7,7 +7,7 @@ use std::{
77 cmp:: { min, PartialEq } ,
88 fmt:: { self , Debug } ,
99 hash:: { Hash , Hasher } ,
10- iter:: FromIterator ,
10+ iter:: { DoubleEndedIterator , FromIterator } ,
1111 mem:: { replace, size_of} ,
1212 ops:: {
1313 Bound :: { Excluded , Included , Unbounded } ,
@@ -1156,6 +1156,42 @@ impl<T: Debug + PrimInt> Iterator for IterSetBits<'_, T> {
11561156 }
11571157}
11581158
1159+ impl < T : Debug + PrimInt > DoubleEndedIterator for IterSetBits < ' _ , T > {
1160+ fn next_back ( & mut self ) -> Option < usize > {
1161+ if let Some ( i) = self . range . next_back ( ) {
1162+ let mut b = block_offset :: < T > ( i) ;
1163+ let mut v = self . vob . vec [ b] ;
1164+ // If all bits are set, we don't need to do any complicated checks.
1165+ if v == T :: max_value ( ) {
1166+ return Some ( i) ;
1167+ }
1168+ // At this point we've got a block which might or might not have some bits set. We now
1169+ // fall back to the general case.
1170+ let mut i_off = i % bits_per_block :: < T > ( ) ;
1171+ loop {
1172+ let lz = ( v << ( bits_per_block :: < T > ( ) - 1 - i_off) ) . leading_zeros ( ) as usize ;
1173+ if lz < bits_per_block :: < T > ( ) {
1174+ let bs = b * bits_per_block :: < T > ( ) + i_off - lz;
1175+ self . range . end = bs;
1176+ if bs < self . range . start {
1177+ break ;
1178+ }
1179+ return Some ( bs) ;
1180+ }
1181+ if b == block_offset :: < T > ( self . range . start ) {
1182+ // We've exhausted the iterator.
1183+ self . range . start = self . range . end ;
1184+ break ;
1185+ }
1186+ b -= 1 ;
1187+ v = self . vob . vec [ b] ;
1188+ i_off = bits_per_block :: < T > ( ) - 1 ;
1189+ }
1190+ }
1191+ None
1192+ }
1193+ }
1194+
11591195#[ derive( Clone ) ]
11601196pub struct IterUnsetBits < ' a , T : ' a > {
11611197 vob : & ' a Vob < T > ,
@@ -1542,6 +1578,7 @@ mod tests {
15421578 hash:: { Hash , Hasher } ,
15431579 iter:: FromIterator ,
15441580 mem:: size_of,
1581+ ops:: RangeBounds ,
15451582 } ;
15461583
15471584 #[ test]
@@ -1791,28 +1828,38 @@ mod tests {
17911828
17921829 #[ test]
17931830 fn test_iter_set_bits ( ) {
1831+ fn t < R > ( v : & Vob , range : R , expected : Vec < usize > )
1832+ where
1833+ R : Clone + RangeBounds < usize > ,
1834+ {
1835+ let rev = expected. iter ( ) . cloned ( ) . rev ( ) . collect :: < Vec < usize > > ( ) ;
1836+ assert_eq ! (
1837+ v. iter_set_bits( range. clone( ) ) . collect:: <Vec <usize >>( ) ,
1838+ expected
1839+ ) ;
1840+ assert_eq ! ( v. iter_set_bits( range) . rev( ) . collect:: <Vec <usize >>( ) , rev) ;
1841+ }
1842+
1843+ t ( & vob ! [ ] , .., vec ! [ ] ) ;
1844+ t ( & Vob :: from_elem ( true , 131 ) , .., ( 0 ..131 ) . collect :: < Vec < _ > > ( ) ) ;
1845+
17941846 let mut v1 = vob ! [ false , true , false , true ] ;
1795- assert_eq ! ( v1 . iter_set_bits ( .. ) . collect :: < Vec < usize >> ( ) , vec![ 1 , 3 ] ) ;
1847+ t ( & v1 , .. , vec ! [ 1 , 3 ] ) ;
17961848 v1. resize ( 127 , false ) ;
17971849 v1. push ( true ) ;
17981850 v1. push ( false ) ;
17991851 v1. push ( true ) ;
18001852 v1. push ( true ) ;
18011853 v1. resize ( 256 , false ) ;
18021854 v1. push ( true ) ;
1803- assert_eq ! (
1804- v1. iter_set_bits( ..) . collect:: <Vec <usize >>( ) ,
1805- vec![ 1 , 3 , 127 , 129 , 130 , 256 ]
1806- ) ;
1807- assert_eq ! (
1808- v1. iter_set_bits( 2 ..256 ) . collect:: <Vec <usize >>( ) ,
1809- vec![ 3 , 127 , 129 , 130 ]
1810- ) ;
1811- assert_eq ! (
1812- v1. iter_set_bits( 2 ..) . collect:: <Vec <usize >>( ) ,
1813- vec![ 3 , 127 , 129 , 130 , 256 ]
1814- ) ;
1815- assert_eq ! ( v1. iter_set_bits( ..3 ) . collect:: <Vec <usize >>( ) , vec![ 1 ] ) ;
1855+ assert_eq ! ( v1. len( ) , 257 ) ;
1856+ t ( & v1, .., vec ! [ 1 , 3 , 127 , 129 , 130 , 256 ] ) ;
1857+ t ( & v1, 2 ..257 , vec ! [ 3 , 127 , 129 , 130 , 256 ] ) ;
1858+ t ( & v1, 2 ..256 , vec ! [ 3 , 127 , 129 , 130 ] ) ;
1859+ t ( & v1, 2 .., vec ! [ 3 , 127 , 129 , 130 , 256 ] ) ;
1860+ t ( & v1, 1 ..255 , vec ! [ 1 , 3 , 127 , 129 , 130 ] ) ;
1861+ t ( & v1, ..3 , vec ! [ 1 ] ) ;
1862+ t ( & v1, 128 .., vec ! [ 129 , 130 , 256 ] ) ;
18161863 }
18171864
18181865 #[ test]
0 commit comments