diff --git a/cpp/src/arrow/compute/kernels/codegen_internal.h b/cpp/src/arrow/compute/kernels/codegen_internal.h index 2a492f581f53b..575a8150b596a 100644 --- a/cpp/src/arrow/compute/kernels/codegen_internal.h +++ b/cpp/src/arrow/compute/kernels/codegen_internal.h @@ -141,6 +141,13 @@ struct GetViewType::value || static T LogicalValue(PhysicalType value) { return value; } }; +template +struct GetViewType> { + using T = typename TypeTraits::ScalarType; + + static T LogicalValue(T value) { return value; } +}; + template <> struct GetViewType { using T = Decimal32; @@ -322,6 +329,47 @@ struct ArrayIterator> { } }; +template +struct ArrayIterator> { + using T = typename TypeTraits::ScalarType; + using ArrayT = typename TypeTraits::ArrayType; + using offset_type = typename Type::offset_type; + + const ArraySpan& arr; + const offset_type* offsets; + offset_type cur_offset; + const ArraySpan& values; + const uint8_t* data; + int64_t position; + + explicit ArrayIterator(const ArraySpan& arr) + : arr(arr), + offsets(reinterpret_cast(arr.buffers[1].data)), + cur_offset(offsets[arr.offset]), + values(arr.child_data[0]), + position(arr.offset) {} + + T operator()() { + offset_type next_offset = offsets[++position]; + const auto len = next_offset - cur_offset; + const auto null_count = values.null_count; + const std::shared_ptr nulls_buffer = + null_count > 0 ? *values.buffers[0].owner : nullptr; + std::vector> bufs = {nulls_buffer, *values.buffers[1].owner}; + const auto child_offset = values.offset; + + // TODO: do not hard code child type. also need to be aware of non-primitive children + const auto array_data = ArrayData::Make(int32(), len, std::move(bufs), null_count, + cur_offset + child_offset); + const auto array = MakeArray(array_data); + const auto result = T{array}; + + cur_offset = next_offset; + + return result; + } +}; + template <> struct ArrayIterator { const ArraySpan& arr; @@ -390,6 +438,12 @@ struct UnboxScalar> { } }; +template +struct UnboxScalar> { + using T = typename TypeTraits::ScalarType; + static const T& Unbox(const Scalar& val) { return checked_cast(val); } +}; + template <> struct UnboxScalar { using T = Decimal32; @@ -1383,6 +1437,22 @@ ArrayKernelExec GenerateDecimal(detail::GetTypeId get_id) { } } +// Generate a kernel given a templated functor for list types +// +// See "Numeric" above for description of the generator functor +template