| 252 | typename Word = typename std::decay< |
| 253 | internal::call_traits::argument_type<0, Visitor&&>>::type::value_type> |
| 254 | static void RunVisitWordsAndWriteLoop(int64_t bit_length, |
| 255 | std::array<ReaderT, N>& readers, |
| 256 | std::array<WriterT, M>& writers, |
| 257 | Visitor&& visitor) { |
| 258 | constexpr int64_t kBitWidth = sizeof(Word) * 8; |
| 259 | |
| 260 | std::array<Word, N> visited_words; |
| 261 | std::array<Word, M> output_words; |
| 262 | |
| 263 | // every reader will have same number of words, since they are same length'ed |
| 264 | // TODO($JIRA) this will be inefficient in some cases. When there are offsets beyond |
| 265 | // Word boundary, every Word would have to be created from 2 adjoining Words |
| 266 | auto n_words = readers[0].words(); |
| 267 | bit_length -= n_words * kBitWidth; |
| 268 | while (n_words--) { |
| 269 | // first collect all words to visited_words array |
| 270 | for (size_t i = 0; i < N; i++) { |
| 271 | visited_words[i] = readers[i].NextWord(); |
| 272 | } |
| 273 | visitor(visited_words, &output_words); |
| 274 | for (size_t i = 0; i < M; i++) { |
| 275 | writers[i].PutNextWord(output_words[i]); |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | // every reader will have same number of trailing bytes, because of the above reason |
| 280 | // tailing portion could be more than one word! (ref: BitmapWordReader constructor) |
| 281 | // remaining full/ partial words to write |
| 282 | |
| 283 | if (bit_length) { |
| 284 | // convert the word visitor lambda to a byte_visitor |
| 285 | auto byte_visitor = [&](const std::array<uint8_t, N>& in, |
| 286 | std::array<uint8_t, M>* out) { |
| 287 | std::array<Word, N> in_words; |
| 288 | std::array<Word, M> out_words; |
| 289 | std::copy(in.begin(), in.end(), in_words.begin()); |
| 290 | visitor(in_words, &out_words); |
| 291 | for (size_t i = 0; i < M; i++) { |
| 292 | out->at(i) = static_cast<uint8_t>(out_words[i]); |
| 293 | } |
| 294 | }; |
| 295 | |
| 296 | std::array<uint8_t, N> visited_bytes; |
| 297 | std::array<uint8_t, M> output_bytes; |
| 298 | int n_bytes = readers[0].trailing_bytes(); |
| 299 | while (n_bytes--) { |
| 300 | visited_bytes.fill(0); |
| 301 | output_bytes.fill(0); |
| 302 | int valid_bits; |
| 303 | for (size_t i = 0; i < N; i++) { |
| 304 | visited_bytes[i] = readers[i].NextTrailingByte(valid_bits); |
| 305 | } |
| 306 | byte_visitor(visited_bytes, &output_bytes); |
| 307 | for (size_t i = 0; i < M; i++) { |
| 308 | writers[i].PutNextTrailingByte(output_bytes[i], valid_bits); |
| 309 | } |
| 310 | } |
| 311 | } |
no test coverage detected