I'm trying to use the boost property tree library to represent recursive data structures, but although I can get the dumped json to look reasonable, I cannot traverse the ptree in any ways I've tried.
The code below, compiles and run, except for the call to Dump in DumpAssign.
Is there a way to traverse arbitrary trees where values can be themselves ptrees?
I'm about to throw the towel and go with boost::seriaization, but I did like the traversal mechanisms property trees offer.
#include <boost/any.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <map>
using boost::property_tree::ptree;
using boost::assign::list_of;
using boost::assign::map_list_of;
using namespace std;
ptree Op(string type, ptree a1, ptree a2) {
ptree pt;
// pt.put_value(type);
pt.put("type", type);
ptree args;
args.push_back(make_pair("", a1));
args.push_back(make_pair("", a2));
pt.add_child("args", args);
return pt;
}
ptree Net(string name) {
ptree pt;
pt.put("type", "net");
pt.put("name", name);
return pt;
}
ptree Assign(ptree lhs, ptree rhs) {
ptree pt;
pt.put("type", "assign");
pt.add_child("lhs", lhs);
pt.add_child("rhs", rhs);
return pt;
}
string Dump(ptree::value_type e);
string DumpConcat(ptree::value_type e) {
string result = "{";
bool first = true;
BOOST_FOREACH(const ptree::value_type& child,
e.second.get_child("args")) {
if (not first) {
result += ", ";
first = false;
}
result += Dump(child);
}
return result + "}";
}
string DumpNet(ptree::value_type e) {
return e.second.get<std::string>("name");
}
string DumpAssign(ptree::value_type e) {
string result = "assign ";
// HOW TO HAVE A RECURSIVE CALL TO Dump(lhs) HERE?
result += Dump(?);
return result;
}
string DumpNop(ptree::value_type) {return "NOP";}
string Dump(ptree::value_type e) {
static std::map<string, string(*)(ptree::value_type)> dump =
map_list_of
("net", DumpNet)
("concat", DumpConcat)
("assign", DumpAssign)
("nop", DumpNop)
;
string type = e.second.get<string>("type", "nop");
return dump[type](e);
}
int main(int, char**) {
ptree pt;
ptree a1;
a1.push_back(make_pair("", Assign(
Op("concat",
Op("concat", Net("a1"), Net("a1")),
Net("w")),
Net("a2"))));
pt.add_child("operators", a1);
cout << "=============\n";
write_json(std::cout, pt);
cout << "=============\n";
BOOST_FOREACH(const ptree::value_type& e, pt.get_child("operators")) {
cout << "> " << Dump(e);
}
}