|
18 | 18 | #[cfg(not(feature = "std"))] |
19 | 19 | extern crate alloc; |
20 | 20 | #[cfg(not(feature = "std"))] |
21 | | -use alloc::{vec, vec::Vec}; |
| 21 | +use alloc::{ |
| 22 | + vec, |
| 23 | + vec::{IntoIter, Vec}, |
| 24 | +}; |
| 25 | +#[cfg(feature = "std")] |
| 26 | +use std::vec::IntoIter; |
22 | 27 |
|
23 | 28 | #[cfg(not(feature = "std"))] |
24 | 29 | use core as std; |
@@ -517,6 +522,32 @@ impl FixedBitSet { |
517 | 522 | } |
518 | 523 | } |
519 | 524 |
|
| 525 | + /// Iterates over all enabled bits. |
| 526 | + /// |
| 527 | + /// Iterator element is the index of the `1` bit, type `usize`. |
| 528 | + /// Unlike `ones`, this function consumes the `FixedBitset`. |
| 529 | + pub fn into_ones(mut self) -> IntoOnes { |
| 530 | + if self.data.len() == 0 { |
| 531 | + IntoOnes { |
| 532 | + bitset_front: 0, |
| 533 | + bitset_back: 0, |
| 534 | + block_idx_front: 0, |
| 535 | + block_idx_back: 0, |
| 536 | + remaining_blocks: self.data.into_iter(), |
| 537 | + } |
| 538 | + } else { |
| 539 | + let first_block = self.data.remove(0); |
| 540 | + let last_block = self.data.pop().unwrap_or(0); |
| 541 | + IntoOnes { |
| 542 | + bitset_front: first_block, |
| 543 | + bitset_back: last_block, |
| 544 | + block_idx_front: 0, |
| 545 | + block_idx_back: (1 + self.data.len()) * BITS, |
| 546 | + remaining_blocks: self.data.into_iter(), |
| 547 | + } |
| 548 | + } |
| 549 | + } |
| 550 | + |
520 | 551 | /// Iterates over all disabled bits. |
521 | 552 | /// |
522 | 553 | /// Iterator element is the index of the `0` bit, type `usize`. |
@@ -1058,6 +1089,116 @@ impl FromIterator<usize> for FixedBitSet { |
1058 | 1089 | } |
1059 | 1090 | } |
1060 | 1091 |
|
| 1092 | +pub struct IntoOnes { |
| 1093 | + bitset_front: Block, |
| 1094 | + bitset_back: Block, |
| 1095 | + block_idx_front: usize, |
| 1096 | + block_idx_back: usize, |
| 1097 | + remaining_blocks: IntoIter<Block>, |
| 1098 | +} |
| 1099 | + |
| 1100 | +impl IntoOnes { |
| 1101 | + #[inline] |
| 1102 | + pub fn last_positive_bit_and_unset(n: &mut Block) -> usize { |
| 1103 | + // Find the last set bit using x & -x |
| 1104 | + let last_bit = *n & n.wrapping_neg(); |
| 1105 | + |
| 1106 | + // Find the position of the last set bit |
| 1107 | + let position = last_bit.trailing_zeros(); |
| 1108 | + |
| 1109 | + // Unset the last set bit |
| 1110 | + *n &= *n - 1; |
| 1111 | + |
| 1112 | + position as usize |
| 1113 | + } |
| 1114 | + |
| 1115 | + #[inline] |
| 1116 | + fn first_positive_bit_and_unset(n: &mut Block) -> usize { |
| 1117 | + /* Identify the first non zero bit */ |
| 1118 | + let bit_idx = n.leading_zeros(); |
| 1119 | + |
| 1120 | + /* set that bit to zero */ |
| 1121 | + let mask = !((1 as Block) << (BITS as u32 - bit_idx - 1)); |
| 1122 | + n.bitand_assign(mask); |
| 1123 | + |
| 1124 | + bit_idx as usize |
| 1125 | + } |
| 1126 | +} |
| 1127 | + |
| 1128 | +impl DoubleEndedIterator for IntoOnes { |
| 1129 | + fn next_back(&mut self) -> Option<Self::Item> { |
| 1130 | + while self.bitset_back == 0 { |
| 1131 | + match self.remaining_blocks.next_back() { |
| 1132 | + None => { |
| 1133 | + if self.bitset_front != 0 { |
| 1134 | + self.bitset_back = 0; |
| 1135 | + self.block_idx_back = self.block_idx_front; |
| 1136 | + return Some( |
| 1137 | + self.block_idx_front + BITS |
| 1138 | + - Self::first_positive_bit_and_unset(&mut self.bitset_front) |
| 1139 | + - 1, |
| 1140 | + ); |
| 1141 | + } else { |
| 1142 | + return None; |
| 1143 | + } |
| 1144 | + } |
| 1145 | + Some(next_block) => { |
| 1146 | + self.bitset_back = next_block; |
| 1147 | + self.block_idx_back -= BITS; |
| 1148 | + } |
| 1149 | + }; |
| 1150 | + } |
| 1151 | + |
| 1152 | + Some( |
| 1153 | + self.block_idx_back - Self::first_positive_bit_and_unset(&mut self.bitset_back) + BITS |
| 1154 | + - 1, |
| 1155 | + ) |
| 1156 | + } |
| 1157 | +} |
| 1158 | + |
| 1159 | +impl Iterator for IntoOnes { |
| 1160 | + type Item = usize; // the bit position of the '1' |
| 1161 | + |
| 1162 | + #[inline] |
| 1163 | + fn next(&mut self) -> Option<Self::Item> { |
| 1164 | + while self.bitset_front == 0 { |
| 1165 | + match self.remaining_blocks.next() { |
| 1166 | + Some(next_block) => { |
| 1167 | + self.bitset_front = next_block; |
| 1168 | + self.block_idx_front += BITS; |
| 1169 | + } |
| 1170 | + None => { |
| 1171 | + if self.bitset_back != 0 { |
| 1172 | + // not needed for iteration, but for size_hint |
| 1173 | + self.block_idx_front = self.block_idx_back; |
| 1174 | + self.bitset_front = 0; |
| 1175 | + |
| 1176 | + return Some( |
| 1177 | + self.block_idx_back |
| 1178 | + + Self::last_positive_bit_and_unset(&mut self.bitset_back), |
| 1179 | + ); |
| 1180 | + } else { |
| 1181 | + return None; |
| 1182 | + } |
| 1183 | + } |
| 1184 | + }; |
| 1185 | + } |
| 1186 | + |
| 1187 | + Some(self.block_idx_front + Self::last_positive_bit_and_unset(&mut self.bitset_front)) |
| 1188 | + } |
| 1189 | + |
| 1190 | + #[inline] |
| 1191 | + fn size_hint(&self) -> (usize, Option<usize>) { |
| 1192 | + ( |
| 1193 | + 0, |
| 1194 | + (Some(self.block_idx_back - self.block_idx_front + 2 * BITS)), |
| 1195 | + ) |
| 1196 | + } |
| 1197 | +} |
| 1198 | + |
| 1199 | +// Ones will continue to return None once it first returns None. |
| 1200 | +impl<'a> FusedIterator for IntoOnes {} |
| 1201 | + |
1061 | 1202 | impl<'a> BitAnd for &'a FixedBitSet { |
1062 | 1203 | type Output = FixedBitSet; |
1063 | 1204 | fn bitand(self, other: &FixedBitSet) -> FixedBitSet { |
@@ -1376,6 +1517,35 @@ mod tests { |
1376 | 1517 | assert_eq!(known_result, ones_alternating); |
1377 | 1518 | } |
1378 | 1519 |
|
| 1520 | + #[test] |
| 1521 | + fn into_ones() { |
| 1522 | + fn create() -> FixedBitSet { |
| 1523 | + let mut fb = FixedBitSet::with_capacity(100); |
| 1524 | + fb.set(11, true); |
| 1525 | + fb.set(12, true); |
| 1526 | + fb.set(7, true); |
| 1527 | + fb.set(35, true); |
| 1528 | + fb.set(40, true); |
| 1529 | + fb.set(77, true); |
| 1530 | + fb.set(95, true); |
| 1531 | + fb.set(50, true); |
| 1532 | + fb.set(99, true); |
| 1533 | + fb |
| 1534 | + } |
| 1535 | + |
| 1536 | + let ones: Vec<_> = create().into_ones().collect(); |
| 1537 | + let ones_rev: Vec<_> = create().into_ones().rev().collect(); |
| 1538 | + let ones_alternating: Vec<_> = create().into_ones().alternate().collect(); |
| 1539 | + |
| 1540 | + let mut known_result = vec![7, 11, 12, 35, 40, 50, 77, 95, 99]; |
| 1541 | + |
| 1542 | + assert_eq!(known_result, ones); |
| 1543 | + known_result.reverse(); |
| 1544 | + assert_eq!(known_result, ones_rev); |
| 1545 | + let known_result: Vec<_> = known_result.into_iter().rev().alternate().collect(); |
| 1546 | + assert_eq!(known_result, ones_alternating); |
| 1547 | + } |
| 1548 | + |
1379 | 1549 | #[test] |
1380 | 1550 | fn size_hint() { |
1381 | 1551 | for s in 0..1000 { |
|
0 commit comments