Index: llvm/include/llvm/ADT/MapVector.h =================================================================== --- llvm/include/llvm/ADT/MapVector.h +++ llvm/include/llvm/ADT/MapVector.h @@ -83,7 +83,10 @@ return Vector[I].second; } + // Returns a copy of the value. Only allowed if ValueT is copyable. ValueT lookup(const KeyT &Key) const { + static_assert(std::is_copy_constructible::value, + "Cannot call lookup() if ValueT is not copyable."); typename MapType::const_iterator Pos = Map.find(Key); return Pos == Map.end()? ValueT() : Vector[Pos->second].second; } @@ -100,6 +103,20 @@ return std::make_pair(begin() + I, false); } + std::pair insert(std::pair &&KV) { + // Copy KV.first into the map, then move it into the vector. + std::pair Pair = std::make_pair(KV.first, 0); + std::pair Result = Map.insert(Pair); + unsigned &I = Result.first->second; + if (Result.second) { + Vector.push_back( + std::make_pair(std::move(KV.first), std::move(KV.second))); + I = Vector.size() - 1; + return std::make_pair(std::prev(end()), true); + } + return std::make_pair(begin() + I, false); + } + size_type count(const KeyT &Key) const { typename MapType::const_iterator Pos = Map.find(Key); return Pos == Map.end()? 0 : 1; Index: llvm/unittests/ADT/MapVectorTest.cpp =================================================================== --- llvm/unittests/ADT/MapVectorTest.cpp +++ llvm/unittests/ADT/MapVectorTest.cpp @@ -148,6 +148,15 @@ } } +TEST(MapVectorTest, NonCopyable) { + MapVector> MV; + MV.insert(std::make_pair(1, llvm::make_unique(1))); + MV.insert(std::make_pair(2, llvm::make_unique(2))); + + ASSERT_EQ(MV.count(1), 1u); + ASSERT_EQ(*MV.find(2)->second, 2); +} + TEST(SmallMapVectorSmallTest, insert_pop) { SmallMapVector MV; std::pair::iterator, bool> R; @@ -257,6 +266,15 @@ } } +TEST(SmallMapVectorSmallTest, NonCopyable) { + SmallMapVector, 8> MV; + MV.insert(std::make_pair(1, llvm::make_unique(1))); + MV.insert(std::make_pair(2, llvm::make_unique(2))); + + ASSERT_EQ(MV.count(1), 1u); + ASSERT_EQ(*MV.find(2)->second, 2); +} + TEST(SmallMapVectorLargeTest, insert_pop) { SmallMapVector MV; std::pair::iterator, bool> R;