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