[llvm] [ADT] Add begin and end to EytzingerTableSpan and EytzingerTable (NFC) (PR #210478)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 17 19:55:23 PDT 2026
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/210478
This patch adds iterator and const_iterator type aliases as well as
begin() and end() methods to EytzingerTableSpan and EytzingerTable.
I'm going to be using these as part of the SecNameTable in the
Eytzinger layout.
RFC:
https://discourse.llvm.org/t/rfc-faster-sample-profile-loading/90957/8
Assisted-by: Antigravity
>From 23175686cb141ef3e655d78c7ffb576c2049e9a7 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Fri, 17 Jul 2026 19:47:59 -0700
Subject: [PATCH] [ADT] Add begin and end to EytzingerTableSpan and
EytzingerTable (NFC)
This patch adds iterator and const_iterator type aliases as well as
begin() and end() methods to EytzingerTableSpan and EytzingerTable.
I'm going to be using these as part of the SecNameTable in the
Eytzinger layout.
RFC:
https://discourse.llvm.org/t/rfc-faster-sample-profile-loading/90957/8
Assisted-by: Antigravity
---
llvm/include/llvm/ADT/Eytzinger.h | 13 ++++++++
llvm/unittests/ADT/EytzingerTest.cpp | 46 ++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/llvm/include/llvm/ADT/Eytzinger.h b/llvm/include/llvm/ADT/Eytzinger.h
index e3813331a59a7..685de6cc35e11 100644
--- a/llvm/include/llvm/ADT/Eytzinger.h
+++ b/llvm/include/llvm/ADT/Eytzinger.h
@@ -29,10 +29,15 @@ namespace llvm {
/// Eytzinger (breadth-first) order.
template <typename T> class EytzingerTableSpan {
public:
+ using iterator = const T *;
+ using const_iterator = const T *;
+
EytzingerTableSpan() = default;
EytzingerTableSpan(const T *Data, size_t NumEntries)
: Data(Data), NumEntries(NumEntries) {}
+ [[nodiscard]] iterator begin() const { return Data; }
+ [[nodiscard]] iterator end() const { return Data + NumEntries; }
[[nodiscard]] const T *data() const { return Data; }
[[nodiscard]] bool empty() const { return !Data || NumEntries == 0; }
[[nodiscard]] size_t size() const { return NumEntries; }
@@ -121,6 +126,9 @@ template <typename T> class EytzingerTable {
explicit EytzingerTable(std::vector<T> Buffer) : Storage(std::move(Buffer)) {}
public:
+ using iterator = typename std::vector<T>::const_iterator;
+ using const_iterator = typename std::vector<T>::const_iterator;
+
EytzingerTable() = default;
/// Construct an Eytzinger search tree from a vector of keys by sorting,
@@ -161,6 +169,11 @@ template <typename T> class EytzingerTable {
[[nodiscard]] bool isSorted() const { return asSpan().isSorted(); }
+ [[nodiscard]] iterator begin() { return Storage.begin(); }
+ [[nodiscard]] const_iterator begin() const { return Storage.begin(); }
+ [[nodiscard]] iterator end() { return Storage.end(); }
+ [[nodiscard]] const_iterator end() const { return Storage.end(); }
+
[[nodiscard]] const T *data() const { return Storage.data(); }
[[nodiscard]] size_t size() const { return Storage.size(); }
[[nodiscard]] bool empty() const { return Storage.empty(); }
diff --git a/llvm/unittests/ADT/EytzingerTest.cpp b/llvm/unittests/ADT/EytzingerTest.cpp
index e887d7cd279f2..17cd06b6a1443 100644
--- a/llvm/unittests/ADT/EytzingerTest.cpp
+++ b/llvm/unittests/ADT/EytzingerTest.cpp
@@ -20,6 +20,8 @@ TEST(EytzingerTest, EmptyTable) {
EXPECT_TRUE(Empty.empty());
EXPECT_EQ(Empty.size(), 0u);
EXPECT_EQ(Empty.data(), nullptr);
+ EXPECT_EQ(Empty.begin(), Empty.end());
+ EXPECT_EQ(Empty.begin(), nullptr);
EXPECT_TRUE(Empty.isSorted());
EXPECT_EQ(Empty.findIndex(42), std::nullopt);
EXPECT_FALSE(Empty.contains(42));
@@ -28,6 +30,7 @@ TEST(EytzingerTest, EmptyTable) {
EytzingerTableSpan<int> NullSpan(nullptr, 0);
EXPECT_TRUE(NullSpan.empty());
EXPECT_EQ(NullSpan.size(), 0u);
+ EXPECT_EQ(NullSpan.begin(), NullSpan.end());
EXPECT_TRUE(NullSpan.isSorted());
EXPECT_EQ(NullSpan.findIndex(42), std::nullopt);
EXPECT_FALSE(NullSpan.contains(42));
@@ -250,12 +253,15 @@ TEST(EytzingerTest, EytzingerTableEmptyAndSingle) {
auto EmptyTable = EytzingerTable<int>::create(std::vector<int>{});
EXPECT_TRUE(EmptyTable.empty());
EXPECT_EQ(EmptyTable.size(), 0u);
+ EXPECT_EQ(EmptyTable.begin(), EmptyTable.end());
EXPECT_TRUE(EmptyTable.isSorted());
EXPECT_FALSE(EmptyTable.contains(42));
auto SingleTable = EytzingerTable<int>::create(std::vector<int>{42, 42});
EXPECT_FALSE(SingleTable.empty());
EXPECT_EQ(SingleTable.size(), 1u);
+ EXPECT_NE(SingleTable.begin(), SingleTable.end());
+ EXPECT_EQ(*SingleTable.begin(), 42);
EXPECT_TRUE(SingleTable.isSorted());
EXPECT_EQ(SingleTable[0], 42);
EXPECT_TRUE(SingleTable.contains(42));
@@ -297,4 +303,44 @@ TEST(EytzingerTest, EytzingerTableHeterogeneousCreate) {
EXPECT_FALSE(Table.contains(uint64_t(999ULL)));
}
+TEST(EytzingerTest, EytzingerTableSpanBeginEnd) {
+ const int Data[] = {40, 20, 60, 10, 30, 50, 70};
+ EytzingerTableSpan<int> Span(Data, 7);
+
+ EXPECT_EQ(Span.begin(), Data);
+ EXPECT_EQ(Span.end(), Data + 7);
+ EXPECT_EQ(std::distance(Span.begin(), Span.end()), 7);
+
+ std::vector<int> Traversed(Span.begin(), Span.end());
+ std::vector<int> Expected = {40, 20, 60, 10, 30, 50, 70};
+ EXPECT_EQ(Traversed, Expected);
+
+ // Range-based for loop verification.
+ std::vector<int> RangeTraversed;
+ for (const int &Val : Span)
+ RangeTraversed.push_back(Val);
+ EXPECT_EQ(RangeTraversed, Expected);
+}
+
+TEST(EytzingerTest, EytzingerTableBeginEnd) {
+ std::vector<int> Unsorted = {70, 20, 40, 10, 60, 30, 50};
+ auto Table = EytzingerTable<int>::create(std::move(Unsorted));
+
+ EXPECT_EQ(std::distance(Table.begin(), Table.end()), 7);
+
+ std::vector<int> Traversed(Table.begin(), Table.end());
+ std::vector<int> Expected = {40, 20, 60, 10, 30, 50, 70};
+ EXPECT_EQ(Traversed, Expected);
+
+ // Range-based for loop verification on both non-const and const tables.
+ std::vector<int> RangeTraversed;
+ for (const int &Val : Table)
+ RangeTraversed.push_back(Val);
+ EXPECT_EQ(RangeTraversed, Expected);
+
+ const auto &ConstTable = Table;
+ std::vector<int> ConstTraversed(ConstTable.begin(), ConstTable.end());
+ EXPECT_EQ(ConstTraversed, Expected);
+}
+
} // namespace
More information about the llvm-commits
mailing list