[llvm] dcf03fe - [ADT] Add begin and end to EytzingerTableSpan and EytzingerTable (NFC) (#210478)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 19 07:37:12 PDT 2026


Author: Kazu Hirata
Date: 2026-07-19T07:37:07-07:00
New Revision: dcf03fefd46ea1426475c948925c9501af2f5495

URL: https://github.com/llvm/llvm-project/commit/dcf03fefd46ea1426475c948925c9501af2f5495
DIFF: https://github.com/llvm/llvm-project/commit/dcf03fefd46ea1426475c948925c9501af2f5495.diff

LOG: [ADT] Add begin and end to EytzingerTableSpan and EytzingerTable (NFC) (#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

Added: 
    

Modified: 
    llvm/include/llvm/ADT/Eytzinger.h
    llvm/unittests/ADT/EytzingerTest.cpp

Removed: 
    


################################################################################
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..23b65c84c05c5 100644
--- a/llvm/unittests/ADT/EytzingerTest.cpp
+++ b/llvm/unittests/ADT/EytzingerTest.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/ADT/Eytzinger.h"
 #include "llvm/Support/Endian.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -20,6 +21,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 +31,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 +254,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 +304,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());
+  const int Expected[] = {40, 20, 60, 10, 30, 50, 70};
+  EXPECT_THAT(Traversed, testing::ElementsAreArray(Expected));
+
+  // Range-based for loop verification.
+  std::vector<int> RangeTraversed;
+  for (const int &Val : Span)
+    RangeTraversed.push_back(Val);
+  EXPECT_THAT(RangeTraversed, testing::ElementsAreArray(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());
+  const int Expected[] = {40, 20, 60, 10, 30, 50, 70};
+  EXPECT_THAT(Traversed, testing::ElementsAreArray(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_THAT(RangeTraversed, testing::ElementsAreArray(Expected));
+
+  const auto &ConstTable = Table;
+  std::vector<int> ConstTraversed(ConstTable.begin(), ConstTable.end());
+  EXPECT_THAT(ConstTraversed, testing::ElementsAreArray(Expected));
+}
+
 } // namespace


        


More information about the llvm-commits mailing list