Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-04 09:26:48

0001 /*
0002  * Project: RooFit
0003  * Authors:
0004  *   Carsten D. Burgard, DESY/ATLAS, Dec 2021
0005  *
0006  * Copyright (c) 2022, CERN
0007  *
0008  * Redistribution and use in source and binary forms,
0009  * with or without modification, are permitted according to the terms
0010  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
0011  */
0012 
0013 #ifndef RooFit_Detail_JSONInterface_h
0014 #define RooFit_Detail_JSONInterface_h
0015 
0016 #include <ROOT/RSpan.hxx>
0017 
0018 #include <iostream>
0019 #include <map>
0020 #include <unordered_map>
0021 #include <memory>
0022 #include <stdexcept>
0023 #include <string>
0024 #include <vector>
0025 
0026 namespace RooFit {
0027 namespace Detail {
0028 
0029 class JSONNode {
0030 public:
0031    template <class Nd>
0032    class child_iterator_t {
0033    public:
0034       class Impl {
0035       public:
0036          virtual ~Impl() = default;
0037          virtual std::unique_ptr<Impl> clone() const = 0;
0038          virtual void forward() = 0;
0039          virtual void backward() = 0;
0040          virtual Nd &current() = 0;
0041          virtual bool equal(const Impl &other) const = 0;
0042       };
0043 
0044       child_iterator_t(std::unique_ptr<Impl> impl) : it(std::move(impl)) {}
0045       child_iterator_t(const child_iterator_t &other) : it(std::move(other.it->clone())) {}
0046 
0047       child_iterator_t &operator++()
0048       {
0049          it->forward();
0050          return *this;
0051       }
0052       child_iterator_t &operator--()
0053       {
0054          it->backward();
0055          return *this;
0056       }
0057       Nd &operator*() const { return it->current(); }
0058       Nd &operator->() const { return it->current(); }
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       friend bool operator==(child_iterator_t const &lhs, child_iterator_t const &rhs)
0065       {
0066          return lhs.it->equal(*rhs.it);
0067       }
0068 
0069    private:
0070       std::unique_ptr<Impl> it;
0071    };
0072 
0073    using child_iterator = child_iterator_t<JSONNode>;
0074    using const_child_iterator = child_iterator_t<const JSONNode>;
0075 
0076    template <class Nd>
0077    class children_view_t {
0078       child_iterator_t<Nd> b, e;
0079 
0080    public:
0081       inline children_view_t(child_iterator_t<Nd> const &b_, child_iterator_t<Nd> const &e_) : b(b_), e(e_) {}
0082 
0083       inline child_iterator_t<Nd> begin() const { return b; }
0084       inline child_iterator_t<Nd> end() const { return e; }
0085    };
0086 
0087 public:
0088    virtual void writeJSON(std::ostream &os) const = 0;
0089 
0090 public:
0091    virtual JSONNode &operator<<(std::string const &s) = 0;
0092    inline JSONNode &operator<<(const char *s) { return *this << std::string(s); }
0093    virtual JSONNode &operator<<(int i) = 0;
0094    virtual JSONNode &operator<<(double d) = 0;
0095    virtual JSONNode &operator<<(bool b) = 0;
0096    virtual const JSONNode &operator>>(std::string &v) const = 0;
0097    virtual JSONNode &operator[](std::string const &k) = 0;
0098    virtual const JSONNode &operator[](std::string const &k) const = 0;
0099    virtual bool is_container() const = 0;
0100    virtual bool is_map() const = 0;
0101    virtual bool is_seq() const = 0;
0102    virtual bool is_null() const = 0;
0103    virtual bool is_number() const;
0104    virtual JSONNode &set_map() = 0;
0105    virtual JSONNode &set_seq() = 0;
0106    virtual JSONNode &set_null() = 0;
0107    virtual void clear() = 0;
0108 
0109    virtual std::string key() const = 0;
0110    virtual std::string val() const = 0;
0111    virtual int val_int() const { return atoi(this->val().c_str()); }
0112    virtual double val_double() const;
0113    virtual bool val_bool() const { return atoi(this->val().c_str()); }
0114    template <class T>
0115    T val_t() const;
0116    virtual bool has_key() const = 0;
0117    virtual bool has_val() const = 0;
0118    virtual bool has_child(std::string const &) const = 0;
0119    virtual JSONNode &append_child() = 0;
0120    virtual size_t num_children() const = 0;
0121 
0122    using children_view = children_view_t<JSONNode>;
0123    using const_children_view = children_view_t<const JSONNode>;
0124 
0125    virtual children_view children();
0126    virtual const_children_view children() const;
0127    virtual JSONNode &child(size_t pos) = 0;
0128    virtual const JSONNode &child(size_t pos) const = 0;
0129 
0130    template <typename Collection>
0131    void fill_seq(Collection const &coll)
0132    {
0133       set_seq();
0134       for (auto const &item : coll) {
0135          append_child() << item;
0136       }
0137    }
0138 
0139    template <typename Collection>
0140    void fill_seq(Collection const &coll, size_t nmax)
0141    {
0142       set_seq();
0143       size_t n = 0;
0144       for (auto const &item : coll) {
0145          if (n >= nmax)
0146             break;
0147          append_child() << item;
0148          ++n;
0149       }
0150    }
0151 
0152    template <typename Collection, typename TransformationFunc>
0153    void fill_seq(Collection const &coll, TransformationFunc func)
0154    {
0155       set_seq();
0156       for (auto const &item : coll) {
0157          append_child() << func(item);
0158       }
0159    }
0160 
0161    template <typename Matrix>
0162    void fill_mat(Matrix const &mat)
0163    {
0164       set_seq();
0165       for (int i = 0; i < mat.GetNrows(); ++i) {
0166          auto &row = append_child();
0167          row.set_seq();
0168          for (int j = 0; j < mat.GetNcols(); ++j) {
0169             row.append_child() << mat(i, j);
0170          }
0171       }
0172    }
0173 
0174    JSONNode const *find(std::string const &key) const
0175    {
0176       auto &n = *this;
0177       return n.has_child(key) ? &n[key] : nullptr;
0178    }
0179 
0180    template <typename... Keys_t>
0181    JSONNode const *find(std::string const &key, Keys_t const &...keys) const
0182    {
0183       auto &n = *this;
0184       return n.has_child(key) ? n[key].find(keys...) : nullptr;
0185    }
0186 
0187    JSONNode &get(std::string const &key)
0188    {
0189       auto &n = *this;
0190       n.set_map();
0191       return n[key];
0192    }
0193 
0194    template <typename... Keys_t>
0195    JSONNode &get(std::string const &key, Keys_t const &...keys)
0196    {
0197       auto &next = get(key);
0198       next.set_map();
0199       return next.get(keys...);
0200    }
0201 };
0202 
0203 class JSONTree {
0204 public:
0205    virtual ~JSONTree() = default;
0206 
0207    virtual JSONNode &rootnode() = 0;
0208 
0209    static std::unique_ptr<JSONTree> create();
0210    static std::unique_ptr<JSONTree> create(std::istream &is);
0211    static std::unique_ptr<JSONTree> create(std::string const &str);
0212 
0213 private:
0214    template <typename... Args>
0215    static std::unique_ptr<JSONTree> createImpl(Args &&...args);
0216 };
0217 
0218 std::ostream &operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s);
0219 
0220 template <class T>
0221 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::children_view const &cv)
0222 {
0223    for (const auto &e : cv) {
0224       v.push_back(e.val_t<T>());
0225    }
0226    return v;
0227 }
0228 
0229 template <class T>
0230 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::const_children_view const &cv)
0231 {
0232    for (const auto &e : cv) {
0233       v.push_back(e.val_t<T>());
0234    }
0235    return v;
0236 }
0237 
0238 template <class T>
0239 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode const &n)
0240 {
0241    if (!n.is_seq()) {
0242       throw std::runtime_error("node " + n.key() + " is not of sequence type!");
0243    }
0244    v << n.children();
0245    return v;
0246 }
0247 
0248 inline RooFit::Detail::JSONNode &operator<<(RooFit::Detail::JSONNode &n, std::span<const double> v)
0249 {
0250    n.fill_seq(v);
0251    return n;
0252 }
0253 
0254 inline RooFit::Detail::JSONNode &operator<<(RooFit::Detail::JSONNode &n, std::span<const float> v)
0255 {
0256    n.fill_seq(v);
0257    return n;
0258 }
0259 
0260 inline RooFit::Detail::JSONNode &operator<<(RooFit::Detail::JSONNode &n, std::span<const int> v)
0261 {
0262    n.fill_seq(v);
0263    return n;
0264 }
0265 
0266 template <class Key, class T, class Hash, class KeyEqual, class Allocator>
0267 RooFit::Detail::JSONNode &
0268 operator<<(RooFit::Detail::JSONNode &n, const std::unordered_map<Key, T, Hash, KeyEqual, Allocator> &m)
0269 {
0270    n.set_map();
0271    for (const auto &it : m) {
0272       n[it.first] << it.second;
0273    }
0274    return n;
0275 }
0276 
0277 template <class Key, class T, class Compare, class Allocator>
0278 RooFit::Detail::JSONNode &operator<<(RooFit::Detail::JSONNode &n, const std::map<Key, T, Compare, Allocator> &m)
0279 {
0280    n.set_map();
0281    for (const auto &it : m) {
0282       n[it.first] << it.second;
0283    }
0284    return n;
0285 }
0286 
0287 template <>
0288 inline int JSONNode::val_t<int>() const
0289 {
0290    return val_int();
0291 }
0292 template <>
0293 inline double JSONNode::val_t<double>() const
0294 {
0295    return val_double();
0296 }
0297 template <>
0298 inline bool JSONNode::val_t<bool>() const
0299 {
0300    return val_bool();
0301 }
0302 template <>
0303 inline std::string JSONNode::val_t<std::string>() const
0304 {
0305    return val();
0306 }
0307 
0308 } // namespace Detail
0309 } // namespace RooFit
0310 
0311 #endif