[llvm] [Support][JSON] Fix compilation error on creating json::Object from std::map (PR #115839)

via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 12 01:40:25 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Aleksei Romanov (saveasguy)

<details>
<summary>Changes</summary>

This patch introduces bugfix, which causes compilation error when using JSON library. json::Value can be constructed from std::map, which causes call to missing json::Object constructor. The PR fixes this.

---
Full diff: https://github.com/llvm/llvm-project/pull/115839.diff


2 Files Affected:

- (modified) llvm/include/llvm/Support/JSON.h (+11) 
- (modified) llvm/unittests/Support/JSONTest.cpp (+15) 


``````````diff
diff --git a/llvm/include/llvm/Support/JSON.h b/llvm/include/llvm/Support/JSON.h
index 14a5c7142ed8ce..2b73a94ff698a2 100644
--- a/llvm/include/llvm/Support/JSON.h
+++ b/llvm/include/llvm/Support/JSON.h
@@ -112,6 +112,8 @@ class Object {
   struct KV;
   explicit Object(std::initializer_list<KV> Properties);
 
+  template <typename T> explicit Object(const std::map<std::string, T> &Map);
+
   iterator begin() { return M.begin(); }
   const_iterator begin() const { return M.begin(); }
   iterator end() { return M.end(); }
@@ -640,6 +642,15 @@ inline Object::Object(std::initializer_list<KV> Properties) {
       R.first->getSecond().moveFrom(std::move(P.V));
   }
 }
+
+template <typename T> Object::Object(const std::map<std::string, T> &Map) {
+  for (const auto &P : Map) {
+    auto R = try_emplace(ObjectKey(P.first), nullptr);
+    if (R.second)
+      R.first->getSecond().moveFrom(Value(P.second));
+  }
+}
+
 inline std::pair<Object::iterator, bool> Object::insert(KV E) {
   return try_emplace(std::move(E.K), std::move(E.V));
 }
diff --git a/llvm/unittests/Support/JSONTest.cpp b/llvm/unittests/Support/JSONTest.cpp
index 4e56557132976c..43251cddf57902 100644
--- a/llvm/unittests/Support/JSONTest.cpp
+++ b/llvm/unittests/Support/JSONTest.cpp
@@ -146,6 +146,21 @@ TEST(JSONTest, Object) {
   O.erase(D);
   EXPECT_EQ(O.size(), 2u);
   EXPECT_EQ(R"({"a":1,"c":3})", s(std::move(O)));
+
+  std::map<std::string, int> Map = {{"a", 1}, {"b", 2}, {"c", 3}};
+  Object ObjectFromMap(Map);
+  EXPECT_TRUE(ObjectFromMap.try_emplace("d", 4).second);
+  EXPECT_FALSE(ObjectFromMap.try_emplace("a", 4).second);
+
+  D = ObjectFromMap.find("d");
+  EXPECT_NE(D, ObjectFromMap.end());
+  E = ObjectFromMap.find("e");
+  EXPECT_EQ(E, ObjectFromMap.end());
+
+  ObjectFromMap.erase("b");
+  ObjectFromMap.erase(D);
+  EXPECT_EQ(ObjectFromMap.size(), 2u);
+  EXPECT_EQ(R"({"a":1,"c":3})", s(std::move(ObjectFromMap)));
 }
 
 TEST(JSONTest, Parse) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/115839


More information about the llvm-commits mailing list