Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

kazutakahirata
Copy link
Contributor

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.

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.
@llvmbot
Copy link
Member

llvmbot commented Sep 13, 2025

@llvm/pr-subscribers-llvm-adt

Author: Kazu Hirata (kazutakahirata)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/158407.diff

1 Files Affected:

  • (modified) llvm/include/llvm/ADT/EnumeratedArray.h (+17-27)
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

Copy link
Member

@kuhar kuhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. I think the side-effect is that this now allows for 0-sized arrays. Could we add a test for this?

Underlying[IX] = V;
}
}
EnumeratedArray(ValueType V) { Underlying.fill(V); }
EnumeratedArray(std::initializer_list<ValueType> Init) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a llvm::copy, no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants