1 //===- llvm/ADT/EnumeratedArray.h - Enumerated Array-------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file defines an array type that can be indexed using scoped enum
11 /// values.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_ADT_ENUMERATEDARRAY_H
16 #define LLVM_ADT_ENUMERATEDARRAY_H
17 
18 #include <cassert>
19 #include <iterator>
20 
21 namespace llvm {
22 
23 template <typename ValueType, typename Enumeration,
24           Enumeration LargestEnum = Enumeration::Last, typename IndexType = int,
25           IndexType Size = 1 + static_cast<IndexType>(LargestEnum)>
26 class EnumeratedArray {
27 public:
28   using iterator = ValueType *;
29   using const_iterator = const ValueType *;
30 
31   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
32   using reverse_iterator = std::reverse_iterator<iterator>;
33 
34   using value_type = ValueType;
35   using reference = ValueType &;
36   using const_reference = const ValueType &;
37   using pointer = ValueType *;
38   using const_pointer = const ValueType *;
39 
40   EnumeratedArray() = default;
EnumeratedArray(ValueType V)41   EnumeratedArray(ValueType V) {
42     for (IndexType IX = 0; IX < Size; ++IX) {
43       Underlying[IX] = V;
44     }
45   }
EnumeratedArray(std::initializer_list<ValueType> Init)46   EnumeratedArray(std::initializer_list<ValueType> Init) {
47     assert(Init.size() == Size && "Incorrect initializer size");
48     for (IndexType IX = 0; IX < Size; ++IX) {
49       Underlying[IX] = *(Init.begin() + IX);
50     }
51   }
52 
53   const ValueType &operator[](Enumeration Index) const {
54     auto IX = static_cast<IndexType>(Index);
55     assert(IX >= 0 && IX < Size && "Index is out of bounds.");
56     return Underlying[IX];
57   }
58   ValueType &operator[](Enumeration Index) {
59     return const_cast<ValueType &>(
60         static_cast<const EnumeratedArray<ValueType, Enumeration, LargestEnum,
61                                           IndexType, Size> &>(*this)[Index]);
62   }
size()63   IndexType size() const { return Size; }
empty()64   bool empty() const { return size() == 0; }
65 
begin()66   iterator begin() { return Underlying; }
begin()67   const_iterator begin() const { return Underlying; }
68 
end()69   iterator end() { return begin() + size(); }
end()70   const_iterator end() const { return begin() + size(); }
71 
rbegin()72   reverse_iterator rbegin() { return reverse_iterator(end()); }
rbegin()73   const_reverse_iterator rbegin() const {
74     return const_reverse_iterator(end());
75   }
rend()76   reverse_iterator rend() { return reverse_iterator(begin()); }
rend()77   const_reverse_iterator rend() const {
78     return const_reverse_iterator(begin());
79   }
80 
81 private:
82   ValueType Underlying[Size];
83 };
84 
85 } // namespace llvm
86 
87 #endif // LLVM_ADT_ENUMERATEDARRAY_H
88