[llvm] e02aed6 - [ADT] Add try_emplace and insert to SortedVectorMap (#216251)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 08:47:06 PDT 2026


Author: Kazu Hirata
Date: 2026-08-14T08:47:00-07:00
New Revision: e02aed68d725366625c76da93d265e0d58f261f9

URL: https://github.com/llvm/llvm-project/commit/e02aed68d725366625c76da93d265e0d58f261f9
DIFF: https://github.com/llvm/llvm-project/commit/e02aed68d725366625c76da93d265e0d58f261f9.diff

LOG: [ADT] Add try_emplace and insert to SortedVectorMap (#216251)

This patch adds try_emplace and insert to SortedVectorMap.

try_emplace_impl serves as the common implementation for try_emplace,
insert, and operator[].

The motivation here is to support insert for the ongoing sample
profile loader/writer work.  We might also need try_emplace if we
clean up constructs like insert(std::make_pair(K, V)).

Assisted-by: Antigravity

Added: 
    

Modified: 
    llvm/include/llvm/ADT/SortedVectorMap.h
    llvm/unittests/ADT/SortedVectorMapTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/SortedVectorMap.h b/llvm/include/llvm/ADT/SortedVectorMap.h
index 709577121fc5b..6bc69e5a5ea0a 100644
--- a/llvm/include/llvm/ADT/SortedVectorMap.h
+++ b/llvm/include/llvm/ADT/SortedVectorMap.h
@@ -35,6 +35,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include <functional>
+#include <tuple>
 #include <utility>
 
 namespace llvm {
@@ -85,6 +86,18 @@ class SortedVectorMap {
     return {Vector.begin() + (ConstIt - Vector.begin()), Found};
   }
 
+  template <typename KeyArgT, typename... Ts>
+  std::pair<iterator, bool> try_emplace_impl(KeyArgT &&Key, Ts &&...Args) {
+    auto [It, Found] = find_or_insert_location(Key);
+    if (Found)
+      return {It, false};
+    It = Vector.insert(
+        It, value_type(std::piecewise_construct,
+                       std::forward_as_tuple(std::forward<KeyArgT>(Key)),
+                       std::forward_as_tuple(std::forward<Ts>(Args)...)));
+    return {It, true};
+  }
+
 public:
   SortedVectorMap() = default;
 
@@ -112,18 +125,30 @@ class SortedVectorMap {
     return Found ? It : Vector.end();
   }
 
+  template <typename... Ts>
+  std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&...Args) {
+    return try_emplace_impl(Key, std::forward<Ts>(Args)...);
+  }
+
+  template <typename... Ts>
+  std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&...Args) {
+    return try_emplace_impl(std::move(Key), std::forward<Ts>(Args)...);
+  }
+
+  std::pair<iterator, bool> insert(const value_type &KV) {
+    return try_emplace_impl(KV.first, KV.second);
+  }
+
+  std::pair<iterator, bool> insert(value_type &&KV) {
+    return try_emplace_impl(std::move(KV.first), std::move(KV.second));
+  }
+
   ValueT &operator[](const KeyT &Key) {
-    auto [It, Found] = find_or_insert_location(Key);
-    if (Found)
-      return It->second;
-    return Vector.insert(It, value_type(Key, ValueT()))->second;
+    return try_emplace_impl(Key).first->second;
   }
 
   ValueT &operator[](KeyT &&Key) {
-    auto [It, Found] = find_or_insert_location(Key);
-    if (Found)
-      return It->second;
-    return Vector.insert(It, value_type(std::move(Key), ValueT()))->second;
+    return try_emplace_impl(std::move(Key)).first->second;
   }
 
   iterator erase(iterator Pos) { return Vector.erase(Pos); }

diff  --git a/llvm/unittests/ADT/SortedVectorMapTest.cpp b/llvm/unittests/ADT/SortedVectorMapTest.cpp
index 9b6fdbd63c336..c2ac1c9e8385f 100644
--- a/llvm/unittests/ADT/SortedVectorMapTest.cpp
+++ b/llvm/unittests/ADT/SortedVectorMapTest.cpp
@@ -71,6 +71,45 @@ TEST(SortedVectorMapTest, EqualityOperator) {
   EXPECT_EQ(Map1, Map2);
 }
 
+TEST(SortedVectorMapTest, InsertAndTryEmplace) {
+  SortedVectorMap<int, std::string> Map;
+
+  // Test insert with lvalue and rvalue pairs
+  auto Pair1 = std::make_pair(3, "three");
+  auto [It1, Inserted1] = Map.insert(Pair1);
+  ASSERT_TRUE(Inserted1);
+  EXPECT_EQ(It1->first, 3);
+  EXPECT_EQ(It1->second, "three");
+
+  auto [It2, Inserted2] = Map.insert(std::make_pair(1, "one"));
+  ASSERT_TRUE(Inserted2);
+  EXPECT_EQ(It2->first, 1);
+  EXPECT_EQ(It2->second, "one");
+
+  // Duplicate insert should fail and preserve existing value
+  auto [ItDup, InsertedDup] = Map.insert(std::make_pair(3, "THREE"));
+  ASSERT_FALSE(InsertedDup);
+  EXPECT_EQ(ItDup->first, 3);
+  EXPECT_EQ(ItDup->second, "three");
+
+  // Test try_emplace in-place construction
+  auto [It3, Inserted3] = Map.try_emplace(2, 4, 'x');
+  ASSERT_TRUE(Inserted3);
+  EXPECT_EQ(It3->first, 2);
+  EXPECT_EQ(It3->second, "xxxx");
+
+  // Duplicate try_emplace should not construct or overwrite
+  auto [It4, Inserted4] = Map.try_emplace(2, "new_two");
+  ASSERT_FALSE(Inserted4);
+  EXPECT_EQ(It4->first, 2);
+  EXPECT_EQ(It4->second, "xxxx");
+
+  // Verify sorted order
+  EXPECT_THAT(Map, testing::ElementsAre(testing::Pair(1, "one"),
+                                        testing::Pair(2, "xxxx"),
+                                        testing::Pair(3, "three")));
+}
+
 TEST(SortedVectorMapTest, ReserveAndCapacity) {
   SortedVectorMap<int, int> Map;
   EXPECT_EQ(Map.size(), 0u);


        


More information about the llvm-commits mailing list