Project
Loading...
Searching...
No Matches
ConfigurableParamHelper.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12//first version 8/2018, Sandro Wenzel
13
14#ifndef COMMON_SIMCONFIG_INCLUDE_SIMCONFIG_CONFIGURABLEPARAMHELPER_H_
15#define COMMON_SIMCONFIG_INCLUDE_SIMCONFIG_CONFIGURABLEPARAMHELPER_H_
16
18#include "TClass.h"
19#include <type_traits>
20#include <typeinfo>
21#include "TFile.h"
22
23namespace o2
24{
25namespace conf
26{
27
28// ----------------------------------------------------------------
29
30// Utility structure for passing around ConfigurableParam data member info
31// (where value is the string representation)
33 std::string name;
34 std::string value;
35 std::string provenance;
36
37 std::string toString(std::string const& prefix, bool showProv) const;
38};
39
40// ----------------------------------------------------------------
41
42// just a (non-templated) helper with exclusively private functions
43// used by ConfigurableParamHelper
45{
46 private:
47 static std::vector<ParamDataMember>* getDataMembersImpl(std::string const& mainkey, TClass* cl, void*,
48 std::map<std::string, ConfigurableParam::EParamProvenance> const* provmap, size_t virtualoffset);
49
50 static void fillKeyValuesImpl(std::string const& mainkey, TClass* cl, void*, boost::property_tree::ptree*,
51 std::map<std::string, std::pair<std::type_info const&, void*>>*,
52 EnumRegistry*, size_t offset);
53
54 static void printWarning(std::type_info const&);
55
56 static void assignmentImpl(std::string const& mainkey, TClass* cl, void* to, void* from,
57 std::map<std::string, ConfigurableParam::EParamProvenance>* provmap, size_t offset);
58 static void syncCCDBandRegistry(std::string const& mainkey, TClass* cl, void* to, void* from,
59 std::map<std::string, ConfigurableParam::EParamProvenance>* provmap, size_t offset);
60
61 static void outputMembersImpl(std::ostream& out, std::string const& mainkey, std::vector<ParamDataMember> const* members, bool showProv, bool useLogger);
62 static void printMembersImpl(std::string const& mainkey, std::vector<ParamDataMember> const* members, bool showProv, bool useLogger);
63
64 static size_t getHashImpl(std::string const& mainkey, std::vector<ParamDataMember> const* members);
65
66 template <typename P>
68
69 template <typename Base, typename P>
71};
72
73// ----------------------------------------------------------------
74
75// implementer (and checker) for concrete ConfigurableParam classes P
76template <typename P>
78{
79 public:
81 static const P& Instance()
82 {
83 return P::sInstance;
84 }
85
86 // ----------------------------------------------------------------
87
88 std::string getName() const final
89 {
90 return P::sKey;
91 }
92
93 // ----------------------------------------------------------------
94 // get the provenace of the member with given key
95 EParamProvenance getMemberProvenance(const std::string& key) const final
96 {
97 return getProvenance(getName() + '.' + key);
98 }
99
100 // ----------------------------------------------------------------
101
102 // one of the key methods, using introspection to print itself
103 void printKeyValues(bool showProv = true, bool useLogger = false) const final
104 {
105 if (!isInitialized()) {
106 initialize();
107 }
108 auto members = getDataMembers();
109 _ParamHelper::printMembersImpl(getName(), members, showProv, useLogger);
110 }
111
112 //
113 size_t getHash() const final
114 {
115 return _ParamHelper::getHashImpl(getName(), getDataMembers());
116 }
117
118 // ----------------------------------------------------------------
119
120 void output(std::ostream& out) const final
121 {
122 auto members = getDataMembers();
123 _ParamHelper::outputMembersImpl(out, getName(), members, true, false);
124 }
125
126 // ----------------------------------------------------------------
127
128 // Grab the list of ConfigurableParam data members
129 // Returns a nullptr if the TClass of the P template class cannot be created.
130 std::vector<ParamDataMember>* getDataMembers() const
131 {
132 // just a helper line to make sure P::sInstance is looked-up
133 // and that compiler complains about missing static sInstance of type P
134 // volatile void* ptr = (void*)&P::sInstance;
135 // static assert on type of sInstance:
136 static_assert(std::is_same<decltype(P::sInstance), P>::value,
137 "static instance must of same type as class");
138
139 // obtain the TClass for P and delegate further
140 auto cl = TClass::GetClass(typeid(P));
141 if (!cl) {
142 _ParamHelper::printWarning(typeid(P));
143 return nullptr;
144 }
145
146 return _ParamHelper::getDataMembersImpl(getName(), cl, (void*)this, sValueProvenanceMap, 0);
147 }
148
149 // ----------------------------------------------------------------
150
151 // fills the data structures with the initial default values
152 void putKeyValues(boost::property_tree::ptree* tree) final
153 {
154 auto cl = TClass::GetClass(typeid(P));
155 if (!cl) {
156 _ParamHelper::printWarning(typeid(P));
157 return;
158 }
159 _ParamHelper::fillKeyValuesImpl(getName(), cl, (void*)this, tree, sKeyToStorageMap, sEnumRegistry, 0);
160 }
161
162 // ----------------------------------------------------------------
163
164 void initFrom(TFile* file) final
165 {
166 // switch off auto registering since the readback object is
167 // only a "temporary" singleton
168 setRegisterMode(false);
169 P* readback = nullptr;
170 file->GetObject(getName().c_str(), readback);
171 if (readback != nullptr) {
172 _ParamHelper::assignmentImpl(getName(), TClass::GetClass(typeid(P)), (void*)this, (void*)readback,
174 delete readback;
175 }
176 setRegisterMode(true);
177 }
178
179 // ----------------------------------------------------------------
180
181 void syncCCDBandRegistry(void* externalobj) final
182 {
183 // We may be getting an external copy from CCDB which is passed as externalobj.
184 // The task of this function is to
185 // a) update the internal registry with fields coming from CCDB
186 // but only if keys have not been modified via RT == command line / ini file
187 // b) update the external object with with fields having RT provenance
188 //
189 setRegisterMode(false);
190 _ParamHelper::syncCCDBandRegistry(getName(), TClass::GetClass(typeid(P)), (void*)this, (void*)externalobj,
192 setRegisterMode(true);
193 }
194
195 // ----------------------------------------------------------------
196
197 void serializeTo(TFile* file) const final
198 {
199 file->WriteObjectAny((void*)this, TClass::GetClass(typeid(P)), getName().c_str());
200 }
201};
202
203// Promotes a simple struct Base to a configurable parameter class
204// Aka implements all interfaces for a ConfigurableParam P, which shares or
205// takes the fields from a Base struct
206template <typename P, typename Base>
208{
209 public:
211
212 static const P& Instance()
213 {
214 return P::sInstance;
215 }
216
217 // extracts a copy of the underlying data struct
218 Base detach() const
219 {
220 static_assert(std::copyable<Base>, "Base type must be copyable.");
221 return static_cast<Base>(*this);
222 }
223
224 // ----------------------------------------------------------------
225 std::string getName() const final
226 {
227 return P::sKey;
228 }
229
230 // ----------------------------------------------------------------
231 // get the provenace of the member with given key
232 EParamProvenance getMemberProvenance(const std::string& key) const final
233 {
234 return getProvenance(getName() + '.' + key);
235 }
236
237 // ----------------------------------------------------------------
238
239 // one of the key methods, using introspection to print itself
240 void printKeyValues(bool showProv = true, bool useLogger = false) const final
241 {
242 if (!isInitialized()) {
243 initialize();
244 }
245 auto members = getDataMembers();
246 _ParamHelper::printMembersImpl(getName(), members, showProv, useLogger);
247 }
248
249 //
250 size_t getHash() const final
251 {
252 return _ParamHelper::getHashImpl(getName(), getDataMembers());
253 }
254
255 // ----------------------------------------------------------------
256
257 void output(std::ostream& out) const final
258 {
259 auto members = getDataMembers();
260 _ParamHelper::outputMembersImpl(out, getName(), members, true, false);
261 }
262
263 // ----------------------------------------------------------------
264
265 // Grab the list of ConfigurableParam data members
266 // Returns a nullptr if the TClass of the P template class cannot be created.
267 std::vector<ParamDataMember>* getDataMembers() const
268 {
269 // just a helper line to make sure P::sInstance is looked-up
270 // and that compiler complains about missing static sInstance of type P
271 // volatile void* ptr = (void*)&P::sInstance;
272 // static assert on type of sInstance:
273 static_assert(std::is_same<decltype(P::sInstance), P>::value,
274 "static instance must of same type as class");
275
276 // obtain the TClass for the Base type and delegate further
277 auto cl = TClass::GetClass(typeid(Base));
278 if (!cl) {
279 _ParamHelper::printWarning(typeid(Base));
280 return nullptr;
281 }
282
283 // we need to put an offset of 8 bytes since internally this is using data members of the Base class
284 // which doesn't account for the virtual table of P
285 return _ParamHelper::getDataMembersImpl(getName(), cl, (void*)this, sValueProvenanceMap, 8);
286 }
287
288 // ----------------------------------------------------------------
289
290 // fills the data structures with the initial default values
291 void putKeyValues(boost::property_tree::ptree* tree) final
292 {
293 auto cl = TClass::GetClass(typeid(Base));
294 if (!cl) {
295 _ParamHelper::printWarning(typeid(Base));
296 return;
297 }
298 _ParamHelper::fillKeyValuesImpl(getName(), cl, (void*)this, tree, sKeyToStorageMap, sEnumRegistry, 8);
299 }
300
301 // ----------------------------------------------------------------
302
303 void initFrom(TFile* file) final
304 {
305 // switch off auto registering since the readback object is
306 // only a "temporary" singleton
307 setRegisterMode(false);
308 P* readback = nullptr;
309 file->GetObject(getName().c_str(), readback);
310 if (readback != nullptr) {
311 _ParamHelper::assignmentImpl(getName(), TClass::GetClass(typeid(Base)), (void*)this, (void*)readback,
313 delete readback;
314 }
315 setRegisterMode(true);
316 }
317
318 // ----------------------------------------------------------------
319
320 void syncCCDBandRegistry(void* externalobj) final
321 {
322 // We may be getting an external copy from CCDB which is passed as externalobj.
323 // The task of this function is to
324 // a) update the internal registry with fields coming from CCDB
325 // but only if keys have not been modified via RT == command line / ini file
326 // b) update the external object with with fields having RT provenance
327 //
328 setRegisterMode(false);
329 _ParamHelper::syncCCDBandRegistry(getName(), TClass::GetClass(typeid(Base)), (void*)this, (void*)externalobj,
331 setRegisterMode(true);
332 }
333
334 // ----------------------------------------------------------------
335
336 void serializeTo(TFile* file) const final
337 {
338 file->WriteObjectAny((void*)this, TClass::GetClass(typeid(P)), getName().c_str());
339 }
340};
341
342} // namespace conf
343} // namespace o2
344
345#endif /* COMMON_SIMCONFIG_INCLUDE_SIMCONFIG_CONFIGURABLEPARAMHELPER_H_ */
StringRef key
void printKeyValues(bool showProv=true, bool useLogger=false) const final
EParamProvenance getMemberProvenance(const std::string &key) const final
void syncCCDBandRegistry(void *externalobj) final
void serializeTo(TFile *file) const final
void putKeyValues(boost::property_tree::ptree *tree) final
std::vector< ParamDataMember > * getDataMembers() const
void output(std::ostream &out) const final
void printKeyValues(bool showProv=true, bool useLogger=false) const final
std::vector< ParamDataMember > * getDataMembers() const
EParamProvenance getMemberProvenance(const std::string &key) const final
void serializeTo(TFile *file) const final
void output(std::ostream &out) const final
void putKeyValues(boost::property_tree::ptree *tree) final
void syncCCDBandRegistry(void *externalobj) final
static std::map< std::string, std::pair< std::type_info const &, void * > > * sKeyToStorageMap
static std::map< std::string, ConfigurableParam::EParamProvenance > * sValueProvenanceMap
static EParamProvenance getProvenance(const std::string &key)
static EnumRegistry * sEnumRegistry
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLintptr offset
Definition glcorearb.h:660
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string toString(std::string const &prefix, bool showProv) const
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))