[PATCH] D135594: [ADT] Extend EnumeratedArray

Jannik Silvanus via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 10 08:46:40 PDT 2022


jsilvanus created this revision.
Herald added a project: All.
jsilvanus requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

EnumeratedArray is essentially a wrapper around a fixed-size
array that uses enum values instead of integers as indices.

- Add iterator support (begin/end/rbegin/rend), which enables the use of iterator/range based algorithms on EnumeratedArrays.
- Add common container typedefs (value_type etc.), allowing drop-in replacements of other containers in cases relying on these.
- Add a constructor that takes an std::initializer_list<T>.
- Make the size() function const.
- Add empty().

Iterator support slightly lowers the protection non-type-safe accesses,
because iterator arithmetic is not enum-based, and one can now use
*(begin() + IntIndex). However, it is and was also always possible to
just cast arbitrary indices to the enum type.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D135594

Files:
  llvm/include/llvm/ADT/EnumeratedArray.h


Index: llvm/include/llvm/ADT/EnumeratedArray.h
===================================================================
--- llvm/include/llvm/ADT/EnumeratedArray.h
+++ llvm/include/llvm/ADT/EnumeratedArray.h
@@ -16,6 +16,7 @@
 #define LLVM_ADT_ENUMERATEDARRAY_H
 
 #include <cassert>
+#include <iterator>
 
 namespace llvm {
 
@@ -24,12 +25,31 @@
           IndexType Size = 1 + static_cast<IndexType>(LargestEnum)>
 class EnumeratedArray {
 public:
+  using value_type = ValueType;
+  using iterator = ValueType *;
+  using const_iterator = const ValueType *;
+
+  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+  using reverse_iterator = std::reverse_iterator<iterator>;
+
+  using reference = ValueType &;
+  using const_reference = const ValueType &;
+  using pointer = ValueType *;
+  using const_pointer = const ValueType *;
+
   EnumeratedArray() = default;
   EnumeratedArray(ValueType V) {
     for (IndexType IX = 0; IX < Size; ++IX) {
       Underlying[IX] = 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);
+    }
+  }
+
   inline const ValueType &operator[](const Enumeration Index) const {
     auto IX = static_cast<const IndexType>(Index);
     assert(IX >= 0 && IX < Size && "Index is out of bounds.");
@@ -40,7 +60,23 @@
         static_cast<const EnumeratedArray<ValueType, Enumeration, LargestEnum,
                                           IndexType, Size> &>(*this)[Index]);
   }
-  inline IndexType size() { return Size; }
+  inline IndexType size() const { return Size; }
+  inline bool empty() const { return size() != 0; }
+
+  inline iterator begin() { return Underlying; }
+  inline const_iterator begin() const { return Underlying; }
+
+  inline iterator end() { return begin() + size(); }
+  inline const_iterator end() const { return begin() + size(); }
+
+  inline reverse_iterator rbegin() { return reverse_iterator(end()); }
+  inline const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+  inline reverse_iterator rend() { return reverse_iterator(begin()); }
+  inline const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
 
 private:
   ValueType Underlying[Size];


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D135594.466517.patch
Type: text/x-patch
Size: 2375 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221010/6a11bb34/attachment.bin>


More information about the llvm-commits mailing list