[llvm] r329523 - [ADT] Fix MapVector when 'Map::mapped_type != unsigned'.
Eric Fiselier via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 8 01:48:59 PDT 2018
Author: ericwf
Date: Sun Apr 8 01:48:58 2018
New Revision: 329523
URL: http://llvm.org/viewvc/llvm-project?rev=329523&view=rev
Log:
[ADT] Fix MapVector when 'Map::mapped_type != unsigned'.
Previously MapVector assumed `Map::mapped_type` was `unsigned`.
This caused problems when using MapVector with a user-specified
map where this didn't hold (For example StringMap<unsigned>).
This patch adjusts MapVector to use the same type as the underlying
map, avoiding reference binding errors in functions like `insert`.
Modified:
llvm/trunk/include/llvm/ADT/MapVector.h
llvm/trunk/unittests/ADT/MapVectorTest.cpp
Modified: llvm/trunk/include/llvm/ADT/MapVector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/MapVector.h?rev=329523&r1=329522&r2=329523&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/MapVector.h (original)
+++ llvm/trunk/include/llvm/ADT/MapVector.h Sun Apr 8 01:48:58 2018
@@ -39,6 +39,10 @@ class MapVector {
MapType Map;
VectorType Vector;
+ static_assert(
+ std::is_integral<typename MapType::mapped_type>::value,
+ "The mapped_type of the specified Map must be an integral type");
+
public:
using value_type = typename VectorType::value_type;
using size_type = typename VectorType::size_type;
@@ -93,9 +97,9 @@ public:
}
ValueT &operator[](const KeyT &Key) {
- std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
+ std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(Key, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
- unsigned &I = Result.first->second;
+ auto &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::make_pair(Key, ValueT()));
I = Vector.size() - 1;
@@ -112,9 +116,9 @@ public:
}
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
- std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0);
+ std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
- unsigned &I = Result.first->second;
+ auto &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::make_pair(KV.first, KV.second));
I = Vector.size() - 1;
@@ -125,9 +129,9 @@ public:
std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
// Copy KV.first into the map, then move it into the vector.
- std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0);
+ std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
- unsigned &I = Result.first->second;
+ auto &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::move(KV));
I = Vector.size() - 1;
Modified: llvm/trunk/unittests/ADT/MapVectorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/MapVectorTest.cpp?rev=329523&r1=329522&r2=329523&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/MapVectorTest.cpp (original)
+++ llvm/trunk/unittests/ADT/MapVectorTest.cpp Sun Apr 8 01:48:58 2018
@@ -157,6 +157,45 @@ TEST(MapVectorTest, NonCopyable) {
ASSERT_EQ(*MV.find(2)->second, 2);
}
+template <class IntType> struct MapVectorMappedTypeTest : ::testing::Test {
+ using int_type = IntType;
+};
+
+using MapIntTypes = ::testing::Types<int, long, long long, unsigned,
+ unsigned long, unsigned long long>;
+TYPED_TEST_CASE(MapVectorMappedTypeTest, MapIntTypes);
+
+TYPED_TEST(MapVectorMappedTypeTest, DifferentDenseMap) {
+ // Test that using a map with a mapped type other than 'unsigned' compiles
+ // and works.
+ using IntType = typename TestFixture::int_type;
+ using MapVectorType = MapVector<int, int, DenseMap<int, IntType>>;
+
+ MapVectorType MV;
+ std::pair<typename MapVectorType::iterator, bool> R;
+
+ R = MV.insert(std::make_pair(1, 2));
+ ASSERT_EQ(R.first, MV.begin());
+ EXPECT_EQ(R.first->first, 1);
+ EXPECT_EQ(R.first->second, 2);
+ EXPECT_TRUE(R.second);
+
+ const std::pair<int, int> Elem(1, 3);
+ R = MV.insert(Elem);
+ ASSERT_EQ(R.first, MV.begin());
+ EXPECT_EQ(R.first->first, 1);
+ EXPECT_EQ(R.first->second, 2);
+ EXPECT_FALSE(R.second);
+
+ int& value = MV[4];
+ EXPECT_EQ(value, 0);
+ value = 5;
+
+ EXPECT_EQ(MV.size(), 2u);
+ EXPECT_EQ(MV[1], 2);
+ EXPECT_EQ(MV[4], 5);
+}
+
TEST(SmallMapVectorSmallTest, insert_pop) {
SmallMapVector<int, int, 32> MV;
std::pair<SmallMapVector<int, int, 32>::iterator, bool> R;
More information about the llvm-commits
mailing list