Skip to content

Commit 07b8990

Browse files
authored
[ADT] Add C++17-style insert_or_assign for DenseMap (#94151)
add C++17-style insert_or_assign for DenseMap close: #94115
1 parent 991d2fb commit 07b8990

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

llvm/include/llvm/ADT/DenseMap.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,22 @@ class DenseMapBase : public DebugEpochBase {
312312
insert(*I);
313313
}
314314

315+
template <typename V>
316+
std::pair<iterator, bool> insert_or_assign(const KeyT &Key, V &&Val) {
317+
auto Ret = try_emplace(Key, std::forward<V>(Val));
318+
if (!Ret.second)
319+
Ret.first->second = std::forward<V>(Val);
320+
return Ret;
321+
}
322+
323+
template <typename V>
324+
std::pair<iterator, bool> insert_or_assign(KeyT &&Key, V &&Val) {
325+
auto Ret = try_emplace(std::move(Key), std::forward<V>(Val));
326+
if (!Ret.second)
327+
Ret.first->second = std::forward<V>(Val);
328+
return Ret;
329+
}
330+
315331
/// Returns the value associated to the key in the map if it exists. If it
316332
/// does not exist, emplace a default value for the key and returns a
317333
/// reference to the newly created value.

llvm/unittests/ADT/DenseMapTest.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,42 @@ TEST(DenseMapCustomTest, ReserveTest) {
475475
}
476476
}
477477

478+
TEST(DenseMapCustomTest, InsertOrAssignTest) {
479+
DenseMap<int, CountCopyAndMove> Map;
480+
481+
CountCopyAndMove val1(1);
482+
CountCopyAndMove::ResetCounts();
483+
auto try0 = Map.insert_or_assign(0, val1);
484+
EXPECT_TRUE(try0.second);
485+
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
486+
EXPECT_EQ(1, CountCopyAndMove::CopyConstructions);
487+
EXPECT_EQ(0, CountCopyAndMove::CopyAssignments);
488+
489+
CountCopyAndMove::ResetCounts();
490+
auto try1 = Map.insert_or_assign(0, val1);
491+
EXPECT_FALSE(try1.second);
492+
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
493+
EXPECT_EQ(0, CountCopyAndMove::CopyConstructions);
494+
EXPECT_EQ(1, CountCopyAndMove::CopyAssignments);
495+
496+
int key2 = 2;
497+
CountCopyAndMove val2(2);
498+
CountCopyAndMove::ResetCounts();
499+
auto try2 = Map.insert_or_assign(key2, std::move(val2));
500+
EXPECT_TRUE(try2.second);
501+
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
502+
EXPECT_EQ(1, CountCopyAndMove::MoveConstructions);
503+
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
504+
505+
CountCopyAndMove val3(3);
506+
CountCopyAndMove::ResetCounts();
507+
auto try3 = Map.insert_or_assign(key2, std::move(val3));
508+
EXPECT_FALSE(try3.second);
509+
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
510+
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
511+
EXPECT_EQ(1, CountCopyAndMove::MoveAssignments);
512+
}
513+
478514
// Make sure DenseMap works with StringRef keys.
479515
TEST(DenseMapCustomTest, StringRefTest) {
480516
DenseMap<StringRef, int> M;

0 commit comments

Comments
 (0)