This is an automated email from the ASF dual-hosted git repository.
raulcd pushed a commit to branch maint-25.0.0
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/maint-25.0.0 by this push:
new 61ca7a9979 GH-50295: [C++][R] #include <ranges> in vector_select_k.cc
breaks macOS CRAN and wasm builds (#50297)
61ca7a9979 is described below
commit 61ca7a99796b31c96dfd3a934d1d0de7e812d7f8
Author: Nic Crane <[email protected]>
AuthorDate: Wed Jul 1 21:57:07 2026 +0100
GH-50295: [C++][R] #include <ranges> in vector_select_k.cc breaks macOS
CRAN and wasm builds (#50297)
### Rationale for this change
R build failures due CRAN toolchain
### What changes are included in this PR?
Use version of functions available on CRAN toolchain
### Are these changes tested?
By existing CI jobs, and additional unit tests.
### Are there any user-facing changes?
No
* GitHub Issue: #50295
Lead-authored-by: Nic Crane <[email protected]>
Co-authored-by: Antoine Pitrou <[email protected]>
Signed-off-by: Nic Crane <[email protected]>
---
cpp/src/arrow/compute/kernels/select_k_test.cc | 366 ++++++++++++++++++++---
cpp/src/arrow/compute/kernels/vector_select_k.cc | 18 +-
2 files changed, 331 insertions(+), 53 deletions(-)
diff --git a/cpp/src/arrow/compute/kernels/select_k_test.cc
b/cpp/src/arrow/compute/kernels/select_k_test.cc
index 67e5d21463..47e4af5800 100644
--- a/cpp/src/arrow/compute/kernels/select_k_test.cc
+++ b/cpp/src/arrow/compute/kernels/select_k_test.cc
@@ -276,6 +276,26 @@ TEST_F(TestSelectKWithArray, FullSelectKNull) {
Check(uint8(), array_input, options, expected);
}
+TEST_F(TestSelectKWithArray, PartialSelectKAllNull) {
+ auto array_input = R"([null, null, null, null, null])";
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
+ auto options = SelectKOptions(4, sort_keys);
+ auto expected = R"([null, null, null, null])";
+ Check(uint8(), array_input, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ Check(uint8(), array_input, options, expected);
+}
+
+TEST_F(TestSelectKWithArray, FullSelectKAllNull) {
+ auto array_input = R"([null, null, null, null, null])";
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
+ auto options = SelectKOptions(10, sort_keys);
+ auto expected = R"([null, null, null, null, null])";
+ Check(uint8(), array_input, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ Check(uint8(), array_input, options, expected);
+}
+
TEST_F(TestSelectKWithArray, PartialSelectKNullNaN) {
auto array_input = R"([null, 30, NaN, 20, 10, null])";
std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Descending)};
@@ -293,9 +313,31 @@ TEST_F(TestSelectKWithArray, FullSelectKNullNaN) {
options.sort_keys[0].null_placement = NullPlacement::AtStart;
Check(float64(), array_input, options, "[null, null, NaN, 30, 20, 10]");
}
+
+TEST_F(TestSelectKWithArray, PartialSelectKAllNullAndNaN) {
+ auto array_input = R"([null, NaN, NaN, null, null])";
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
+ auto options = SelectKOptions(4, sort_keys);
+ auto expected = R"([NaN, NaN, null, null])";
+ Check(float64(), array_input, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ expected = R"([null, null, null, NaN])";
+ Check(float64(), array_input, options, expected);
+}
+
+TEST_F(TestSelectKWithArray, FullSelectKAllNullAndNaN) {
+ auto array_input = R"([null, NaN, NaN, null, null])";
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
+ auto options = SelectKOptions(10, sort_keys);
+ auto expected = R"([NaN, NaN, null, null, null])";
+ Check(float64(), array_input, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ expected = R"([null, null, null, NaN, NaN])";
+ Check(float64(), array_input, options, expected);
+}
+
// Test basic cases for chunked array
-template <typename ArrowType>
struct TestSelectKWithChunkedArray : public ::testing::Test {
TestSelectKWithChunkedArray() {}
@@ -323,6 +365,15 @@ struct TestSelectKWithChunkedArray : public
::testing::Test {
AssertSelectK<SortOrder::Ascending>(chunked_array, k);
}
+ void Check(const std::shared_ptr<DataType>& type, const
std::vector<std::string>& input,
+ const SelectKOptions& options, const std::string& expected) {
+ std::shared_ptr<ChunkedArray> actual;
+ auto input_array = ChunkedArrayFromJSON(type, input);
+ auto expected_array = ChunkedArrayFromJSON(type, {expected});
+ ASSERT_OK(this->DoSelectK(input_array, options, &actual));
+ AssertChunkedEqual(*expected_array, *actual);
+ }
+
void Check(const std::shared_ptr<ChunkedArray>& chunked_array,
const SelectKOptions& options,
const std::shared_ptr<ChunkedArray>& expected_array) {
@@ -343,9 +394,12 @@ struct TestSelectKWithChunkedArray : public
::testing::Test {
}
};
-TYPED_TEST_SUITE(TestSelectKWithChunkedArray, SelectKableTypes);
+template <typename ArrowType>
+struct TestSelectKWithChunkedArrayTyped : public TestSelectKWithChunkedArray
{};
+
+TYPED_TEST_SUITE(TestSelectKWithChunkedArrayTyped, SelectKableTypes);
-TYPED_TEST(TestSelectKWithChunkedArray, RandomValuesWithSlices) {
+TYPED_TEST(TestSelectKWithChunkedArrayTyped, RandomValuesWithSlices) {
Random<TypeParam> rand(0x61549225);
int length = 100;
for (auto null_probability : {0.0, 0.1, 0.5, 1.0}) {
@@ -361,62 +415,119 @@ TYPED_TEST(TestSelectKWithChunkedArray,
RandomValuesWithSlices) {
}
}
-TYPED_TEST(TestSelectKWithChunkedArray, PartialSelectKNull) {
- auto chunked_array = ChunkedArrayFromJSON(uint8(), {
- "[null, 1]",
- "[3, null, 2]",
- "[1]",
- });
+TEST_F(TestSelectKWithChunkedArray, PartialSelectKNull) {
+ auto chunked_array = std::vector<std::string>{
+ "[null, 1]",
+ "[3, null, 2]",
+ "[1]",
+ };
std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
auto options = SelectKOptions(3, sort_keys);
- auto expected = ChunkedArrayFromJSON(uint8(), {"[1, 1, 2]"});
- this->Check(chunked_array, options, expected);
+ auto expected = "[1, 1, 2]";
+ this->Check(uint8(), chunked_array, options, expected);
options.sort_keys[0].null_placement = NullPlacement::AtStart;
- expected = ChunkedArrayFromJSON(uint8(), {"[null, null, 1]"});
- this->Check(chunked_array, options, expected);
+ expected = "[null, null, 1]";
+ this->Check(uint8(), chunked_array, options, expected);
}
-TYPED_TEST(TestSelectKWithChunkedArray, FullSelectKNull) {
- auto chunked_array = ChunkedArrayFromJSON(uint8(), {
- "[null, 1]",
- "[3, null, 2]",
- "[1]",
- });
+TEST_F(TestSelectKWithChunkedArray, FullSelectKNull) {
+ auto chunked_array = std::vector<std::string>{
+ "[null, 1]",
+ "[3, null, 2]",
+ "[1]",
+ };
std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
auto options = SelectKOptions(10, sort_keys);
options.sort_keys[0].null_placement = NullPlacement::AtStart;
- auto expected = ChunkedArrayFromJSON(uint8(), {"[null, null, 1, 1, 2, 3]"});
- this->Check(chunked_array, options, expected);
+ auto expected = "[null, null, 1, 1, 2, 3]";
+ this->Check(uint8(), chunked_array, options, expected);
options.sort_keys[0].null_placement = NullPlacement::AtEnd;
- expected = ChunkedArrayFromJSON(uint8(), {"[1, 1, 2, 3, null, null]"});
- this->Check(chunked_array, options, expected);
+ expected = "[1, 1, 2, 3, null, null]";
+ this->Check(uint8(), chunked_array, options, expected);
}
-TYPED_TEST(TestSelectKWithChunkedArray, PartialSelectKNullNaN) {
- auto chunked_array = ChunkedArrayFromJSON(
- float64(), {"[null, 1]", "[3, null, NaN]", "[10, NaN, 2]", "[1]"});
+TEST_F(TestSelectKWithChunkedArray, PartialSelectKAllNull) {
+ auto chunked_array = std::vector<std::string>{
+ "[null, null]",
+ "[null, null, null]",
+ "[null]",
+ };
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
+ auto options = SelectKOptions(3, sort_keys);
+ auto expected = "[null, null, null]";
+ this->Check(uint8(), chunked_array, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ this->Check(uint8(), chunked_array, options, expected);
+}
+
+TEST_F(TestSelectKWithChunkedArray, FullSelectKAllNull) {
+ auto chunked_array = std::vector<std::string>{
+ "[null, null]",
+ "[null, null, null]",
+ "[null]",
+ };
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
+ auto options = SelectKOptions(10, sort_keys);
+ auto expected = "[null, null, null, null, null, null]";
+ this->Check(uint8(), chunked_array, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ this->Check(uint8(), chunked_array, options, expected);
+}
+
+TEST_F(TestSelectKWithChunkedArray, PartialSelectKNullNaN) {
+ auto chunked_array =
+ std::vector<std::string>{"[null, 1]", "[3, null, NaN]", "[10, NaN, 2]",
"[1]"};
std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Descending)};
auto options = SelectKOptions(3, sort_keys);
options.sort_keys[0].null_placement = NullPlacement::AtStart;
- auto expected = ChunkedArrayFromJSON(float64(), {"[null, null, NaN]"});
- this->Check(chunked_array, options, expected);
+ auto expected = "[null, null, NaN]";
+ this->Check(float64(), chunked_array, options, expected);
options.sort_keys[0].null_placement = NullPlacement::AtEnd;
- expected = ChunkedArrayFromJSON(float64(), {"[10, 3, 2]"});
- this->Check(chunked_array, options, expected);
+ expected = "[10, 3, 2]";
+ this->Check(float64(), chunked_array, options, expected);
}
-TYPED_TEST(TestSelectKWithChunkedArray, FullSelectKNullNaN) {
- auto chunked_array = ChunkedArrayFromJSON(
- float64(), {"[null, 1]", "[3, null, NaN]", "[10, NaN, 2]", "[1]"});
+TEST_F(TestSelectKWithChunkedArray, FullSelectKNullNaN) {
+ auto chunked_array =
+ std::vector<std::string>{"[null, 1]", "[3, null, NaN]", "[10, NaN, 2]",
"[1]"};
std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Descending)};
auto options = SelectKOptions(10, sort_keys);
options.sort_keys[0].null_placement = NullPlacement::AtStart;
- auto expected =
- ChunkedArrayFromJSON(float64(), {"[null, null, NaN, NaN, 10, 3, 2, 1,
1]"});
- this->Check(chunked_array, options, expected);
+ auto expected = "[null, null, NaN, NaN, 10, 3, 2, 1, 1]";
+ this->Check(float64(), chunked_array, options, expected);
options.sort_keys[0].null_placement = NullPlacement::AtEnd;
- expected = ChunkedArrayFromJSON(float64(), {"[10, 3, 2, 1, 1, NaN, NaN,
null, null]"});
- this->Check(chunked_array, options, expected);
+ expected = "[10, 3, 2, 1, 1, NaN, NaN, null, null]";
+ this->Check(float64(), chunked_array, options, expected);
+}
+
+TEST_F(TestSelectKWithChunkedArray, PartialSelectKAllNullAndNaN) {
+ auto chunked_array = std::vector<std::string>{
+ "[null, NaN]",
+ "[NaN, null, null]",
+ "[null]",
+ };
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
+ auto options = SelectKOptions(3, sort_keys);
+ auto expected = "[NaN, NaN, null]";
+ this->Check(float64(), chunked_array, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ expected = "[null, null, null]";
+ this->Check(float64(), chunked_array, options, expected);
+}
+
+TEST_F(TestSelectKWithChunkedArray, FullSelectKAllNullAndNaN) {
+ auto chunked_array = std::vector<std::string>{
+ "[null, NaN]",
+ "[NaN, null, null]",
+ "[null]",
+ };
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending)};
+ auto options = SelectKOptions(10, sort_keys);
+ auto expected = "[NaN, NaN, null, null, null, null]";
+ this->Check(float64(), chunked_array, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ expected = "[null, null, null, null, NaN, NaN]";
+ this->Check(float64(), chunked_array, options, expected);
}
template <typename ArrayType, SortOrder order>
@@ -790,6 +901,39 @@ TEST_F(TestSelectKWithRecordBatch, PartialSelectKNullNaN) {
Check(schema, batch_input, options, expected);
}
+TEST_F(TestSelectKWithRecordBatch, PartialSelectKAllNullNaN) {
+ auto schema = ::arrow::schema({
+ {field("a", float32())},
+ {field("b", float64())},
+ });
+ auto batch_input = R"([
+ {"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": NaN, "b": null},
+ {"a": null, "b": NaN},
+ {"a": NaN, "b": NaN},
+ {"a": null, "b": NaN}
+ ])";
+ std::vector<SortKey> sort_keys{
+ SortKey("a", SortOrder::Ascending, NullPlacement::AtStart),
+ SortKey("b", SortOrder::Descending)};
+ auto options = SelectKOptions(3, sort_keys);
+ auto expected = R"([{"a": null, "b": NaN},
+ {"a": null, "b": NaN},
+ {"a": null, "b": null}])";
+ Check(schema, batch_input, options, expected);
+ options.sort_keys[1].null_placement = NullPlacement::AtStart;
+ expected = R"([{"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": null, "b": NaN}])";
+ Check(schema, batch_input, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtEnd;
+ expected = R"([{"a": NaN, "b": null},
+ {"a": NaN, "b": NaN},
+ {"a": null, "b": null}])";
+ Check(schema, batch_input, options, expected);
+}
+
TEST_F(TestSelectKWithRecordBatch, FullSelectKNullNaN) {
auto schema = ::arrow::schema({
{field("a", float32())},
@@ -834,6 +978,51 @@ TEST_F(TestSelectKWithRecordBatch, FullSelectKNullNaN) {
Check(schema, batch_input, options, expected);
}
+TEST_F(TestSelectKWithRecordBatch, FullSelectKAllNullNaN) {
+ auto schema = ::arrow::schema({
+ {field("a", float32())},
+ {field("b", float64())},
+ });
+ auto batch_input = R"([
+ {"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": NaN, "b": null},
+ {"a": null, "b": NaN},
+ {"a": NaN, "b": NaN},
+ {"a": null, "b": NaN}
+ ])";
+ std::vector<SortKey> sort_keys{
+ SortKey("a", SortOrder::Ascending, NullPlacement::AtStart),
+ SortKey("b", SortOrder::Descending)};
+ auto options = SelectKOptions(10, sort_keys);
+ auto expected = R"([{"a": null, "b": NaN},
+ {"a": null, "b": NaN},
+ {"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": NaN, "b": NaN},
+ {"a": NaN, "b": null}
+ ])";
+ Check(schema, batch_input, options, expected);
+ options.sort_keys[1].null_placement = NullPlacement::AtStart;
+ expected = R"([{"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": null, "b": NaN},
+ {"a": null, "b": NaN},
+ {"a": NaN, "b": null},
+ {"a": NaN, "b": NaN}
+ ])";
+ Check(schema, batch_input, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtEnd;
+ expected = R"([{"a": NaN, "b": null},
+ {"a": NaN, "b": NaN},
+ {"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": null, "b": NaN},
+ {"a": null, "b": NaN}
+ ])";
+ Check(schema, batch_input, options, expected);
+}
+
TEST_F(TestSelectKWithRecordBatch, BottomKOneColumnKey) {
auto schema = ::arrow::schema({
{field("country", utf8())},
@@ -1147,26 +1336,26 @@ TEST_F(TestSelectKWithTable, FullSelectKNullNaN) {
{"a": 1, "b": 3},
{"a": 3, "b": null},
{"a": 6, "b": NaN},
- {"a": 6, "b": null},
+ {"a": 6, "b": null},
{"a": NaN, "b": 5},
- {"a": null, "b": 5},
+ {"a": null, "b": 5},
{"a": null, "b": null}])"};
Check(schema, input, options, expected);
options.sort_keys[0].null_placement = NullPlacement::AtStart;
expected = {R"([
- {"a": null, "b": 5},
+ {"a": null, "b": 5},
{"a": null, "b": null},
{"a": NaN, "b": 5},
{"a": 1, "b": 5},
{"a": 1, "b": 3},
{"a": 3, "b": null},
{"a": 6, "b": NaN},
- {"a": 6, "b": null}
+ {"a": 6, "b": null}
])"};
Check(schema, input, options, expected);
options.sort_keys[1].null_placement = NullPlacement::AtStart;
expected = {R"([
- {"a": null, "b": null},
+ {"a": null, "b": null},
{"a": null, "b": 5},
{"a": NaN, "b": 5},
{"a": 1, "b": 5},
@@ -1178,5 +1367,96 @@ TEST_F(TestSelectKWithTable, FullSelectKNullNaN) {
Check(schema, input, options, expected);
}
+TEST_F(TestSelectKWithTable, PartialSelectKAllNullNaN) {
+ auto schema = ::arrow::schema({
+ {field("a", float32())},
+ {field("b", float64())},
+ });
+ std::vector<std::string> input = {
+ R"([{"a": null, "b": null},
+ {"a": NaN, "b": null},
+ {"a": null, "b": NaN}
+ ])",
+ R"([{"a": null, "b": null},
+ {"a": NaN, "b": null},
+ {"a": NaN, "b": NaN}
+ ])"};
+
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending),
+ SortKey("b", SortOrder::Descending)};
+ auto options = SelectKOptions(3, sort_keys);
+
+ std::vector<std::string> expected = {
+ R"([{"a": NaN, "b": NaN},
+ {"a": NaN, "b": null},
+ {"a": NaN, "b": null}
+ ])"};
+ Check(schema, input, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ expected = {
+ R"([{"a": null, "b": NaN},
+ {"a": null, "b": null},
+ {"a": null, "b": null}
+ ])"};
+ Check(schema, input, options, expected);
+ options.sort_keys[1].null_placement = NullPlacement::AtStart;
+ expected = {
+ R"([{"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": null, "b": NaN}
+ ])"};
+ Check(schema, input, options, expected);
+}
+
+TEST_F(TestSelectKWithTable, FullSelectKAllNullNaN) {
+ auto schema = ::arrow::schema({
+ {field("a", float32())},
+ {field("b", float64())},
+ });
+ std::vector<std::string> input = {
+ R"([{"a": null, "b": null},
+ {"a": NaN, "b": null},
+ {"a": null, "b": NaN}
+ ])",
+ R"([{"a": null, "b": null},
+ {"a": NaN, "b": null},
+ {"a": NaN, "b": NaN}
+ ])"};
+
+ std::vector<SortKey> sort_keys{SortKey("a", SortOrder::Ascending),
+ SortKey("b", SortOrder::Descending)};
+ auto options = SelectKOptions(10, sort_keys);
+
+ std::vector<std::string> expected = {
+ R"([{"a": NaN, "b": NaN},
+ {"a": NaN, "b": null},
+ {"a": NaN, "b": null},
+ {"a": null, "b": NaN},
+ {"a": null, "b": null},
+ {"a": null, "b": null}
+ ])"};
+ Check(schema, input, options, expected);
+ options.sort_keys[0].null_placement = NullPlacement::AtStart;
+ expected = {
+ R"([{"a": null, "b": NaN},
+ {"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": NaN, "b": NaN},
+ {"a": NaN, "b": null},
+ {"a": NaN, "b": null}
+ ])"};
+ Check(schema, input, options, expected);
+ options.sort_keys[1].null_placement = NullPlacement::AtStart;
+ expected = {
+ R"([{"a": null, "b": null},
+ {"a": null, "b": null},
+ {"a": null, "b": NaN},
+ {"a": NaN, "b": null},
+ {"a": NaN, "b": null},
+ {"a": NaN, "b": NaN}
+ ])"};
+ Check(schema, input, options, expected);
+}
+
} // namespace compute
} // namespace arrow
diff --git a/cpp/src/arrow/compute/kernels/vector_select_k.cc
b/cpp/src/arrow/compute/kernels/vector_select_k.cc
index cc37591965..ea072d179e 100644
--- a/cpp/src/arrow/compute/kernels/vector_select_k.cc
+++ b/cpp/src/arrow/compute/kernels/vector_select_k.cc
@@ -17,7 +17,6 @@
#include <algorithm>
#include <queue>
-#include <ranges>
#include <span>
#include "arrow/compute/function.h"
@@ -118,22 +117,22 @@ void HeapSortNonNullsToOutput(std::span<uint64_t>
non_null_input_range, Comparat
return;
}
std::span<uint64_t> heap = non_null_input_range.subspan(0,
output_range.size());
- std::ranges::make_heap(heap, cmp);
+ std::make_heap(heap.begin(), heap.end(), cmp);
std::span<uint64_t> remaining_input =
non_null_input_range.subspan(output_range.size());
for (uint64_t x_index : remaining_input) {
if (cmp(x_index, heap.front())) {
- std::ranges::pop_heap(heap, cmp);
+ std::pop_heap(heap.begin(), heap.end(), cmp);
heap.back() = x_index;
- std::ranges::push_heap(heap, cmp);
+ std::push_heap(heap.begin(), heap.end(), cmp);
}
}
// fill output in reverse when destructing,
// as the "worst" (next-to-would-have-been-replaced) element is at heap-top
- for (auto& reverse_out_iter : std::ranges::reverse_view(output_range)) {
- reverse_out_iter = heap.front(); // heap-top has the next element
- std::ranges::pop_heap(heap, cmp);
+ for (int64_t i = output_range.size(); i > 0; --i) {
+ output_range[i - 1] = heap.front(); // heap-top has the next element
+ std::pop_heap(heap.begin(), heap.end(), cmp);
// Decrease heap-size by one
heap = heap.first(heap.size() - 1);
}
@@ -422,9 +421,8 @@ class ChunkedArraySelector : public TypeVisitor {
// so the heap must have been completely filled
DCHECK_EQ(heap.size(), output.non_null_like_range.size());
- for (uint64_t& reverse_out_iter :
- std::ranges::reverse_view(output.non_null_like_range)) {
- reverse_out_iter =
+ for (int64_t i = output.non_null_like_range.size(); i > 0; --i) {
+ output.non_null_like_range[i - 1] =
heap.top().index + heap.top().offset; // heap-top has the next
element
heap.pop();
}