in c/validation/adbc_validation_util.h [400:483]
void CompareArray(struct ArrowArrayView* array,
const std::vector<std::optional<T>>& values, int64_t offset = 0,
int64_t length = -1) {
if (length == -1) {
length = array->length;
}
ASSERT_EQ(static_cast<int64_t>(values.size()), length);
int64_t i = offset;
for (const auto& v : values) {
SCOPED_TRACE("Array index " + std::to_string(i));
if (v.has_value()) {
ASSERT_FALSE(ArrowArrayViewIsNull(array, i));
if constexpr (std::is_same<T, float>::value || std::is_same<T, double>::value) {
ASSERT_NE(array->buffer_views[1].data.data, nullptr);
ASSERT_EQ(ArrowArrayViewGetDoubleUnsafe(array, i), *v);
} else if constexpr (std::is_same<T, bool>::value ||
std::is_same<T, int8_t>::value ||
std::is_same<T, int16_t>::value ||
std::is_same<T, int32_t>::value ||
std::is_same<T, int64_t>::value) {
ASSERT_NE(array->buffer_views[1].data.data, nullptr);
ASSERT_EQ(ArrowArrayViewGetIntUnsafe(array, i), *v);
} else if constexpr (std::is_same<T, uint8_t>::value ||
std::is_same<T, uint16_t>::value ||
std::is_same<T, uint32_t>::value ||
std::is_same<T, uint64_t>::value) {
ASSERT_NE(array->buffer_views[1].data.data, nullptr);
ASSERT_EQ(ArrowArrayViewGetUIntUnsafe(array, i), *v);
} else if constexpr (std::is_same<T, std::string>::value) {
struct ArrowStringView view = ArrowArrayViewGetStringUnsafe(array, i);
std::string str(view.data, view.size_bytes);
ASSERT_EQ(*v, str);
} else if constexpr (std::is_same<T, std::vector<std::byte>>::value) {
struct ArrowBufferView view = ArrowArrayViewGetBytesUnsafe(array, i);
ASSERT_EQ(v->size(), view.size_bytes);
for (int64_t i = 0; i < view.size_bytes; i++) {
ASSERT_EQ((*v)[i], std::byte{view.data.as_uint8[i]});
}
} else if constexpr (std::is_same<T, ArrowInterval*>::value) {
ASSERT_NE(array->buffer_views[1].data.data, nullptr);
struct ArrowInterval interval;
ArrowIntervalInit(&interval, ArrowType::NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO);
ArrowArrayViewGetIntervalUnsafe(array, i, &interval);
ASSERT_EQ(interval.months, (*v)->months);
ASSERT_EQ(interval.days, (*v)->days);
ASSERT_EQ(interval.ns, (*v)->ns);
} else if constexpr (
// Possibly a more effective way to do this using template magic
// Not included but possible are the std::optional<> variants of this
std::is_same<T, std::vector<bool>>::value ||
std::is_same<T, std::vector<int8_t>>::value ||
std::is_same<T, std::vector<int16_t>>::value ||
std::is_same<T, std::vector<int32_t>>::value ||
std::is_same<T, std::vector<int64_t>>::value ||
std::is_same<T, std::vector<uint8_t>>::value ||
std::is_same<T, std::vector<uint16_t>>::value ||
std::is_same<T, std::vector<uint32_t>>::value ||
std::is_same<T, std::vector<uint64_t>>::value ||
std::is_same<T, std::vector<double>>::value ||
std::is_same<T, std::vector<float>>::value ||
std::is_same<T, std::vector<std::string>>::value ||
std::is_same<T, std::vector<std::vector<std::byte>>>::value) {
using child_t = typename T::value_type;
std::vector<std::optional<child_t>> value_nullable;
for (const auto& child_value : *v) {
value_nullable.push_back(child_value);
}
SCOPED_TRACE("List item");
int64_t child_offset = ArrowArrayViewListChildOffset(array, i);
int64_t child_length = ArrowArrayViewListChildOffset(array, i + 1) - child_offset;
CompareArray<child_t>(array->children[0], value_nullable, child_offset,
child_length);
} else {
static_assert(!sizeof(T), "Not yet implemented");
}
} else {
ASSERT_TRUE(ArrowArrayViewIsNull(array, i));
}
i++;
}
}