diff --git a/llvm/include/llvm/ADT/EnumeratedArray.h b/llvm/include/llvm/ADT/EnumeratedArray.h --- a/llvm/include/llvm/ADT/EnumeratedArray.h +++ b/llvm/include/llvm/ADT/EnumeratedArray.h @@ -16,6 +16,7 @@ #define LLVM_ADT_ENUMERATEDARRAY_H #include +#include namespace llvm { @@ -24,23 +25,58 @@ IndexType Size = 1 + static_cast(LargestEnum)> class EnumeratedArray { public: + using iterator = ValueType *; + using const_iterator = const ValueType *; + + using const_reverse_iterator = std::reverse_iterator; + using reverse_iterator = std::reverse_iterator; + + using value_type = ValueType; + 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; } } - inline const ValueType &operator[](const Enumeration Index) const { - auto IX = static_cast(Index); + EnumeratedArray(std::initializer_list Init) { + assert(Init.size() == Size && "Incorrect initializer size"); + for (IndexType IX = 0; IX < Size; ++IX) { + Underlying[IX] = *(Init.begin() + IX); + } + } + + const ValueType &operator[](Enumeration Index) const { + auto IX = static_cast(Index); assert(IX >= 0 && IX < Size && "Index is out of bounds."); return Underlying[IX]; } - inline ValueType &operator[](const Enumeration Index) { + ValueType &operator[](Enumeration Index) { return const_cast( static_cast &>(*this)[Index]); } - inline IndexType size() { return Size; } + 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()); + } private: ValueType Underlying[Size]; diff --git a/llvm/unittests/ADT/EnumeratedArrayTest.cpp b/llvm/unittests/ADT/EnumeratedArrayTest.cpp --- a/llvm/unittests/ADT/EnumeratedArrayTest.cpp +++ b/llvm/unittests/ADT/EnumeratedArrayTest.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/EnumeratedArray.h" #include "gtest/gtest.h" +#include namespace llvm { @@ -46,6 +47,79 @@ EXPECT_TRUE(Array2[Colors::Red]); EXPECT_FALSE(Array2[Colors::Blue]); EXPECT_TRUE(Array2[Colors::Green]); + + EnumeratedArray Array3 = {10.0, 11.0, + 12.0}; + EXPECT_EQ(Array3[Colors::Red], 10.0); + EXPECT_EQ(Array3[Colors::Blue], 11.0); + EXPECT_EQ(Array3[Colors::Green], 12.0); +} + +//===--------------------------------------------------------------------===// +// Test size and empty function +//===--------------------------------------------------------------------===// + +TEST(EnumeratedArray, Size) { + + enum class Colors { Red, Blue, Green, Last = Green }; + + EnumeratedArray Array; + const auto &ConstArray = Array; + + EXPECT_EQ(ConstArray.size(), 3u); + EXPECT_EQ(ConstArray.empty(), false); +} + +//===--------------------------------------------------------------------===// +// Test iterators +//===--------------------------------------------------------------------===// + +TEST(EnumeratedArray, Iterators) { + + enum class Colors { Red, Blue, Green, Last = Green }; + + EnumeratedArray Array; + const auto &ConstArray = Array; + + Array[Colors::Red] = 1.0; + Array[Colors::Blue] = 2.0; + Array[Colors::Green] = 3.0; + + EXPECT_EQ(*(Array.begin() + 0), 1.0); + EXPECT_EQ(*(Array.begin() + 1), 2.0); + EXPECT_EQ(*(Array.begin() + 2), 3.0); + EXPECT_EQ(*(ConstArray.begin() + 0), 1.0); + EXPECT_EQ(*(ConstArray.begin() + 1), 2.0); + EXPECT_EQ(*(ConstArray.begin() + 2), 3.0); + + EXPECT_EQ(*(Array.rbegin() + 0), 3.0); + EXPECT_EQ(*(Array.rbegin() + 1), 2.0); + EXPECT_EQ(*(Array.rbegin() + 2), 1.0); + EXPECT_EQ(*(ConstArray.rbegin() + 0), 3.0); + EXPECT_EQ(*(ConstArray.rbegin() + 1), 2.0); + EXPECT_EQ(*(ConstArray.rbegin() + 2), 1.0); +} + +//===--------------------------------------------------------------------===// +// Test typedefs +//===--------------------------------------------------------------------===// + +TEST(EnumeratedArray, Typedefs) { + + enum class Colors { Red, Blue, Green, Last = Green }; + + using Array = EnumeratedArray; + + static_assert(std::is_same::value, + "Incorrect value_type type"); + static_assert(std::is_same::value, + "Incorrect reference type!"); + static_assert(std::is_same::value, + "Incorrect pointer type!"); + static_assert(std::is_same::value, + "Incorrect const_reference type!"); + static_assert(std::is_same::value, + "Incorrect const_pointer type!"); } } // namespace llvm