ATLAS Offline Software
Loading...
Searching...
No Matches
DataStructure.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <iostream>
7
8#define BOOST_BIND_GLOBAL_PLACEHOLDERS // Needed to silence Boost pragma message
9#include "boost/property_tree/json_parser.hpp"
10
13
14
18
20 m_initialized(true),
23{}
24
25
30
32 m_initialized(true),
33 m_dataSPtr(std::make_shared<ptree>(std::move(data))),
35{}
36
37
38void
40{
41 clear();
42 m_initialized = true;
43 m_dataSPtr.reset();
44 m_dataPtr = &data;
45 update();
46}
47
48
49void
51{
52 clear();
53 m_initialized = true;
54 m_dataSPtr = std::make_shared<ptree>(std::move(data));
55 m_dataPtr = nullptr;
56 update();
57}
58
59void TrigConf::DataStructure::setName(const std::string& n) {
60 m_name = n;
61}
62
63
64void
66{
67 m_initialized = false;
68 m_dataSPtr = nullptr;
69 m_dataPtr = nullptr;
70}
71
72
73bool
75 return data().empty(); // just a key->value pair, no children
76}
77
78
79std::string
81 return data().get_value<std::string>();
82}
83
84bool
85TrigConf::DataStructure::hasAttribute(const std::string & key) const {
86 const auto & child = data().get_child_optional( key );
87 if( ! bool(child) ) // key does not exist
88 return false;
89 return child.get().empty(); // if empty then it is an attribute, otherwise a child note
90}
91
92bool
93TrigConf::DataStructure::isNull(const std::string & key) const {
94 auto child = data().get_child_optional( key );
95 if( ! child ) {
96 return false;
97 }
98 return child->get_value<std::string>() == "null";
99}
100
101
102std::string
104 return "DataStructure";
105}
106
107const std::string &
109 return m_name;
110}
111
112bool
113TrigConf::DataStructure::hasChild(const std::string & path) const {
114 const auto & child = data().get_child_optional( path );
115 return bool(child);
116}
117
118
119std::string
120TrigConf::DataStructure::operator[](const std::string & key) const
121{
122 const auto & obj = data().get_child(key);
123 // check if the key points to a plain string value
124 if ( !obj.empty() ) {
125 if ( obj.front().first.empty() ) {
126 throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' is not a simple attribute but a list [], it needs to be accessed via getList(\"" + key + "\") -> vector<DataStructure>");
127 } else {
128 throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' is not a simple attribute but an object {}, it needs to be accessed via getObject(\"" + key + "\") -> DataStructure");
129 }
130 }
131 return obj.data();
132}
133
134const std::string &
135TrigConf::DataStructure::getAttribute(const std::string & key, bool ignoreIfMissing, const std::string & def) const
136{
137 const auto & obj = data().get_child_optional(key);
138 if( !obj ) {
139 if( ignoreIfMissing ) {
140 return def;
141 } else {
142 throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' does not exist" );
143 }
144 }
145 // check if the key points to a plain string value
146 if ( !obj.get().empty() ) {
147 if ( obj.get().front().first.empty() ) {
148 throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' is not a simple attribute but a list [], it needs to be accessed via getList(\"" + key + "\") -> vector<DataStructure>");
149 } else {
150 throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' is not a simple attribute but an object {}, it needs to be accessed via getObject(\"" + key + "\") -> DataStructure");
151 }
152 }
153 return obj.get().data();
154}
155
156std::vector<TrigConf::DataStructure>
157TrigConf::DataStructure::getList(const std::string & pathToChild, bool ignoreIfMissing) const
158{
159 std::vector<TrigConf::DataStructure> childList;
160 const auto & list = data().get_child_optional(pathToChild);
161 if( ! list ) {
162 if ( ignoreIfMissing ) {
163 return childList;
164 } else {
165 throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' does not exist.");
166 }
167 }
168
169 // check if the pathToChild points to a list
170
171 // this check is not complete, because boost::ptree can not
172 // distinguish between and empty list and an empty string. In both cases
173 // the value is empty and there are no children
174
175 if ( list.get().empty() ) {
176 if ( list.get().get_value<std::string>() != "" ) {
177 // if the value is not empty, then it is for sure an attribute ("key" : "value")
178 throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not a list [] but a simple attribute, it needs to be accessed via [\"" + pathToChild + "\"] -> string");
179 }
180 // else: if the value is empty, we can not say for sure and will not
181 // give this debugging hint (an empty list will be returned
182 } else if ( ! list.get().front().first.empty() ) {
183 throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not a list [] but an object {}, it needs to be accessed via getObject(\"" + pathToChild + "\") -> DataStructure");
184 }
185
186 childList.reserve(list.get().size());
187
188 for( auto & childData : list.get() )
189 childList.emplace_back( childData.second );
190
191 return childList;
192}
193
194
195std::optional<std::vector<TrigConf::DataStructure> >
196TrigConf::DataStructure::getList_optional(const std::string & pathToChild) const
197{
198 if(data().find(pathToChild) == data().not_found()) {
199 return std::nullopt;
200 }
201 return std::optional<std::vector<TrigConf::DataStructure> >(getList(pathToChild));
202}
203
204
206TrigConf::DataStructure::getObject(const std::string & pathToChild, bool ignoreIfMissing) const
207{
208 const auto & obj = data().get_child_optional(pathToChild);
209 if( ! obj ) {
210 if ( ignoreIfMissing ) {
211 return DataStructure();
212 } else {
213 throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' does not exist.");
214 }
215 }
216 // check if the pathToChild is an attribute
217 if( obj.get().get_value<std::string>() != "" ) {
218 throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not an object {} but a simple attribute, it needs to be accessed via [\"" + pathToChild + "\"] -> string");
219 }
220 // check if the pathToChild points to a list
221 if ( obj.get().front().first.empty() ) {
222 throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not an object {} but a list [], it needs to be accessed via getList(\"" + pathToChild + "\") -> vector<DataStructure>");
223 }
224 return { obj.get() };
225}
226
227
228std::optional<TrigConf::DataStructure>
229TrigConf::DataStructure::getObject_optional(const std::string & pathToChild) const
230{
231
232 if(const auto & obj = data().get_child_optional(pathToChild)) {
233 // check if the pathToChild is an attribute
234 if( obj.get().get_value<std::string>() != "" ) {
235 throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not an object {} but a simple attribute, it needs to be accessed via [\"" + pathToChild + "\"] -> string");
236 }
237 // check if the pathToChild points to a list
238 if ( obj.get().front().first.empty() ) {
239 throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not an object {} but a list [], it needs to be accessed via getList(\"" + pathToChild + "\") -> vector<DataStructure>");
240 }
241 return std::optional<TrigConf::DataStructure>(obj.get());
242 }
243 return std::nullopt;
244}
245
246
247
248std::vector<std::string>
250{
251 std::vector<std::string> keys;
252 if ( ! data().empty() &&
253 ! data().front().first.empty() )
254 {
255 keys.reserve(data().size());
256 for( auto & entry : data() ) {
257 keys.push_back(entry.first);
258 }
259 }
260 return keys;
261}
262
263void
264TrigConf::DataStructure::printRaw(std::ostream & os) const
265{
266 boost::property_tree::json_parser::write_json( os, data() );
267}
268
269
270void
271TrigConf::DataStructure::print(std::ostream & os) const
272{
273 printElement("", data(), 0, os);
274 os << std::endl;
275}
276
277void
278TrigConf::DataStructure::printElement(const std::string& key, const ptree & data, uint level, std::ostream & os)
279{
280 constexpr char del = '"';
281
282 const std::string value = data.get_value<std::string>();
283
284 if( data.empty() ) { // no children, so just a key->value pair
285 uint n(4*level); while(n--) os << " ";
286 os << del << key << del << ": " << del << value << del;
287 return;
288 }
289
290
291 bool isArray ( data.begin()->first.empty() ); // dictionaries have keys, arrays don't
292 { uint n(4*level); while(n--) os << " "; }
293 if ( ! key.empty() )
294 os << del << key << del << ": ";
295 os << (isArray ? "[" : "{") << std::endl;
296
297 size_t childCounter = data.size();
298 for( const boost::property_tree::ptree::value_type & x : data ) {
299 printElement(x.first, x.second, level + 1, os);
300 if( --childCounter ) os << ",";
301 os << std::endl;
302 }
303 { uint n(4*level); while(n--) os << " "; }
304 os << (isArray ? "]" : "}");
305
306}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
unsigned int uint
#define x
static const Attributes_t empty
Base class for Trigger configuration data and wrapper around underlying representation.
std::optional< TrigConf::DataStructure > getObject_optional(const std::string &pathToChild) const
void setName(const std::string &n)
Setting the configuration element name.
std::shared_ptr< ptree > m_dataSPtr
virtual const std::string & name() const final
std::vector< DataStructure > getList(const std::string &pathToChild, bool ignoreIfMissing=false) const
Access to array structure.
bool m_initialized
if initialized, the underlying ptree is has been assigned to (can be empty)
const ptree & data() const
Access to the underlying data, if needed.
bool hasAttribute(const std::string &key) const
Check for attribute.
std::optional< std::vector< DataStructure > > getList_optional(const std::string &pathToChild) const
DataStructure()
Default constructor, leading to an uninitialized configuration object.
void setData(const ptree &data)
Setting the configuration data.
virtual void clear()
Clearing the configuration data.
std::vector< std::string > getKeys() const
Access to the keys of an DataStructure which presents a dictionary.
virtual std::string className() const
A string that is the name of the class.
std::string getValue() const
Access to simple content.
T getAttribute(const std::string &key, bool ignoreIfMissing=false, const T &def=T()) const
Access to simple attribute.
bool isNull(const std::string &key) const
Check if an attribute is null.
void printRaw(std::ostream &os=std::cout) const
virtual void update()
Update the internal data after modification of the data object.
static void printElement(const std::string &key, const ptree &data, uint level=0, std::ostream &os=std::cout)
Static function to print a ptree object.
bool hasChild(const std::string &path) const
Check if child exists.
DataStructure getObject(const std::string &pathToChild, bool ignoreIfMissing=false) const
Access to configuration object.
std::string operator[](const std::string &key) const
Access to simple attribute.
boost::property_tree::ptree ptree
bool isValue() const
Check for attribute.
virtual void print(std::ostream &os=std::cout) const
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
STL namespace.