17#include "TClassEdit.h"
20#include "TMemberStreamer.h"
21#include "TStreamerElement.h"
22#include "TStreamerInfo.h"
24#include "TDataMember.h"
25#include "TMethodCall.h"
26#include "TInterpreter.h"
52class DataVectorConvertStreamer
53 :
public TMemberStreamer
65 DataVectorConvertStreamer (TClass* cl, TClass* from, TClass* to);
83 void* convert_ptr (
void* from);
107DataVectorConvertStreamer::DataVectorConvertStreamer (TClass* cl,
124DataVectorConvertStreamer::operator() (TBuffer& b,
134 std::vector<void*>*
obj = (std::vector<void*>*)pmember;
140 m_cl->Streamer (obj, b);
143 std::vector<void*>&
v = *
obj;
144 size_t len =
v.size();
145 for (
unsigned i=0;
i < len;
i++)
146 v[i] = convert_ptr (v[i]);
160void* DataVectorConvertStreamer::convert_ptr (
void* from)
164 if (m_from == m_to || from == 0)
178 TClass* cl_actual = m_from->GetActualClass (from);
181 int offs1 = cl_actual->GetBaseClassOffset (m_from);
182 int offs2 = cl_actual->GetBaseClassOffset (m_to);
183 if (offs1 < 0 || offs2 < 0)
185 return (
char*)from - offs1 + offs2;
191 std::ostringstream
os;
192 os <<
"dynamic_cast<" << m_to->GetName() <<
"*>((" << m_from->GetName() <<
"*)" << from <<
")";
193 std::string
line =
os.str();
194 Long_t ret = gInterpreter->Calc (
line.c_str());
195 return reinterpret_cast<void*
> (ret);
219TClass* find_class (RootUtils::ILogger* logfn,
221 const std::string& name,
224 std::string name2 =
name;
229 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
231 name2 = TClassEdit::ShortType (name2.c_str(), TClassEdit::kInnerClass);
232 name2 = TClassEdit::ShortType (name2.c_str(), TClassEdit::kDropTrailStar);
234 TClass*
cls = gROOT->GetClass (name2.c_str());
235 if (cls == 0 && logfn) {
236 std::ostringstream
ss;
237 ss << dv_class->GetName() <<
": Can't find class " << name2;
238 logfn->
debug (
ss.str().c_str());
254int get_member_offset (TClass* dv_class, TDataMember* dm)
257 meth.InitWithPrototype (dv_class,
"baseOffset",
"const std::type_info&");
258 if (!meth.IsValid()) {
261 TClass* mcls =
dm->GetClass();
263 meth.SetParam (
reinterpret_cast<Long_t
> (mcls->GetTypeInfo()));
266 TRealData* rd = mcls->GetRealData (
dm->GetName());
268 return rd->GetThisOffset() + ret;
286void diddle_dv_streaminfo (RootUtils::ILogger* logfn,
289 TStreamerElement* sie0,
290 TStreamerElement* sie1)
294 std::string vec_name = sie1->GetTypeName();
300 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
301 if (std::abs(TClassEdit::IsSTLCont (vec_name.c_str(), 0)) !=
310 std::ostringstream
ss;
311 ss << dv_class->GetName() <<
": Type to be converted is not a vector: "
313 logfn->
debug (
ss.str().c_str());
321 TClass* cl_from = find_class (logfn, dv_class, vec_name,
true);
322 TClass* cl_to = find_class (logfn, dv_class, sie0->GetTypeName(),
true);
323 TClass* vcls = find_class (logfn, dv_class, vec_name);
324 if (cl_from == 0 || cl_to == 0 || vcls == 0)
329 sie1->SetTypeName (sie0->GetTypeName());
330 sie1->TStreamerElement::SetStreamer
331 (
new DataVectorConvertStreamer (vcls, cl_from, cl_to));
334 TIter
next (si1->GetElements());
335 while (TStreamerElement* elem =
dynamic_cast<TStreamerElement*
> (
next())) {
337 TRealData* rd = dv_class->GetRealData (
elem->GetName());
344 int offs = get_member_offset (dv_class, rd->GetDataMember());
346 elem->SetOffset (offs);
348 elem->SetNewType (-2);
351 elem->SetNewType (-2);
356 auto errhand = [](
int ,
bool ,
const char* ,
const char*
msg)
358 if (strstr (
msg,
"No information on the alignment") != 0) {
363 RootUtils::WithRootErrorHandler eh (errhand);
377void test_dv (RootUtils::ILogger* logfn,
381 std::ostringstream
ss;
382 ss <<
"Testing class " << dv_class->GetName()
383 <<
" for possible back-compatibility conversions.";
384 logfn->
debug (
ss.str().c_str());
388 const TObjArray* infos = dv_class->GetStreamerInfos();
391 std::ostringstream
ss;
392 ss << dv_class->GetName() <<
": Can't find TStreamerInfo list.";
393 logfn->
debug (
ss.str().c_str());
399 if (infos->GetEntries() == 0)
403 int dv_vers = dv_class->GetClassVersion();
404 TVirtualStreamerInfo* si0 = dv_class->GetStreamerInfo();
407 std::ostringstream
ss;
408 ss << dv_class->GetName() <<
": Can't find primary shape.";
409 logfn->
debug (
ss.str().c_str());
416 TStreamerElement* sie0 = si0->GetStreamerElement (
"m_pCont", offset);
417 bool isvec = (sie0 != 0);
422 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
423 if (std::abs(TClassEdit::IsSTLCont (sie0->GetTypeName(), 0)) !=
432 std::ostringstream
ss;
433 ss << dv_class->GetName() <<
": m_pCont not present, or not a vector.";
434 logfn->
debug (
ss.str().c_str());
443 Int_t nent = infos->GetEntriesFast();
444 for (Int_t i = 0;
i < nent;
i++) {
445 if (i == dv_vers)
continue;
446 TStreamerInfo* si1 =
dynamic_cast<TStreamerInfo*
>(infos->At (i));
448 TStreamerElement* sie1 = si1->GetStreamerElement (
"m_pCont", offset);
449 if (sie1 != 0 && strcmp (sie0->GetTypeName(), sie1->GetTypeName()) != 0){
451 std::ostringstream
ss;
452 ss << dv_class->GetName()
453 <<
": SI slot " <<
i <<
" has m_pCont with type "
454 << sie1->GetTypeName() <<
"; needs adjustment.";
455 logfn->
debug (
ss.str().c_str());
457 diddle_dv_streaminfo (logfn, dv_class, si1, sie0, sie1);
467namespace DataModelAthenaPool {
483 std::lock_guard<std::mutex>
lock (m);
488 TIter next (gROOT->GetListOfClasses());
489 while (TClass* cls =
dynamic_cast<TClass*
> (next())) {
490 if (std::strncmp (cls->GetName(),
"DataVector<", 11) == 0) {
491 if (std::find (s_seen.begin(), s_seen.end(), cls) == s_seen.end()) {
492 test_dv (logfn, cls);
493 s_seen.push_back (cls);
Provide backwards compatibility for reading DataVector classes.
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
size_t size() const
Number of registered mappings.
Run a MT piece of code with an alternate root error handler.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
static void initialize(RootUtils::ILogger *logfn=0)
Scan all known DataVector classes and fix up the Root data for any that need conversion.
Very simple interface for writing log messages.
virtual void debug(const char *msg)=0
Log a debugging message.
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]