Index: include/llvm/ADT/DenseMap.h =================================================================== --- include/llvm/ADT/DenseMap.h +++ include/llvm/ADT/DenseMap.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,9 @@ // implementation without requiring two members. template struct DenseMapPair : public std::pair { + + using std::pair::pair; + KeyT &getFirst() { return std::pair::first; } const KeyT &getFirst() const { return std::pair::first; } ValueT &getSecond() { return std::pair::second; } @@ -640,6 +644,31 @@ } }; +/// Equality comparison for DenseMapBase. +template +bool operator==( + const DenseMapBase &LHS, + const DenseMapBase &RHS) { + if (LHS.size() != RHS.size()) + return false; + + for (auto LHSI = LHS.begin(), RHSI = RHS.begin(), E = LHS.end(); LHSI != E; + ++LHSI, ++RHSI) + if (*LHSI != *RHSI) + return false; + return true; +} + +/// Inequality comparison for DenseMapBase. +template +bool operator!=( + const DenseMapBase &LHS, + const DenseMapBase &RHS) { + return !(LHS == RHS); +} + template , typename BucketT = llvm::detail::DenseMapPair> @@ -677,6 +706,11 @@ this->insert(I, E); } + DenseMap(std::initializer_list Vals) { + init(Vals.size()); + this->insert(Vals.begin(), Vals.end()); + } + ~DenseMap() { this->destroyAll(); operator delete(Buckets); Index: include/llvm/ADT/DenseSet.h =================================================================== --- include/llvm/ADT/DenseSet.h +++ include/llvm/ADT/DenseSet.h @@ -16,6 +16,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/type_traits.h" #include #include @@ -67,7 +68,7 @@ explicit DenseSetImpl(unsigned InitialReserve = 0) : TheMap(InitialReserve) {} DenseSetImpl(std::initializer_list Elems) - : DenseSetImpl(Elems.size()) { + : DenseSetImpl(NextPowerOf2(Elems.size())) { insert(Elems.begin(), Elems.end()); } @@ -214,6 +215,27 @@ } }; +/// Equality comparison for DenseSet. +template +bool operator==(const DenseSetImpl &LHS, + const DenseSetImpl &RHS) { + if (LHS.size() != RHS.size()) + return false; + + for (auto LHSI = LHS.begin(), RHSI = RHS.begin(), E = LHS.end(); LHSI != E; + ++LHSI, ++RHSI) + if (*LHSI != *RHSI) + return false; + return true; +} + +/// Inequality comparison for DenseSet. +template +bool operator!=(const DenseSetImpl &LHS, + const DenseSetImpl &RHS) { + return !(LHS == RHS); +} + } // end namespace detail /// Implements a dense probed hash-table based set. Index: unittests/ADT/DenseMapTest.cpp =================================================================== --- unittests/ADT/DenseMapTest.cpp +++ unittests/ADT/DenseMapTest.cpp @@ -362,6 +362,26 @@ } // anonymous namespace +// Test initializer list construction. +TEST(DenseMapCustomTest, InitializerList) { + DenseMap M({{0, 0}, {0, 1}, {1, 2}}); + EXPECT_EQ(2u, M.size()); + EXPECT_EQ(1u, M.count(0)); + EXPECT_EQ(0, M[0]); + EXPECT_EQ(1u, M.count(1)); + EXPECT_EQ(2, M[1]); +} + +// Test initializer list construction. +TEST(DenseMapCustomTest, EqualityComparison) { + DenseMap M1({{0, 0}, {1, 2}}); + DenseMap M2({{0, 0}, {1, 2}}); + DenseMap M3({{0, 0}, {1, 3}}); + + EXPECT_EQ(M1, M2); + EXPECT_NE(M1, M3); +} + // Test for the default minimum size of a DenseMap TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) { // IF THIS VALUE CHANGE, please update InitialSizeTest, InitFromIterator, and Index: unittests/ADT/DenseSetTest.cpp =================================================================== --- unittests/ADT/DenseSetTest.cpp +++ unittests/ADT/DenseSetTest.cpp @@ -121,6 +121,15 @@ EXPECT_TRUE(set.find_as("d") == set.end()); } +TYPED_TEST(DenseSetTest, EqualityComparisonTest) { + TypeParam set1({1, 2, 3}); + TypeParam set2({1,2,3}); + TypeParam set3({1,2,4}); + + EXPECT_EQ(set1, set2); + EXPECT_NE(set1, set3); +} + // Simple class that counts how many moves and copy happens when growing a map struct CountCopyAndMove { static int Move;