File indexing completed on 2025-01-18 10:10:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef RooFit_Detail_JSONInterface_h
0014 #define RooFit_Detail_JSONInterface_h
0015
0016 #include <iostream>
0017 #include <memory>
0018 #include <stdexcept>
0019 #include <string>
0020 #include <vector>
0021
0022 namespace RooFit {
0023 namespace Detail {
0024
0025 class JSONNode {
0026 public:
0027 template <class Nd>
0028 class child_iterator_t {
0029 public:
0030 class Impl {
0031 public:
0032 virtual ~Impl() = default;
0033 virtual std::unique_ptr<Impl> clone() const = 0;
0034 virtual void forward() = 0;
0035 virtual void backward() = 0;
0036 virtual Nd ¤t() = 0;
0037 virtual bool equal(const Impl &other) const = 0;
0038 };
0039
0040 child_iterator_t(std::unique_ptr<Impl> impl) : it(std::move(impl)) {}
0041 child_iterator_t(const child_iterator_t &other) : it(std::move(other.it->clone())) {}
0042
0043 child_iterator_t &operator++()
0044 {
0045 it->forward();
0046 return *this;
0047 }
0048 child_iterator_t &operator--()
0049 {
0050 it->backward();
0051 return *this;
0052 }
0053 Nd &operator*() const { return it->current(); }
0054 Nd &operator->() const { return it->current(); }
0055
0056 friend bool operator!=(child_iterator_t const &lhs, child_iterator_t const &rhs)
0057 {
0058 return !lhs.it->equal(*rhs.it);
0059 }
0060 friend bool operator==(child_iterator_t const &lhs, child_iterator_t const &rhs)
0061 {
0062 return lhs.it->equal(*rhs.it);
0063 }
0064
0065 private:
0066 std::unique_ptr<Impl> it;
0067 };
0068
0069 using child_iterator = child_iterator_t<JSONNode>;
0070 using const_child_iterator = child_iterator_t<const JSONNode>;
0071
0072 template <class Nd>
0073 class children_view_t {
0074 child_iterator_t<Nd> b, e;
0075
0076 public:
0077 inline children_view_t(child_iterator_t<Nd> const &b_, child_iterator_t<Nd> const &e_) : b(b_), e(e_) {}
0078
0079 inline child_iterator_t<Nd> begin() const { return b; }
0080 inline child_iterator_t<Nd> end() const { return e; }
0081 };
0082
0083 public:
0084 virtual void writeJSON(std::ostream &os) const = 0;
0085 virtual void writeYML(std::ostream &) const { throw std::runtime_error("YML not supported"); }
0086
0087 public:
0088 virtual JSONNode &operator<<(std::string const &s) = 0;
0089 inline JSONNode &operator<<(const char *s) { return *this << std::string(s); }
0090 virtual JSONNode &operator<<(int i) = 0;
0091 virtual JSONNode &operator<<(double d) = 0;
0092 virtual JSONNode &operator<<(bool b) = 0;
0093 virtual const JSONNode &operator>>(std::string &v) const = 0;
0094 virtual JSONNode &operator[](std::string const &k) = 0;
0095 virtual const JSONNode &operator[](std::string const &k) const = 0;
0096 virtual bool is_container() const = 0;
0097 virtual bool is_map() const = 0;
0098 virtual bool is_seq() const = 0;
0099 virtual JSONNode &set_map() = 0;
0100 virtual JSONNode &set_seq() = 0;
0101 virtual void clear() = 0;
0102
0103 virtual std::string key() const = 0;
0104 virtual std::string val() const = 0;
0105 virtual int val_int() const { return atoi(this->val().c_str()); }
0106 virtual double val_double() const { return std::stod(this->val()); }
0107 virtual bool val_bool() const { return atoi(this->val().c_str()); }
0108 template <class T>
0109 T val_t() const;
0110 virtual bool has_key() const = 0;
0111 virtual bool has_val() const = 0;
0112 virtual bool has_child(std::string const &) const = 0;
0113 virtual JSONNode &append_child() = 0;
0114 virtual size_t num_children() const = 0;
0115
0116 using children_view = children_view_t<JSONNode>;
0117 using const_children_view = children_view_t<const JSONNode>;
0118
0119 virtual children_view children();
0120 virtual const_children_view children() const;
0121 virtual JSONNode &child(size_t pos) = 0;
0122 virtual const JSONNode &child(size_t pos) const = 0;
0123
0124 template <typename Collection>
0125 void fill_seq(Collection const &coll)
0126 {
0127 set_seq();
0128 for (auto const &item : coll) {
0129 append_child() << item;
0130 }
0131 }
0132
0133 template <typename Collection>
0134 void fill_seq(Collection const &coll, size_t nmax)
0135 {
0136 set_seq();
0137 size_t n = 0;
0138 for (auto const &item : coll) {
0139 if (n >= nmax)
0140 break;
0141 append_child() << item;
0142 ++n;
0143 }
0144 }
0145
0146 template <typename Collection, typename TransformationFunc>
0147 void fill_seq(Collection const &coll, TransformationFunc func)
0148 {
0149 set_seq();
0150 for (auto const &item : coll) {
0151 append_child() << func(item);
0152 }
0153 }
0154
0155 template <typename Matrix>
0156 void fill_mat(Matrix const &mat)
0157 {
0158 set_seq();
0159 for (int i = 0; i < mat.GetNrows(); ++i) {
0160 auto &row = append_child();
0161 row.set_seq();
0162 for (int j = 0; j < mat.GetNcols(); ++j) {
0163 row.append_child() << mat(i, j);
0164 }
0165 }
0166 }
0167
0168 JSONNode const *find(std::string const &key) const
0169 {
0170 auto &n = *this;
0171 return n.has_child(key) ? &n[key] : nullptr;
0172 }
0173
0174 template <typename... Keys_t>
0175 JSONNode const *find(std::string const &key, Keys_t const &...keys) const
0176 {
0177 auto &n = *this;
0178 return n.has_child(key) ? n[key].find(keys...) : nullptr;
0179 }
0180
0181 JSONNode &get(std::string const &key)
0182 {
0183 auto &n = *this;
0184 n.set_map();
0185 return n[key];
0186 }
0187
0188 template <typename... Keys_t>
0189 JSONNode &get(std::string const &key, Keys_t const &...keys)
0190 {
0191 auto &next = get(key);
0192 next.set_map();
0193 return next.get(keys...);
0194 }
0195 };
0196
0197 class JSONTree {
0198 public:
0199 virtual ~JSONTree() = default;
0200
0201 virtual JSONNode &rootnode() = 0;
0202
0203 static std::unique_ptr<JSONTree> create();
0204 static std::unique_ptr<JSONTree> create(std::istream &is);
0205 static std::unique_ptr<JSONTree> create(std::string const &str);
0206
0207 static std::string getBackend();
0208 static void setBackend(std::string const &name);
0209
0210 static bool hasBackend(std::string const &name);
0211
0212 private:
0213
0214 enum class Backend { NlohmannJson, Ryml };
0215
0216 static Backend &getBackendEnum();
0217
0218 template <typename... Args>
0219 static std::unique_ptr<JSONTree> createImpl(Args &&...args);
0220 };
0221
0222 std::ostream &operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s);
0223
0224 template <class T>
0225 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::children_view const &cv)
0226 {
0227 for (const auto &e : cv) {
0228 v.push_back(e.val_t<T>());
0229 }
0230 return v;
0231 }
0232
0233 template <class T>
0234 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::const_children_view const &cv)
0235 {
0236 for (const auto &e : cv) {
0237 v.push_back(e.val_t<T>());
0238 }
0239 return v;
0240 }
0241
0242 template <class T>
0243 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode const &n)
0244 {
0245 if (!n.is_seq()) {
0246 throw std::runtime_error("node " + n.key() + " is not of sequence type!");
0247 }
0248 v << n.children();
0249 return v;
0250 }
0251
0252 template <>
0253 inline int JSONNode::val_t<int>() const
0254 {
0255 return val_int();
0256 }
0257 template <>
0258 inline double JSONNode::val_t<double>() const
0259 {
0260 return val_double();
0261 }
0262 template <>
0263 inline bool JSONNode::val_t<bool>() const
0264 {
0265 return val_bool();
0266 }
0267 template <>
0268 inline std::string JSONNode::val_t<std::string>() const
0269 {
0270 return val();
0271 }
0272
0273 }
0274 }
0275
0276 #endif