ATLAS Offline Software
Loading...
Searching...
No Matches
AthDictLoaderSvc.cxx
Go to the documentation of this file.
1
2
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"
24#include "TClassEdit.h"
25
26
27namespace {
28
29bool 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
38AthDictLoaderSvc::AthDictLoaderSvc (const std::string& name,
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
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
78bool
79AthDictLoaderSvc::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
94bool
95AthDictLoaderSvc::has_type (const std::type_info& typeinfo)
96{
97 return has_type (System::typeinfoName(typeinfo).c_str());
98}
99
102bool
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
129const RootType
130AthDictLoaderSvc::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
152const RootType
153AthDictLoaderSvc::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
165const RootType
166AthDictLoaderSvc::load_type (CLID clid, bool recursive /*= false*/)
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
182 RootType type = load_type(name, recursive);
183 if (type) {
184 return type;
185 }
186
187 // try out the typeinfo-name
188 m_clidSvc->getTypeInfoNameOfID(clid, name).ignore();
189 type = load_type(name, recursive);
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
211void 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}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
Provide an interface for finding inheritance information at run time.
uint32_t CLID
The Class ID type.
TTypeAdapter RootType
Definition RootType.h:211
Run a MT piece of code with an alternate root error handler.
const Ath::DsoDb * m_dsodb
dictionary of all known (reflex) types
virtual bool has_type(const std::string &type_name) override
check a Reflex dictionary exists for a given type
void load_recursive1(const std::string &tnam, Memo_t &memo)
virtual ~AthDictLoaderSvc()
Destructor:
virtual StatusCode finalize() override
ServiceHandle< ITPCnvSvc > m_tpCnvSvc
std::unordered_set< std::string > Memo_t
virtual StatusCode initialize() override
Gaudi Service Implementation.
void load_recursive(const RootType &typ)
AthDictLoaderSvc()
Default constructor:
ServiceHandle< IClassIDSvc > m_clidSvc
handle to a IClassIDSvc to handle loading of types by CLID
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.
static const DsoDb * instance()
factory for the DsoDb
Definition DsoDb.cxx:237
Run a MT piece of code with an alternate root error handler.
The non-template portion of the BaseInfo implementation.
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition BaseInfo.cxx:570
const std::type_info & typeinfo() const
Return the std::type_info for this class.
Definition BaseInfo.cxx:151
std::string Name() const
Definition RootType.cxx:361
TTypeAdapter TypeOf() const
Definition RootType.cxx:160
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition RootType.cxx:586
Bool_t IsPointer() const
Definition RootType.cxx:702
size_t DataMemberSize() const
Definition RootType.cxx:802
Bool_t IsFundamental() const
Definition RootType.cxx:731
TMemberAdapter DataMemberAt(size_t nth) const
Definition RootType.cxx:812
TBaseAdapter BaseAt(size_t nth) const
Definition RootType.cxx:778
std::string Name(unsigned int mod=Reflex::SCOPED) const
Definition RootType.cxx:612
Bool_t IsEnum() const
Definition RootType.cxx:738
size_t BaseSize() const
Definition RootType.cxx:754
Bool_t IsClass() const
Definition RootType.cxx:916
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177