@@ -45,18 +45,18 @@ class _ParamHelper
4545{
4646 private:
4747 static std::vector<ParamDataMember>* getDataMembersImpl (std::string const & mainkey, TClass* cl, void *,
48- std::map<std::string, ConfigurableParam::EParamProvenance> const * provmap);
48+ std::map<std::string, ConfigurableParam::EParamProvenance> const * provmap, size_t virtualoffset );
4949
5050 static void fillKeyValuesImpl (std::string const & mainkey, TClass* cl, void *, boost::property_tree::ptree*,
5151 std::map<std::string, std::pair<std::type_info const &, void *>>*,
52- EnumRegistry*);
52+ EnumRegistry*, size_t offset );
5353
5454 static void printWarning (std::type_info const &);
5555
5656 static void assignmentImpl (std::string const & mainkey, TClass* cl, void * to, void * from,
57- std::map<std::string, ConfigurableParam::EParamProvenance>* provmap);
57+ std::map<std::string, ConfigurableParam::EParamProvenance>* provmap, size_t offset );
5858 static void syncCCDBandRegistry (std::string const & mainkey, TClass* cl, void * to, void * from,
59- std::map<std::string, ConfigurableParam::EParamProvenance>* provmap);
59+ std::map<std::string, ConfigurableParam::EParamProvenance>* provmap, size_t offset );
6060
6161 static void outputMembersImpl (std::ostream& out, std::string const & mainkey, std::vector<ParamDataMember> const * members, bool showProv, bool useLogger);
6262 static void printMembersImpl (std::string const & mainkey, std::vector<ParamDataMember> const * members, bool showProv, bool useLogger);
@@ -65,6 +65,9 @@ class _ParamHelper
6565
6666 template <typename P>
6767 friend class ConfigurableParamHelper ;
68+
69+ template <typename Base, typename P>
70+ friend class ConfigurableParamPromoter ;
6871};
6972
7073// ----------------------------------------------------------------
@@ -140,7 +143,7 @@ class ConfigurableParamHelper : virtual public ConfigurableParam
140143 return nullptr ;
141144 }
142145
143- return _ParamHelper::getDataMembersImpl (getName (), cl, (void *)this , sValueProvenanceMap );
146+ return _ParamHelper::getDataMembersImpl (getName (), cl, (void *)this , sValueProvenanceMap , 0 );
144147 }
145148
146149 // ----------------------------------------------------------------
@@ -153,7 +156,7 @@ class ConfigurableParamHelper : virtual public ConfigurableParam
153156 _ParamHelper::printWarning (typeid (P));
154157 return ;
155158 }
156- _ParamHelper::fillKeyValuesImpl (getName (), cl, (void *)this , tree, sKeyToStorageMap , sEnumRegistry );
159+ _ParamHelper::fillKeyValuesImpl (getName (), cl, (void *)this , tree, sKeyToStorageMap , sEnumRegistry , 0 );
157160 }
158161
159162 // ----------------------------------------------------------------
@@ -167,7 +170,7 @@ class ConfigurableParamHelper : virtual public ConfigurableParam
167170 file->GetObject (getName ().c_str (), readback);
168171 if (readback != nullptr ) {
169172 _ParamHelper::assignmentImpl (getName (), TClass::GetClass (typeid (P)), (void *)this , (void *)readback,
170- sValueProvenanceMap );
173+ sValueProvenanceMap , 0 );
171174 delete readback;
172175 }
173176 setRegisterMode (true );
@@ -185,7 +188,146 @@ class ConfigurableParamHelper : virtual public ConfigurableParam
185188 //
186189 setRegisterMode (false );
187190 _ParamHelper::syncCCDBandRegistry (getName (), TClass::GetClass (typeid (P)), (void *)this , (void *)externalobj,
188- sValueProvenanceMap );
191+ sValueProvenanceMap , 0 );
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
206+ template <typename P, typename Base>
207+ class ConfigurableParamPromoter : public Base , virtual public ConfigurableParam
208+ {
209+ public:
210+ using ConfigurableParam::ConfigurableParam;
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,
312+ sValueProvenanceMap , 8 );
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,
330+ sValueProvenanceMap , 8 );
189331 setRegisterMode (true );
190332 }
191333
0 commit comments