ATLAS Offline Software
AthDictLoaderSvc.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // AthDictLoaderSvc.cxx
8 // Implementation file for class AthDictLoaderSvc
9 // Author: S.Binet<binet@cern.ch>
11 
12 // AthenaServices includes
13 #include "AthDictLoaderSvc.h"
14 
15 // STL includes
16 
17 // FrameWork includes
18 #include "Gaudi/Property.h"
19 #include "GaudiKernel/System.h"
20 #include "AthenaKernel/BaseInfo.h"
22 #include "AthenaKernel/ITPCnvSvc.h"
24 #include "TClassEdit.h"
25 
26 
27 namespace {
28 
29 bool startsWith (const std::string& a, const std::string& b)
30 {
31  return (a.compare (0, b.size(), b) == 0);
32 }
33 
34 } // anonymous namespace
35 
36 // Constructors
39  ISvcLocator* pSvcLocator) :
40  base_class( name, pSvcLocator ),
41  m_dsodb (nullptr),
42  m_clidSvc ("ClassIDSvc", name),
43  m_tpCnvSvc("AthTPCnvSvc", name)
44 {
45 }
46 
47 // Destructor
50 {}
51 
52 // Athena Service's Hooks
55 {
56  ATH_MSG_INFO ("in initialize...");
58  if (!m_dsodb) {
59  ATH_MSG_ERROR("could not acquire Dso-registry");
60  return StatusCode::FAILURE;
61  }
62  ATH_MSG_INFO ("acquired Dso-registry");
63 
64  ATH_CHECK( m_clidSvc.retrieve() );
65  ATH_CHECK( m_tpCnvSvc.retrieve() );
66 
67  return StatusCode::SUCCESS;
68 }
69 
71 {
72  ATH_MSG_INFO ("in finalize...");
73  return StatusCode::SUCCESS;
74 }
75 
78 bool
79 AthDictLoaderSvc::has_type (const std::string& type_name)
80 {
81  if (!m_dsodb)
82  return false;
83 
84  bool has_type = m_dsodb->has_type(type_name);
85  if (!has_type) {
86  ATH_MSG_DEBUG ("no reflex dict. for type [" << type_name << "]");
87  }
88 
89  return has_type;
90 }
91 
94 bool
95 AthDictLoaderSvc::has_type (const std::type_info& typeinfo)
96 {
97  return has_type (System::typeinfoName(typeinfo).c_str());
98 }
99 
102 bool
104 {
105  bool ret = false;
106  std::string name = "<N/A>";
107  if (m_clidSvc->getTypeNameOfID(clid, name).isSuccess()) {
108  ret = has_type (name);
109  if (ret) {
110  return ret;
111  }
112  }
113 
114  // try out the typeinfoname...
115  if (m_clidSvc->getTypeInfoNameOfID(clid, name).isSuccess()) {
116  ret = has_type (name);
117  if (ret) {
118  return ret;
119  }
120  }
121 
122  return ret;
123 }
124 
129 const RootType
130 AthDictLoaderSvc::load_type (const std::string& type_name,
131  bool recursive /* = false*/)
132 {
133  ATH_MSG_DEBUG ("loading [" << type_name << "]...");
134 
135  // MN: short-cutting all the dance with type names done in DSODB...
136  // may need verification
137  // return RootType::ByName (m_dsodb->load_type(type_name));
138  RootType rt = RootType::ByNameNoQuiet(type_name);
139 
140  if (recursive) {
141  load_recursive (rt);
142  }
143  return rt;
144 }
145 
152 const RootType
153 AthDictLoaderSvc::load_type (const std::type_info& typeinfo,
154  bool recursive /*= false*/)
155 {
157  ("loading [" << System::typeinfoName(typeinfo) << " (from typeinfo)]...");
158  return load_type (System::typeinfoName(typeinfo), recursive);
159 }
160 
165 const RootType
167 {
168  std::string name = "<N/A>";
169  if (!m_clidSvc->getTypeNameOfID(clid, name).isSuccess()) {
170  ATH_MSG_INFO ("could not retrieve typename for clid [" << clid << "]");
171  // try out the bare std::type_info if available...
172  const SG::BaseInfoBase* bib = SG::BaseInfoBase::find(clid);
173  if (bib) {
174  return load_type(bib->typeinfo(), recursive);
175  }
176  // fail early...
177  return RootType();
178  }
179 
180  ATH_MSG_DEBUG("loading [" << name << " (from clid="<<clid<<")]...");
181 
183  if (type) {
184  return type;
185  }
186 
187  // try out the typeinfo-name
188  m_clidSvc->getTypeInfoNameOfID(clid, name).ignore();
190  if (type) {
191  return type;
192  }
193 
194  // try out the bare std::type_info if available...
195  const SG::BaseInfoBase* bib = SG::BaseInfoBase::find(clid);
196  if (bib) {
197  return load_type(bib->typeinfo(), recursive);
198  }
199  // cppcheck-suppress identicalConditionAfterEarlyExit
200  return type;
201 }
202 
203 
205 {
206  Memo_t memo;
207  RootUtils::WithRootErrorHandler hand ([] (int, bool, const char*, const char*) { return false; });
208  load_recursive1 (typ, memo);
209 }
210 
211 void AthDictLoaderSvc::load_recursive1 (const std::string& tnam,
212  Memo_t& memo)
213 {
214  if (startsWith (tnam, "const ")) {
215  load_recursive1 (RootType::ByNameNoQuiet (tnam.substr (6, std::string::npos)),
216  memo);
217  }
218  else {
220  }
221 }
223 {
224  if (!typ) return;
225  if (typ.IsFundamental() || typ.IsPointer() || typ.IsEnum()) return;
226  if (!typ.IsClass()) return;
227  std::string nam = typ.Name();
228  if (!memo.insert (nam).second) return;
229  if (nam == "string" || nam == "std::string" ||
230  startsWith (nam, "basic_string<") ||
231  startsWith (nam, "std::basic_string<"))
232  {
233  return;
234  }
235  if (startsWith (nam, "vector<") || startsWith (nam, "std::vector<")) {
236  std::string eltclass;
237  {
238  // Protect against data race inside TClassEdit.
239  // https://github.com/root-project/root/issues/10353
240  // Should be fixed in root 6.26.02.
241  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
242  TClassEdit::TSplitType split (nam.c_str());
243  if (split.fElements.size() > 1) {
244  eltclass = split.fElements[1];
245  }
246  }
247  if (!eltclass.empty()) {
248  load_recursive1 (eltclass, memo);
249  return;
250  }
251 
252  }
253  else if (startsWith (nam, "DataVector<")) {
254  std::string eltclass;
255  {
256  // Protect against data race inside TClassEdit.
257  // https://github.com/root-project/root/issues/10353
258  // Should be fixed in root 6.26.02.
259  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
260  TClassEdit::TSplitType split (nam.c_str());
261  if (split.fElements.size() > 1) {
262  eltclass = split.fElements[1];
263  }
264  }
265  if (!eltclass.empty()) {
266  load_recursive1 (eltclass, memo);
267  return;
268  }
269  }
270  else if (startsWith (nam, "pair<") || startsWith (nam, "std::pair<")) {
271  std::string pclass1, pclass2;
272  {
273  // Protect against data race inside TClassEdit.
274  // https://github.com/root-project/root/issues/10353
275  // Should be fixed in root 6.26.02.
276  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
277  TClassEdit::TSplitType split (nam.c_str());
278  if (split.fElements.size() > 2) {
279  pclass1 = split.fElements[1];
280  pclass2 = split.fElements[2];
281  }
282  }
283  if (!pclass1.empty()) {
284  load_recursive1 (pclass1, memo);
285  load_recursive1 (pclass2, memo);
286  return;
287  }
288  }
289  else if (startsWith (nam, "map<") || startsWith (nam, "std::map<")) {
290  std::string pclass1, pclass2;
291  {
292  // Protect against data race inside TClassEdit.
293  // https://github.com/root-project/root/issues/10353
294  // Should be fixed in root 6.26.02.
295  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
296  TClassEdit::TSplitType split (nam.c_str());
297  if (split.fElements.size() > 2) {
298  pclass1 = split.fElements[1];
299  pclass2 = split.fElements[2];
300  }
301  }
302  if (!pclass1.empty()) {
303  load_recursive1 (pclass1, memo);
304  load_recursive1 (pclass2, memo);
305  // For ROOT persistency.
306  std::string pname = "std::pair<" + pclass1 + "," + pclass2 + ">";
307  load_type (pname);
308  return;
309  }
310  }
311  else if (startsWith (nam, "LArConditionsContainer<")) {
312  std::string pname;
313  {
314  // Protect against data race inside TClassEdit.
315  // https://github.com/root-project/root/issues/10353
316  // Should be fixed in root 6.26.02.
317  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
318  TClassEdit::TSplitType split (nam.c_str());
319  if (split.fElements.size() > 1) {
320  pname = "LArConditionsSubset<" + split.fElements[1] + ">";
321  }
322  }
323  if (!pname.empty()) {
324  load_recursive1 (pname, memo);
325 
326  std::unique_ptr<ITPCnvBase> tpcnv = m_tpCnvSvc->t2p_cnv_unique (pname);
327  if (tpcnv) {
328  load_type (tpcnv->persistentTInfo(), true);
329  }
330  return;
331  }
332  }
333 
334  size_t nbase = typ.BaseSize();
335  for (size_t i = 0; i < nbase; i++) {
336  load_recursive1 (typ.BaseAt(i).Name(), memo);
337  }
338 
339  size_t nmem = typ.DataMemberSize();
340  for (size_t i = 0; i < nmem; i++) {
341  RootType mem = typ.DataMemberAt(i).TypeOf();
342  load_recursive1 (mem, memo);
343  }
344 }
TScopeAdapter::DataMemberSize
size_t DataMemberSize() const
Definition: RootType.cxx:797
TScopeAdapter::ByNameNoQuiet
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition: RootType.cxx:581
AthDictLoaderSvc::m_tpCnvSvc
ServiceHandle< ITPCnvSvc > m_tpCnvSvc
Definition: AthDictLoaderSvc.h:114
AthDictLoaderSvc::Memo_t
std::unordered_set< std::string > Memo_t
Definition: AthDictLoaderSvc.h:117
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Ath::DsoDb::instance
static const DsoDb * instance()
factory for the DsoDb
Definition: DsoDb.cxx:237
ITPCnvSvc.h
AthDictLoaderSvc::~AthDictLoaderSvc
virtual ~AthDictLoaderSvc()
Destructor:
Definition: AthDictLoaderSvc.cxx:49
AthDictLoaderSvc.h
ITPCnvBase.h
TScopeAdapter::IsClass
Bool_t IsClass() const
Definition: RootType.cxx:911
RootType
TTypeAdapter RootType
Definition: RootType.h:211
Ath::DsoDb::has_type
bool has_type(const std::string &type_name) const
Definition: DsoDb.cxx:263
AthDictLoaderSvc::load_recursive
void load_recursive(const RootType &typ)
Definition: AthDictLoaderSvc.cxx:204
TMemberAdapter::TypeOf
TTypeAdapter TypeOf() const
Definition: RootType.cxx:160
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Athena::typeinfoName
std::string typeinfoName(const std::type_info &ti)
Convert a type_info to a demangled string.
Definition: AthenaKernel/src/ClassName.cxx:23
lumiFormat.i
int i
Definition: lumiFormat.py:85
BaseInfo.h
Provide an interface for finding inheritance information at run time.
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TScopeAdapter::IsPointer
Bool_t IsPointer() const
Definition: RootType.cxx:697
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
AthDictLoaderSvc::AthDictLoaderSvc
AthDictLoaderSvc()
Default constructor:
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
AthDictLoaderSvc::m_dsodb
const Ath::DsoDb * m_dsodb
dictionary of all known (reflex) types
Definition: AthDictLoaderSvc.h:108
TScopeAdapter::Name
std::string Name(unsigned int mod=Reflex::SCOPED) const
Definition: RootType.cxx:607
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
SG::BaseInfoBase::find
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition: BaseInfo.cxx:569
RootUtils::WithRootErrorHandler
Run a MT piece of code with an alternate root error handler.
Definition: WithRootErrorHandler.h:56
AthDictLoaderSvc::m_clidSvc
ServiceHandle< IClassIDSvc > m_clidSvc
handle to a IClassIDSvc to handle loading of types by CLID
Definition: AthDictLoaderSvc.h:112
WithRootErrorHandler.h
Run a MT piece of code with an alternate root error handler.
AthDictLoaderSvc::finalize
virtual StatusCode finalize() override
Definition: AthDictLoaderSvc.cxx:70
TScopeAdapter::IsFundamental
Bool_t IsFundamental() const
Definition: RootType.cxx:726
a
TList * a
Definition: liststreamerinfos.cxx:10
TBaseAdapter::Name
std::string Name() const
Definition: RootType.cxx:356
AthDictLoaderSvc::load_recursive1
void load_recursive1(const std::string &tnam, Memo_t &memo)
Definition: AthDictLoaderSvc.cxx:211
ITPCnvBase::persistentTInfo
virtual const std::type_info & persistentTInfo() const =0
return C++ type id of the persistent class this converter is for
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
SG::BaseInfoBase
The non-template portion of the BaseInfo implementation.
Definition: Control/AthenaKernel/AthenaKernel/BaseInfo.h:451
TScopeAdapter::IsEnum
Bool_t IsEnum() const
Definition: RootType.cxx:733
AthDictLoaderSvc::load_type
virtual const RootType load_type(const std::string &type_name, bool recursive=false) override
retrieve a Reflex::Type by name (auto)loading the dictionary by any necessary means.
Definition: AthDictLoaderSvc.cxx:130
TScopeAdapter::BaseSize
size_t BaseSize() const
Definition: RootType.cxx:749
generateReferenceFile.recursive
recursive
Definition: generateReferenceFile.py:12
TScopeAdapter::DataMemberAt
TMemberAdapter DataMemberAt(size_t nth) const
Definition: RootType.cxx:807
SG::BaseInfoBase::typeinfo
const std::type_info & typeinfo() const
Return the std::type_info for this class.
Definition: BaseInfo.cxx:151
AthDictLoaderSvc::has_type
virtual bool has_type(const std::string &type_name) override
check a Reflex dictionary exists for a given type
Definition: AthDictLoaderSvc.cxx:79
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
TScopeAdapter
Definition: RootType.h:119
AthDictLoaderSvc::initialize
virtual StatusCode initialize() override
Gaudi Service Implementation.
Definition: AthDictLoaderSvc.cxx:54
TScopeAdapter::BaseAt
TBaseAdapter BaseAt(size_t nth) const
Definition: RootType.cxx:773