1

I'm creating a JSON string exploiting boost ptree library but I'm finding it tedious just by doing the following. I need to add a simple array like "metric.name" : [A, B] to the metrics ptree. Can I do better than this? Or at least write this in a cleaner way.

      pt::ptree metric_avg;
      metric_avg.put("", 9999);
      pt::ptree metric_std;
      metric_std.put("", 0);
      pt::ptree metric_distr;
      metric_distr.push_back({"", metric_avg});
      metric_distr.push_back({"", metric_std});
      metrics.add_child(metric.name, metric_distr);
Barnercart
  • 1,523
  • 1
  • 11
  • 23
  • 1
    you'd be better off using a json library, ptree is convenient but if you want a specific JSON output you'll run into limitations – Alan Birtles Jan 28 '21 at 12:16
  • Do you have any recommendation for that? I heavily use ptree inside this project and the json formatting occurs just 2/3 times so I'd rather prefer sticking with ptree as long as I can do what I need to. – Barnercart Jan 28 '21 at 13:06
  • [nlohman](https://github.com/nlohmann/json/) is quite easy to use and gives some nice syntax – Alan Birtles Jan 28 '21 at 14:27

2 Answers2

2

I'd write some helper functions

template<typename T>
pt::ptree scalar(const T & value)
{
    pt::ptree tree;
    tree.put("", value);
    return tree;
}

template<typename T>
pt::ptree array(std::initialiser_list<T> container)
{
    pt::ptree tree;
    for (auto & v : container)
    { 
        tree.push_back(scalar(v));
    }
    return tree;
}

That way you can write

metrics.put(metric.name, array({ 9999, 0 }));
Caleth
  • 52,200
  • 2
  • 44
  • 75
1

I would:

Live On Coliru

ptree metric_avg;
auto& arr = metric_avg.put_child("metric name", {});
arr.push_back({"", ptree("9999")});
arr.push_back({"", ptree("0")});

Or Live On Coliru

for (auto el : {"9999", "0"})
    arr.push_back({"", ptree(el)});

Or even Live On Coliru

for (auto el : {9999, 0})
    arr.push_back({"", ptree(std::to_string(el))});

All of which print

{
    "metric name": [
        "9999",
        "0"
    ]
}

See also JSON Array using Boost::Ptree

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    I've found @Caleth answer to be more general and flexible and I ended up writing my own template functions but yours goes straight to the point I was looking for originally so thanks anyway. – Barnercart Jan 29 '21 at 11:36
  • Oh yeah, I +1'ed @Caleth's answer before. It's nice! – sehe Jan 29 '21 at 15:25