ATLAS Offline Software
getDynamicAuxID.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
16 #include "TClass.h"
17 #include "TROOT.h"
18 
19 
20 namespace SG {
21 
22 
27 TClass* getClassIfDictionaryExists (const std::string& cname)
28 {
29  if (TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname.c_str())) {
30  if (cl->IsLoaded() && cl->HasDictionary()) return cl;
31  return nullptr;
32  }
33 
34  // The idea of calling GetClassSharedLibs was to test if a class was
35  // listed in the rootmap file, so we could avoid autoparsing.
36  // This worked with older versions of root 6.
37  // But now root has started doing dynamic linking itself,
38  // and GetClassSharedLibs will itself trigger autoparsing.
39  // So currently, this test does more harm than good.
40  // Still need to see if we can find a reliable way of failing
41  // a TClass lookup rather than triggering autoparsing.
42  //if (gInterpreter->GetClassSharedLibs (cname.c_str()))
43  {
44  TClass* cl = TClass::GetClass (cname.c_str());
45  if (cl->HasDictionary())
46  return cl;
47  }
48  return nullptr;
49 }
50 
51 
64 SG::auxid_t getDynamicAuxID (const std::type_info& ti,
65  const std::string& name,
66  const std::string& elementTypeName,
67  const std::string& branchTypeName,
68  bool standalone,
69  SG::auxid_t linked_auxid)
70 {
72  SG::auxid_t auxid = SG::null_auxid;
73 
77  }
78 
79  auxid = r.getAuxID (ti, name, "", flags, linked_auxid);
80  if (auxid != SG::null_auxid) return auxid;
81 
82  // Be careful --- if we don't exactly match the name
83  // in TClassTable, then we may trigger autoparsing. Besides the
84  // resource usage that implies, that can lead to crashes in dbg
85  // builds due to cling bugs.
86  std::string tn = elementTypeName;
87  if (tn.starts_with("std::vector<"))
88  tn.erase (0, 5);
89  std::string fac_class_name = "SG::AuxTypeVectorFactory<" +
90  tn + ",allocator<" + tn;
91  if (fac_class_name[fac_class_name.size()-1] == '>')
92  fac_class_name += ' ';
93  fac_class_name += "> >";
94  TClass* fac_class = getClassIfDictionaryExists (fac_class_name);
95  if (fac_class)
96  {
97  TClass* base_class = getClassIfDictionaryExists ("SG::IAuxTypeVectorFactory");
98  if (base_class) {
99  int offs = fac_class->GetBaseClassOffset (base_class);
100  if (offs >= 0) {
101  void* fac_vp = fac_class->New();
102  if (fac_vp) {
103  SG::IAuxTypeVectorFactory* fac = reinterpret_cast<SG::IAuxTypeVectorFactory*> (reinterpret_cast<unsigned long>(fac_vp) + offs);
104  const std::type_info* tiAlloc = fac->tiAlloc();
105  r.addFactory (ti, *tiAlloc, std::unique_ptr<SG::IAuxTypeVectorFactory> (fac));
106  auxid = r.getAuxID(*fac->tiAlloc(), ti, name, "", flags, linked_auxid);
107  }
108  }
109  }
110  }
111 
112  if (auxid == SG::null_auxid) {
113  if (linked_auxid != SG::null_auxid) {
114  errorcheck::ReportMessage msg (MSG::INFO, ERRORCHECK_ARGS, "getDynamicAuxID");
115  msg << "dynamic ROOT vector factory not implemented for linked types: "
116  << name << " " << branchTypeName << "\n";
117  return SG::null_auxid;
118  }
119 
120  std::string vec_name = branchTypeName;
121  if (standalone) {
122  vec_name = "std::vector<" + branchTypeName;
123  if (vec_name[vec_name.size()-1] == '>')
124  vec_name += " ";
125  vec_name += ">";
126  }
127  TClass* vec_class = TClass::GetClass (vec_name.c_str());
128 
129  if (vec_class) {
130  auto facp = std::make_unique<SG::RootAuxVectorFactory> (vec_class);
131  std::string tiAllocName = facp->tiAllocName();
132  (void)r.addFactory (ti, tiAllocName, std::move (facp));
133  auxid = r.getAuxID(tiAllocName, ti, name, "", flags);
134  }
135  }
136 
137  return auxid;
138 }
139 
140 
141 } // namespace SG
beamspotman.r
def r
Definition: beamspotman.py:676
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::SkipNameCheck
@ SkipNameCheck
Definition: AuxTypes.h:81
L1CaloPhase1Monitoring.standalone
standalone
Definition: L1CaloPhase1Monitoring.py:112
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:640
AthenaPoolTestRead.flags
flags
Definition: AthenaPoolTestRead.py:8
errorcheck::ReportMessage
Helper class to use to report a message.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:173
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
SG::Linked
@ Linked
Mark that this variable is linked to another one.
Definition: AuxTypes.h:77
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
SG::getDynamicAuxID
SG::auxid_t getDynamicAuxID(const std::type_info &ti, const std::string &name, const std::string &elementTypeName, const std::string &branch_type_name, bool standalone, SG::auxid_t linked_auxid)
Find the auxid for a dynamic branch.
Definition: getDynamicAuxID.cxx:64
SG::IAuxTypeVectorFactory
Interface for factory objects that create vectors.
Definition: IAuxTypeVectorFactory.h:50
SG::IAuxTypeVectorFactory::tiAlloc
virtual const std::type_info * tiAlloc() const =0
Return the type_info of the vector allocator.
getDynamicAuxID.h
Find the auxid for a dynamic branch.
error.h
Helper for emitting error messages.
SG::AuxTypeRegistry::isLinkedName
static bool isLinkedName(const std::string &name)
Test if a variable name corresponds to a linked variable.
Definition: AuxTypeRegistry.cxx:1293
SG::AuxVarFlags
AuxVarFlags
Additional flags to qualify an auxiliary variable.
Definition: AuxTypes.h:58
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
SG::getClassIfDictionaryExists
TClass * getClassIfDictionaryExists(const std::string &cname)
Look up a TClass given a name.
Definition: getDynamicAuxID.cxx:27
RootAuxVectorFactory.h
Dynamic implementation of IAuxVectorFactory, relying on root's vector proxy.
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
ERRORCHECK_ARGS
#define ERRORCHECK_ARGS
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:323
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7