[llvm] [ADT] Implement EnumeratedArray with std::array (NFC) (PR #158407)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 13 09:41:22 PDT 2025


https://github.com/kazutakahirata updated https://github.com/llvm/llvm-project/pull/158407

>From a7670770f165b3808c787050aa6fb8af6e56c399 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Wed, 3 Sep 2025 01:07:34 -0700
Subject: [PATCH 1/2] [ADT] Implement EnumeratedArray with std::array (NFC)

EnumeratedArray provides an std::array-like interface except that you
access the array with an enum index.  Now, the problem is that because
the underlying array is implemented as a C array, we have to mirror
what std::array would do:

  iterator end() { return begin() + size(); }

  reverse_iterator rbegin() { return reverse_iterator(end()); }

This patch switches to the std::array.  This way, we just have to
"forward" calls to begin, end, rbegin, rend, etc.  Also, we benefit
from std::array::fill in one of the constructors.
---
 llvm/include/llvm/ADT/EnumeratedArray.h | 44 ++++++++++---------------
 1 file changed, 17 insertions(+), 27 deletions(-)

diff --git a/llvm/include/llvm/ADT/EnumeratedArray.h b/llvm/include/llvm/ADT/EnumeratedArray.h
index 93e1327306175..de150dfa3c3c2 100644
--- a/llvm/include/llvm/ADT/EnumeratedArray.h
+++ b/llvm/include/llvm/ADT/EnumeratedArray.h
@@ -15,8 +15,8 @@
 #ifndef LLVM_ADT_ENUMERATEDARRAY_H
 #define LLVM_ADT_ENUMERATEDARRAY_H
 
+#include <array>
 #include <cassert>
-#include <iterator>
 
 namespace llvm {
 
@@ -24,12 +24,14 @@ template <typename ValueType, typename Enumeration,
           Enumeration LargestEnum = Enumeration::Last, typename IndexType = int,
           IndexType Size = 1 + static_cast<IndexType>(LargestEnum)>
 class EnumeratedArray {
-public:
-  using iterator = ValueType *;
-  using const_iterator = const ValueType *;
+  using ArrayTy = std::array<ValueType, Size>;
+  ArrayTy Underlying;
 
-  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-  using reverse_iterator = std::reverse_iterator<iterator>;
+public:
+  using iterator = typename ArrayTy::iterator;
+  using const_iterator = typename ArrayTy::const_iterator;
+  using reverse_iterator = typename ArrayTy::reverse_iterator;
+  using const_reverse_iterator = typename ArrayTy::const_reverse_iterator;
 
   using value_type = ValueType;
   using reference = ValueType &;
@@ -38,11 +40,7 @@ class EnumeratedArray {
   using const_pointer = const ValueType *;
 
   EnumeratedArray() = default;
-  EnumeratedArray(ValueType V) {
-    for (IndexType IX = 0; IX < Size; ++IX) {
-      Underlying[IX] = V;
-    }
-  }
+  EnumeratedArray(ValueType V) { Underlying.fill(V); }
   EnumeratedArray(std::initializer_list<ValueType> Init) {
     assert(Init.size() == Size && "Incorrect initializer size");
     for (IndexType IX = 0; IX < Size; ++IX) {
@@ -62,23 +60,15 @@ class EnumeratedArray {
   IndexType size() const { return Size; }
   bool empty() const { return size() == 0; }
 
-  iterator begin() { return Underlying; }
-  const_iterator begin() const { return Underlying; }
-
-  iterator end() { return begin() + size(); }
-  const_iterator end() const { return begin() + size(); }
-
-  reverse_iterator rbegin() { return reverse_iterator(end()); }
-  const_reverse_iterator rbegin() const {
-    return const_reverse_iterator(end());
-  }
-  reverse_iterator rend() { return reverse_iterator(begin()); }
-  const_reverse_iterator rend() const {
-    return const_reverse_iterator(begin());
-  }
+  iterator begin() { return Underlying.begin(); }
+  const_iterator begin() const { return Underlying.begin(); }
+  iterator end() { return Underlying.end(); }
+  const_iterator end() const { return Underlying.end(); }
 
-private:
-  ValueType Underlying[Size];
+  reverse_iterator rbegin() { return Underlying.rbegin(); }
+  const_reverse_iterator rbegin() const { return Underlying.rbegin(); }
+  reverse_iterator rend() { return Underlying.rend(); }
+  const_reverse_iterator rend() const { return Underlying.rend(); }
 };
 
 } // namespace llvm

>From dce2543984f4a3243d5a6cb171eb4de67a77c97c Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Sat, 13 Sep 2025 09:35:19 -0700
Subject: [PATCH 2/2] Address comments.

---
 llvm/include/llvm/ADT/EnumeratedArray.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/ADT/EnumeratedArray.h b/llvm/include/llvm/ADT/EnumeratedArray.h
index de150dfa3c3c2..2fe6be434f11b 100644
--- a/llvm/include/llvm/ADT/EnumeratedArray.h
+++ b/llvm/include/llvm/ADT/EnumeratedArray.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_ADT_ENUMERATEDARRAY_H
 #define LLVM_ADT_ENUMERATEDARRAY_H
 
+#include "llvm/ADT/STLExtras.h"
 #include <array>
 #include <cassert>
 
@@ -24,6 +25,7 @@ template <typename ValueType, typename Enumeration,
           Enumeration LargestEnum = Enumeration::Last, typename IndexType = int,
           IndexType Size = 1 + static_cast<IndexType>(LargestEnum)>
 class EnumeratedArray {
+  static_assert(Size > 0);
   using ArrayTy = std::array<ValueType, Size>;
   ArrayTy Underlying;
 
@@ -43,9 +45,7 @@ class EnumeratedArray {
   EnumeratedArray(ValueType V) { Underlying.fill(V); }
   EnumeratedArray(std::initializer_list<ValueType> Init) {
     assert(Init.size() == Size && "Incorrect initializer size");
-    for (IndexType IX = 0; IX < Size; ++IX) {
-      Underlying[IX] = *(Init.begin() + IX);
-    }
+    llvm::copy(Init, Underlying.begin());
   }
 
   const ValueType &operator[](Enumeration Index) const {



More information about the llvm-commits mailing list