I understand that boost::property_tree::ptree may contain key-value pairs where the 'value' may be of any type. Now my question is that, now my 'value' is a std::map, and when I attempt to pt.get<std::map<std::string, std::string>> where pt is a property tree, I get a compile time error. Hence, my question is:
How to extract a STL map value from a boost property tree? If this is not possible, is there any way of converting between STL map and boost property tree (so that each node of the property tree is not a STL container but a simple data type).
Very simply:
Live On Coliru
ptree pt;
std::map<std::string, ptree> m(pt.begin(), pt.end());
However, note that keys need not be unique:
std::multimap<std::string, ptree> mm(pt.begin(), pt.end());
And if you are want to transform all values to std::string (assuming they all have a string value):
std::map<std::string, std::string> dict;
for (auto& [k,v]: pt) {
dict.emplace(k, v.get_value<std::string>());
}
Live On Compiler Explorer
#include <boost/property_tree/ptree.hpp>
#include <map>
#include <fmt/ranges.h>
using boost::property_tree::ptree;
template<> struct fmt::formatter<ptree> : fmt::formatter<std::string>
{
template<typename Ctx>
auto format(ptree const& pt, Ctx& ctx) {
return format_to(ctx.out(), "'{}'", pt.get_value<std::string>());
}
};
int main() {
ptree pt;
pt.put("keyA", "valueA-1");
pt.put("keyB", "valueB");
pt.put("keyC", "valueC");
pt.add("keyA", "valueA-2"); // not replacing same key
std::map<std::string, ptree> m(pt.begin(), pt.end());
std::multimap<std::string, ptree> mm(pt.begin(), pt.end());
std::map<std::string, std::string> dict;
for (auto& [k,v]: pt) {
dict.emplace(k, v.get_value<std::string>());
}
fmt::print(
"map:\n\t{}\n"
"multimap:\n\t{}\n"
"dict:\n\t{}\n",
fmt::join(m, "\n\t"),
fmt::join(mm, "\n\t"),
fmt::join(dict, "\n\t")
);
}
Prints
map:
("keyA", 'valueA-1')
("keyB", 'valueB')
("keyC", 'valueC')
multimap:
("keyA", 'valueA-1')
("keyA", 'valueA-2')
("keyB", 'valueB')
("keyC", 'valueC')
dict:
("keyA", "valueA-1")
("keyB", "valueB")
("keyC", "valueC")
added ptree_from_map function
template <typename MapLike>
ptree ptree_from_map(MapLike const& m) {
ptree pt;
for (auto const& [k,v]: m) {
pt.add(k, v);
}
return pt;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With