Skip to content

Commit 1633e0b

Browse files
authored
[ADT] Add from_range constructor for (Small)DenseMap (#153515)
This follows how we support range construction for (Small)DenseSet.
1 parent e3dcdb6 commit 1633e0b

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

llvm/include/llvm/ADT/DenseMap.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/ADT/DenseMapInfo.h"
1919
#include "llvm/ADT/EpochTracker.h"
2020
#include "llvm/ADT/STLExtras.h"
21+
#include "llvm/ADT/STLForwardCompat.h"
2122
#include "llvm/Support/AlignOf.h"
2223
#include "llvm/Support/Compiler.h"
2324
#include "llvm/Support/MathExtras.h"
@@ -811,10 +812,12 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
811812
this->insert(I, E);
812813
}
813814

814-
DenseMap(std::initializer_list<typename BaseT::value_type> Vals) {
815-
init(Vals.size());
816-
this->insert(Vals.begin(), Vals.end());
817-
}
815+
template <typename RangeT>
816+
DenseMap(llvm::from_range_t, const RangeT &Range)
817+
: DenseMap(adl_begin(Range), adl_end(Range)) {}
818+
819+
DenseMap(std::initializer_list<typename BaseT::value_type> Vals)
820+
: DenseMap(Vals.begin(), Vals.end()) {}
818821

819822
~DenseMap() {
820823
this->destroyAll();
@@ -985,6 +988,10 @@ class SmallDenseMap
985988
this->insert(I, E);
986989
}
987990

991+
template <typename RangeT>
992+
SmallDenseMap(llvm::from_range_t, const RangeT &Range)
993+
: SmallDenseMap(adl_begin(Range), adl_end(Range)) {}
994+
988995
SmallDenseMap(std::initializer_list<typename BaseT::value_type> Vals)
989996
: SmallDenseMap(Vals.begin(), Vals.end()) {}
990997

llvm/unittests/ADT/DenseMapTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "CountCopyAndMove.h"
1111
#include "llvm/ADT/DenseMapInfo.h"
1212
#include "llvm/ADT/DenseMapInfoVariant.h"
13+
#include "llvm/ADT/STLForwardCompat.h"
1314
#include "llvm/ADT/SmallSet.h"
1415
#include "llvm/ADT/StringRef.h"
1516
#include "gmock/gmock.h"
@@ -249,6 +250,25 @@ TYPED_TEST(DenseMapTest, CopyConstructorNotSmallTest) {
249250
EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
250251
}
251252

253+
// Test range constructors.
254+
TYPED_TEST(DenseMapTest, RangeConstructorTest) {
255+
using KeyAndValue =
256+
std::pair<typename TypeParam::key_type, typename TypeParam::mapped_type>;
257+
KeyAndValue PlainArray[] = {{this->getKey(0), this->getValue(0)},
258+
{this->getKey(1), this->getValue(1)}};
259+
260+
TypeParam MapFromRange(llvm::from_range, PlainArray);
261+
EXPECT_EQ(2u, MapFromRange.size());
262+
EXPECT_EQ(this->getValue(0), MapFromRange[this->getKey(0)]);
263+
EXPECT_EQ(this->getValue(1), MapFromRange[this->getKey(1)]);
264+
265+
TypeParam MapFromInitList({{this->getKey(0), this->getValue(1)},
266+
{this->getKey(1), this->getValue(2)}});
267+
EXPECT_EQ(2u, MapFromInitList.size());
268+
EXPECT_EQ(this->getValue(1), MapFromInitList[this->getKey(0)]);
269+
EXPECT_EQ(this->getValue(2), MapFromInitList[this->getKey(1)]);
270+
}
271+
252272
// Test copying from a default-constructed map.
253273
TYPED_TEST(DenseMapTest, CopyConstructorFromDefaultTest) {
254274
TypeParam copyMap(this->Map);
@@ -726,6 +746,15 @@ TEST(DenseMapCustomTest, FindAsTest) {
726746
EXPECT_TRUE(map.find_as("d") == map.end());
727747
}
728748

749+
TEST(DenseMapCustomTest, SmallDenseMapFromRange) {
750+
std::pair<int, StringRef> PlainArray[] = {{0, "0"}, {1, "1"}, {2, "2"}};
751+
SmallDenseMap<int, StringRef> M(llvm::from_range, PlainArray);
752+
EXPECT_EQ(3u, M.size());
753+
using testing::Pair;
754+
EXPECT_THAT(M, testing::UnorderedElementsAre(Pair(0, "0"), Pair(1, "1"),
755+
Pair(2, "2")));
756+
}
757+
729758
TEST(DenseMapCustomTest, SmallDenseMapInitializerList) {
730759
SmallDenseMap<int, int> M = {{0, 0}, {0, 1}, {1, 2}};
731760
EXPECT_EQ(2u, M.size());

0 commit comments

Comments
 (0)