rv.first->second = std::forward<V>(val);
}
+inline void dynamic::update(const dynamic& mergeObj) {
+ if (!isObject() || !mergeObj.isObject()) {
+ throw TypeError("object", type(), mergeObj.type());
+ }
+
+ for (const auto& pair : mergeObj.items()) {
+ (*this)[pair.first] = pair.second;
+ }
+}
+
+inline void dynamic::update_missing(const dynamic& mergeObj1) {
+ if (!isObject() || !mergeObj1.isObject()) {
+ throw TypeError("object", type(), mergeObj1.type());
+ }
+
+ // Only add if not already there
+ for (const auto& pair : mergeObj1.items()) {
+ if ((*this).find(pair.first) == (*this).items().end()) {
+ (*this)[pair.first] = pair.second;
+ }
+ }
+}
+
+inline dynamic dynamic::merge(
+ const dynamic& mergeObj1,
+ const dynamic& mergeObj2) {
+
+ // No checks on type needed here because they are done in update_missing
+ // Note that we do update_missing here instead of update() because
+ // it will prevent the extra writes that would occur with update()
+ auto ret = mergeObj2;
+ ret.update_missing(mergeObj1);
+ return ret;
+}
+
inline std::size_t dynamic::erase(dynamic const& key) {
auto& obj = get<ObjectImpl>();
return obj.erase(key);
*/
template<class K, class V> void insert(K&&, V&& val);
+ /*
+ * These functions merge two folly dynamic objects.
+ * The "update" and "update_missing" functions extend the object by
+ * inserting the key/value pairs of mergeObj into the current object.
+ * For update, if key is duplicated between the two objects, it
+ * will overwrite with the value of the object being inserted (mergeObj).
+ * For "update_missing", it will prefer the value in the original object
+ *
+ * The "merge" function creates a new object consisting of the key/value
+ * pairs of both mergeObj1 and mergeObj2
+ * If the key is duplicated between the two objects,
+ * it will prefer value in the second object (mergeObj2)
+ */
+ void update(const dynamic& mergeObj);
+ void update_missing(const dynamic& other);
+ static dynamic merge(const dynamic& mergeObj1, const dynamic& mergeObj2);
+
/*
* Erase an element from a dynamic object, by key.
*
// We don't allow objects as keys in objects.
EXPECT_ANY_THROW(newObject[d3] = 12);
+
+ // Merge two objects
+ dynamic origMergeObj1 = folly::dynamic::object();
+ dynamic mergeObj1 = origMergeObj1 = folly::dynamic::object
+ ("key1", "value1")
+ ("key2", "value2");
+ dynamic mergeObj2 = folly::dynamic::object
+ ("key2", "value3")
+ ("key3", "value4");
+ dynamic combinedObj = folly::dynamic::object
+ ("key1", "value1")
+ ("key2", "value3")
+ ("key3", "value4");
+ auto newMergeObj = dynamic::merge(mergeObj1, mergeObj2);
+ EXPECT_EQ(newMergeObj, combinedObj);
+ EXPECT_EQ(mergeObj1, origMergeObj1); // mergeObj1 should be unchanged
+
+ mergeObj1.update(mergeObj2);
+ EXPECT_EQ(mergeObj1, combinedObj);
+ dynamic arr = { 1, 2, 3, 4, 5, 6 };
+ EXPECT_THROW(mergeObj1.update(arr), std::exception);
}
TEST(Dynamic, ObjectErase) {