\brief Return the next run of available bits, usually 64. The returned pair contains the size of run and the number of true values. The last block will have a length less than 64 if the bitmap length is not a multiple of 64, and will return 0-length blocks in subsequent invocations.
| 165 | /// multiple of 64, and will return 0-length blocks in subsequent |
| 166 | /// invocations. |
| 167 | BitBlockCount NextWord() { |
| 168 | using detail::LoadWord; |
| 169 | using detail::ShiftWord; |
| 170 | |
| 171 | if (!bits_remaining_) { |
| 172 | return {0, 0}; |
| 173 | } |
| 174 | int64_t popcount = 0; |
| 175 | if (offset_ == 0) { |
| 176 | if (bits_remaining_ < kWordBits) { |
| 177 | return GetBlockSlow(kWordBits); |
| 178 | } |
| 179 | popcount = std::popcount(LoadWord(bitmap_)); |
| 180 | } else { |
| 181 | // When the offset is > 0, we need there to be a word beyond the last |
| 182 | // aligned word in the bitmap for the bit shifting logic. |
| 183 | if (bits_remaining_ < 2 * kWordBits - offset_) { |
| 184 | return GetBlockSlow(kWordBits); |
| 185 | } |
| 186 | popcount = |
| 187 | std::popcount(ShiftWord(LoadWord(bitmap_), LoadWord(bitmap_ + 8), offset_)); |
| 188 | } |
| 189 | bitmap_ += kWordBits / 8; |
| 190 | bits_remaining_ -= kWordBits; |
| 191 | return {64, static_cast<int16_t>(popcount)}; |
| 192 | } |
| 193 | |
| 194 | private: |
| 195 | /// \brief Return block with the requested size when doing word-wise |