Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
JSONInterface.h
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * Carsten D. Burgard, DESY/ATLAS, Dec 2021
5 *
6 * Copyright (c) 2022, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13#ifndef RooFit_Detail_JSONInterface_h
14#define RooFit_Detail_JSONInterface_h
15
16#include <ROOT/RSpan.hxx>
17
18#include <iostream>
19#include <map>
20#include <unordered_map>
21#include <memory>
22#include <stdexcept>
23#include <string>
24#include <vector>
25
26namespace RooFit {
27namespace Detail {
28
29class JSONNode {
30public:
31 template <class Nd>
33 public:
34 explicit child_iterator_t(Nd *const *pos) : _pos(pos) {}
35
37 {
38 ++_pos;
39 return *this;
40 }
42 {
43 --_pos;
44 return *this;
45 }
46 Nd &operator*() const { return **_pos; }
47 Nd &operator->() const { return **_pos; }
48
49 friend bool operator!=(child_iterator_t const &lhs, child_iterator_t const &rhs) { return lhs._pos != rhs._pos; }
50 friend bool operator==(child_iterator_t const &lhs, child_iterator_t const &rhs) { return lhs._pos == rhs._pos; }
51
52 private:
53 Nd *const *_pos;
54 };
55
58
59 template <class Nd>
62
63 public:
64 inline children_view_t(child_iterator_t<Nd> const &b_, child_iterator_t<Nd> const &e_) : b(b_), e(e_) {}
65
66 inline child_iterator_t<Nd> begin() const { return b; }
67 inline child_iterator_t<Nd> end() const { return e; }
68 };
69
70 // A node refers to a value of its tree. Copying it would copy that reference, not the value.
71 JSONNode(JSONNode const &) = delete;
72 JSONNode &operator=(JSONNode const &) = delete;
73
74public:
75 void writeJSON(std::ostream &os) const;
76
77public:
78 JSONNode &operator<<(std::string const &s);
79 inline JSONNode &operator<<(const char *s) { return *this << std::string(s); }
80 JSONNode &operator<<(int i);
81 JSONNode &operator<<(double d);
82 JSONNode &operator<<(bool b);
83 const JSONNode &operator>>(std::string &v) const;
84 JSONNode &operator[](std::string const &k);
85 const JSONNode &operator[](std::string const &k) const;
86 bool is_container() const;
87 bool is_map() const;
88 bool is_seq() const;
89 bool is_null() const;
90 bool is_number() const;
94 void clear();
95 /// Remove a child of a map, if it exists.
96 void erase(std::string const &key);
97
98 std::string key() const;
99 std::string val() const;
100 int val_int() const;
101 double val_double() const;
102 bool val_bool() const;
103 template <class T>
104 T val_t() const;
105 bool has_key() const;
106 bool has_val() const;
107 bool has_child(std::string const &) const;
109 size_t num_children() const;
110
113
116 JSONNode &child(size_t pos);
117 const JSONNode &child(size_t pos) const;
118
119 template <typename Collection>
120 void fill_seq(Collection const &coll)
121 {
122 set_seq();
123 for (auto const &item : coll) {
124 append_child() << item;
125 }
126 }
127
128 template <typename Collection>
129 void fill_seq(Collection const &coll, size_t nmax)
130 {
131 set_seq();
132 size_t n = 0;
133 for (auto const &item : coll) {
134 if (n >= nmax)
135 break;
136 append_child() << item;
137 ++n;
138 }
139 }
140
141 template <typename Collection, typename TransformationFunc>
142 void fill_seq(Collection const &coll, TransformationFunc func)
143 {
144 set_seq();
145 for (auto const &item : coll) {
146 append_child() << func(item);
147 }
148 }
149
150 template <typename Matrix>
151 void fill_mat(Matrix const &mat)
152 {
153 set_seq();
154 for (int i = 0; i < mat.GetNrows(); ++i) {
155 auto &row = append_child();
156 row.set_seq();
157 for (int j = 0; j < mat.GetNcols(); ++j) {
158 row.append_child() << mat(i, j);
159 }
160 }
161 }
162
163 JSONNode const *find(std::string const &key) const
164 {
165 auto &n = *this;
166 return n.has_child(key) ? &n[key] : nullptr;
167 }
168
169 template <typename... Keys_t>
170 JSONNode const *find(std::string const &key, Keys_t const &...keys) const
171 {
172 auto &n = *this;
173 return n.has_child(key) ? n[key].find(keys...) : nullptr;
174 }
175
176 JSONNode &get(std::string const &key)
177 {
178 auto &n = *this;
179 n.set_map();
180 return n[key];
181 }
182
183 template <typename... Keys_t>
184 JSONNode &get(std::string const &key, Keys_t const &...keys)
185 {
186 auto &next = get(key);
187 next.set_map();
188 return next.get(keys...);
189 }
190
191private:
192 friend class JSONTree;
193 friend class JSONReadRecorder;
194
195 // Owns the values and the nodes of a tree. It is defined in the only source file that knows the JSON library.
196 class Storage;
197
198 JSONNode(Storage &storage, void *value, std::string key);
199
201 void *_value; // of the value type of the JSON library
202 std::string _key;
203};
204
205class JSONTree {
206public:
208
210
211 static std::unique_ptr<JSONTree> create();
212 static std::unique_ptr<JSONTree> create(std::istream &is);
213 static std::unique_ptr<JSONTree> create(std::string const &str);
214
215private:
216 explicit JSONTree(std::unique_ptr<JSONNode::Storage> storage);
217
218 std::unique_ptr<JSONNode::Storage> _storage;
219};
220
221std::ostream &operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s);
222
223template <class T>
224std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::children_view const &cv)
225{
226 for (const auto &e : cv) {
227 v.push_back(e.val_t<T>());
228 }
229 return v;
230}
231
232template <class T>
233std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::const_children_view const &cv)
234{
235 for (const auto &e : cv) {
236 v.push_back(e.val_t<T>());
237 }
238 return v;
239}
240
241template <class T>
242std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode const &n)
243{
244 if (!n.is_seq()) {
245 throw std::runtime_error("node " + n.key() + " is not of sequence type!");
246 }
247 v << n.children();
248 return v;
249}
250
252{
253 n.fill_seq(v);
254 return n;
255}
256
258{
259 n.fill_seq(v);
260 return n;
261}
262
264{
265 n.fill_seq(v);
266 return n;
267}
268
269template <class Key, class T, class Hash, class KeyEqual, class Allocator>
271operator<<(RooFit::Detail::JSONNode &n, const std::unordered_map<Key, T, Hash, KeyEqual, Allocator> &m)
272{
273 n.set_map();
274 for (const auto &it : m) {
275 n[it.first] << it.second;
276 }
277 return n;
278}
279
280template <class Key, class T, class Compare, class Allocator>
281RooFit::Detail::JSONNode &operator<<(RooFit::Detail::JSONNode &n, const std::map<Key, T, Compare, Allocator> &m)
282{
283 n.set_map();
284 for (const auto &it : m) {
285 n[it.first] << it.second;
286 }
287 return n;
288}
289
290template <>
291inline int JSONNode::val_t<int>() const
292{
293 return val_int();
294}
295template <>
296inline double JSONNode::val_t<double>() const
297{
298 return val_double();
299}
300template <>
301inline bool JSONNode::val_t<bool>() const
302{
303 return val_bool();
304}
305template <>
306inline std::string JSONNode::val_t<std::string>() const
307{
308 return val();
309}
310
311} // namespace Detail
312} // namespace RooFit
313
314#endif
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define e(i)
Definition RSha256.hxx:103
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t child
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
friend bool operator==(child_iterator_t const &lhs, child_iterator_t const &rhs)
friend bool operator!=(child_iterator_t const &lhs, child_iterator_t const &rhs)
child_iterator_t< Nd > begin() const
children_view_t(child_iterator_t< Nd > const &b_, child_iterator_t< Nd > const &e_)
child_iterator_t< Nd > end() const
JSONNode & operator[](std::string const &k)
JSONNode & get(std::string const &key)
void erase(std::string const &key)
Remove a child of a map, if it exists.
void fill_seq(Collection const &coll, size_t nmax)
JSONNode & get(std::string const &key, Keys_t const &...keys)
void fill_seq(Collection const &coll)
JSONNode const * find(std::string const &key, Keys_t const &...keys) const
void writeJSON(std::ostream &os) const
JSONNode & operator<<(std::string const &s)
std::string val() const
JSONNode & operator=(JSONNode const &)=delete
JSONNode & operator<<(const char *s)
void fill_seq(Collection const &coll, TransformationFunc func)
void fill_mat(Matrix const &mat)
JSONNode const * find(std::string const &key) const
JSONNode(JSONNode const &)=delete
const JSONNode & operator>>(std::string &v) const
bool has_child(std::string const &) const
std::string key() const
Records which components of a JSON map are read while it is alive, through any node of the tree.
static std::unique_ptr< JSONTree > create()
JSONTree(std::unique_ptr< JSONNode::Storage > storage)
std::unique_ptr< JSONNode::Storage > _storage
Int_t GetNrows() const
Int_t GetNcols() const
const Int_t n
Definition legend1.C:16
std::ostream & operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition CodegenImpl.h:73
TMarker m
Definition textangle.C:8