void Settings::merge(const boost::property_tree::ptree& from, boost::property_tree::ptree& to, bool overwrite) { // Is this a single value or a subtree? if (!from.data().empty()) { // Single value if (overwrite || to.data().empty()) { to.put_value(from.data()); } return; } // Subtree for (const auto& fromEntry : from) { // Does the key exist in the destination? auto toIt = to.find(fromEntry.first); if (toIt == to.not_found()) { ptree::ptree child; // Recurse into the new child merge(fromEntry.second, child, overwrite); // Create a path object because ptree uses '.' as a path delimiter // when strings are used ptree::ptree::path_type treePath = createPath(fromEntry.first); to.add_child(treePath, child); } else { // Recurse into the subtrees merge(fromEntry.second, toIt->second, overwrite); } } }