diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h index 1f2721322e34..2a35c3d583f7 100644 --- a/llvm/include/llvm/ADT/DenseMap.h +++ b/llvm/include/llvm/ADT/DenseMap.h @@ -18,6 +18,7 @@ #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/EpochTracker.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/STLForwardCompat.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" @@ -811,10 +812,12 @@ public: this->insert(I, E); } - DenseMap(std::initializer_list Vals) { - init(Vals.size()); - this->insert(Vals.begin(), Vals.end()); - } + template + DenseMap(llvm::from_range_t, const RangeT &Range) + : DenseMap(adl_begin(Range), adl_end(Range)) {} + + DenseMap(std::initializer_list Vals) + : DenseMap(Vals.begin(), Vals.end()) {} ~DenseMap() { this->destroyAll(); @@ -985,6 +988,10 @@ public: this->insert(I, E); } + template + SmallDenseMap(llvm::from_range_t, const RangeT &Range) + : SmallDenseMap(adl_begin(Range), adl_end(Range)) {} + SmallDenseMap(std::initializer_list Vals) : SmallDenseMap(Vals.begin(), Vals.end()) {} diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp index bdfbc8557859..fdecfb7bb5b0 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp @@ -10,6 +10,7 @@ #include "CountCopyAndMove.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/DenseMapInfoVariant.h" +#include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringRef.h" #include "gmock/gmock.h" @@ -249,6 +250,25 @@ TYPED_TEST(DenseMapTest, CopyConstructorNotSmallTest) { EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]); } +// Test range constructors. +TYPED_TEST(DenseMapTest, RangeConstructorTest) { + using KeyAndValue = + std::pair; + KeyAndValue PlainArray[] = {{this->getKey(0), this->getValue(0)}, + {this->getKey(1), this->getValue(1)}}; + + TypeParam MapFromRange(llvm::from_range, PlainArray); + EXPECT_EQ(2u, MapFromRange.size()); + EXPECT_EQ(this->getValue(0), MapFromRange[this->getKey(0)]); + EXPECT_EQ(this->getValue(1), MapFromRange[this->getKey(1)]); + + TypeParam MapFromInitList({{this->getKey(0), this->getValue(1)}, + {this->getKey(1), this->getValue(2)}}); + EXPECT_EQ(2u, MapFromInitList.size()); + EXPECT_EQ(this->getValue(1), MapFromInitList[this->getKey(0)]); + EXPECT_EQ(this->getValue(2), MapFromInitList[this->getKey(1)]); +} + // Test copying from a default-constructed map. TYPED_TEST(DenseMapTest, CopyConstructorFromDefaultTest) { TypeParam copyMap(this->Map); @@ -726,6 +746,15 @@ TEST(DenseMapCustomTest, FindAsTest) { EXPECT_TRUE(map.find_as("d") == map.end()); } +TEST(DenseMapCustomTest, SmallDenseMapFromRange) { + std::pair PlainArray[] = {{0, "0"}, {1, "1"}, {2, "2"}}; + SmallDenseMap M(llvm::from_range, PlainArray); + EXPECT_EQ(3u, M.size()); + using testing::Pair; + EXPECT_THAT(M, testing::UnorderedElementsAre(Pair(0, "0"), Pair(1, "1"), + Pair(2, "2"))); +} + TEST(DenseMapCustomTest, SmallDenseMapInitializerList) { SmallDenseMap M = {{0, 0}, {0, 1}, {1, 2}}; EXPECT_EQ(2u, M.size());