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

Aleksei Romanov via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 12 01:39:30 PST 2024


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

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.

>From 98f52d3ac11971c978fccaf1bb18a798adc21fd3 Mon Sep 17 00:00:00 2001
From: anton-afanasyev <>
Date: Tue, 12 Nov 2024 12:36:44 +0300
Subject: [PATCH] [Support][JSON] Fix compilation error on creating
 json::Object from std::map

---
 llvm/include/llvm/Support/JSON.h    | 11 +++++++++++
 llvm/unittests/Support/JSONTest.cpp | 15 +++++++++++++++
 2 files changed, 26 insertions(+)

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) {



More information about the llvm-commits mailing list