| 61 | |
| 62 | template <class Generator> |
| 63 | void GenerateBitsUnrolled(uint8_t* bitmap, int64_t start_offset, int64_t length, |
| 64 | Generator&& g) { |
| 65 | static_assert(std::is_same<decltype(std::declval<Generator>()()), bool>::value, |
| 66 | "Functor passed to GenerateBitsUnrolled must return bool"); |
| 67 | |
| 68 | if (length == 0) { |
| 69 | return; |
| 70 | } |
| 71 | uint8_t current_byte; |
| 72 | uint8_t* cur = bitmap + start_offset / 8; |
| 73 | const uint64_t start_bit_offset = start_offset % 8; |
| 74 | uint8_t bit_mask = bit_util::kBitmask[start_bit_offset]; |
| 75 | int64_t remaining = length; |
| 76 | |
| 77 | if (bit_mask != 0x01) { |
| 78 | current_byte = *cur & bit_util::kPrecedingBitmask[start_bit_offset]; |
| 79 | while (bit_mask != 0 && remaining > 0) { |
| 80 | current_byte |= g() * bit_mask; |
| 81 | bit_mask = static_cast<uint8_t>(bit_mask << 1); |
| 82 | --remaining; |
| 83 | } |
| 84 | *cur++ = current_byte; |
| 85 | } |
| 86 | |
| 87 | int64_t remaining_bytes = remaining / 8; |
| 88 | uint8_t out_results[8]; |
| 89 | while (remaining_bytes-- > 0) { |
| 90 | for (int i = 0; i < 8; ++i) { |
| 91 | out_results[i] = g(); |
| 92 | } |
| 93 | *cur++ = static_cast<uint8_t>(out_results[0] | out_results[1] << 1 | |
| 94 | out_results[2] << 2 | out_results[3] << 3 | |
| 95 | out_results[4] << 4 | out_results[5] << 5 | |
| 96 | out_results[6] << 6 | out_results[7] << 7); |
| 97 | } |
| 98 | |
| 99 | int64_t remaining_bits = remaining % 8; |
| 100 | if (remaining_bits) { |
| 101 | current_byte = 0; |
| 102 | bit_mask = 0x01; |
| 103 | while (remaining_bits-- > 0) { |
| 104 | current_byte |= g() * bit_mask; |
| 105 | bit_mask = static_cast<uint8_t>(bit_mask << 1); |
| 106 | } |
| 107 | *cur++ = current_byte; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | } // namespace internal |
| 112 | } // namespace arrow |
no outgoing calls