@@ -296,6 +296,18 @@ inline bool BitReader::GetValue(int num_bits, T* v) {
296296 return GetBatch (num_bits, v, 1 ) == 1 ;
297297}
298298
299+ namespace internal {
300+ template <typename T>
301+ struct unpack_detect {
302+ using type = std::make_unsigned_t <T>;
303+ };
304+
305+ template <>
306+ struct unpack_detect <bool > {
307+ using type = uint8_t ;
308+ };
309+ } // namespace internal
310+
299311template <typename T>
300312inline int BitReader::GetBatch (int num_bits, T* v, int batch_size) {
301313 ARROW_DCHECK (buffer_ != NULL );
@@ -323,38 +335,12 @@ inline int BitReader::GetBatch(int num_bits, T* v, int batch_size) {
323335 }
324336 }
325337
326- if constexpr (sizeof (T) >= sizeof (uint16_t )) {
327- int num_unpacked = internal::unpack (buffer + byte_offset,
328- reinterpret_cast <std::make_unsigned_t <T>*>(v + i),
329- batch_size - i, num_bits);
330- i += num_unpacked;
331- byte_offset += num_unpacked * num_bits / 8 ;
332- } else {
333- // TODO: revisit this limit if necessary
334- ARROW_DCHECK_LE (num_bits, 32 );
335- const int buffer_size = 1024 ;
336- uint32_t unpack_buffer[buffer_size];
337- while (i < batch_size) {
338- int unpack_size = std::min (buffer_size, batch_size - i);
339- int num_unpacked =
340- internal::unpack (buffer + byte_offset, unpack_buffer, unpack_size, num_bits);
341- if (num_unpacked == 0 ) {
342- break ;
343- }
344- for (int k = 0 ; k < num_unpacked; ++k) {
345- #ifdef _MSC_VER
346- # pragma warning(push)
347- # pragma warning(disable : 4800)
348- #endif
349- v[i + k] = static_cast <T>(unpack_buffer[k]);
350- #ifdef _MSC_VER
351- # pragma warning(pop)
352- #endif
353- }
354- i += num_unpacked;
355- byte_offset += num_unpacked * num_bits / 8 ;
356- }
357- }
338+ using unpack_t = typename internal::unpack_detect<T>::type;
339+
340+ int num_unpacked = ::arrow::internal::unpack (
341+ buffer + byte_offset, reinterpret_cast <unpack_t *>(v + i), batch_size - i, num_bits);
342+ i += num_unpacked;
343+ byte_offset += num_unpacked * num_bits / 8 ;
358344
359345 buffered_values =
360346 detail::ReadLittleEndianWord (buffer + byte_offset, max_bytes - byte_offset);
0 commit comments