17#include "TClassEdit.h"
19#include "TMemberStreamer.h"
20#include "TStreamerElement.h"
21#include "TStreamerInfo.h"
23#include "TDataMember.h"
24#include "TMethodCall.h"
25#include "TInterpreter.h"
51class DataVectorConvertStreamer
52 :
public TMemberStreamer
64 DataVectorConvertStreamer (TClass* cl, TClass* from, TClass* to);
82 void* convert_ptr (
void* from);
106DataVectorConvertStreamer::DataVectorConvertStreamer (TClass* cl,
123DataVectorConvertStreamer::operator() (TBuffer& b,
133 std::vector<void*>*
obj = (std::vector<void*>*)pmember;
139 m_cl->Streamer (obj, b);
142 std::vector<void*>&
v = *
obj;
143 size_t len =
v.size();
144 for (
unsigned i=0;
i < len;
i++)
145 v[i] = convert_ptr (v[i]);
159void* DataVectorConvertStreamer::convert_ptr (
void* from)
163 if (m_from == m_to || from == 0)
177 TClass* cl_actual = m_from->GetActualClass (from);
180 int offs1 = cl_actual->GetBaseClassOffset (m_from);
181 int offs2 = cl_actual->GetBaseClassOffset (m_to);
182 if (offs1 < 0 || offs2 < 0)
184 return (
char*)from - offs1 + offs2;
190 std::ostringstream
os;
191 os <<
"dynamic_cast<" << m_to->GetName() <<
"*>((" << m_from->GetName() <<
"*)" << from <<
")";
192 std::string
line =
os.str();
193 Long_t ret = gInterpreter->Calc (
line.c_str());
194 return reinterpret_cast<void*
> (ret);
218TClass* find_class (RootUtils::ILogger* logfn,
220 const std::string& name,
223 std::string name2 =
name;
228 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
230 name2 = TClassEdit::ShortType (name2.c_str(), TClassEdit::kInnerClass);
231 name2 = TClassEdit::ShortType (name2.c_str(), TClassEdit::kDropTrailStar);
233 TClass*
cls = gROOT->GetClass (name2.c_str());
234 if (cls == 0 && logfn) {
235 std::ostringstream
ss;
236 ss << dv_class->GetName() <<
": Can't find class " << name2;
237 logfn->
debug (
ss.str().c_str());
253int get_member_offset (TClass* dv_class, TDataMember* dm)
256 meth.InitWithPrototype (dv_class,
"baseOffset",
"const std::type_info&");
257 if (!meth.IsValid()) {
260 TClass* mcls =
dm->GetClass();
262 meth.SetParam (
reinterpret_cast<Long_t
> (mcls->GetTypeInfo()));
265 TRealData* rd = mcls->GetRealData (
dm->GetName());
267 return rd->GetThisOffset() + ret;
285void diddle_dv_streaminfo (RootUtils::ILogger* logfn,
288 TStreamerElement* sie0,
289 TStreamerElement* sie1)
293 std::string vec_name = sie1->GetTypeName();
299 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
300 if (std::abs(TClassEdit::IsSTLCont (vec_name.c_str(), 0)) !=
309 std::ostringstream
ss;
310 ss << dv_class->GetName() <<
": Type to be converted is not a vector: "
312 logfn->
debug (
ss.str().c_str());
320 TClass* cl_from = find_class (logfn, dv_class, vec_name,
true);
321 TClass* cl_to = find_class (logfn, dv_class, sie0->GetTypeName(),
true);
322 TClass* vcls = find_class (logfn, dv_class, vec_name);
323 if (cl_from == 0 || cl_to == 0 || vcls == 0)
328 sie1->SetTypeName (sie0->GetTypeName());
329 sie1->TStreamerElement::SetStreamer
330 (
new DataVectorConvertStreamer (vcls, cl_from, cl_to));
333 TIter
next (si1->GetElements());
334 while (TStreamerElement* elem =
dynamic_cast<TStreamerElement*
> (
next())) {
336 TRealData* rd = dv_class->GetRealData (
elem->GetName());
343 int offs = get_member_offset (dv_class, rd->GetDataMember());
345 elem->SetOffset (offs);
347 elem->SetNewType (-2);
350 elem->SetNewType (-2);
355 auto errhand = [](
int ,
bool ,
const char* ,
const char*
msg)
357 if (strstr (
msg,
"No information on the alignment") != 0) {
362 RootUtils::WithRootErrorHandler eh (errhand);
376void test_dv (RootUtils::ILogger* logfn,
380 std::ostringstream
ss;
381 ss <<
"Testing class " << dv_class->GetName()
382 <<
" for possible back-compatibility conversions.";
383 logfn->
debug (
ss.str().c_str());
387 const TObjArray* infos = dv_class->GetStreamerInfos();
390 std::ostringstream
ss;
391 ss << dv_class->GetName() <<
": Can't find TStreamerInfo list.";
392 logfn->
debug (
ss.str().c_str());
398 if (infos->GetEntries() == 0)
402 int dv_vers = dv_class->GetClassVersion();
403 TVirtualStreamerInfo* si0 = dv_class->GetStreamerInfo();
406 std::ostringstream
ss;
407 ss << dv_class->GetName() <<
": Can't find primary shape.";
408 logfn->
debug (
ss.str().c_str());
415 TStreamerElement* sie0 = si0->GetStreamerElement (
"m_pCont", offset);
416 bool isvec = (sie0 != 0);
421 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
422 if (std::abs(TClassEdit::IsSTLCont (sie0->GetTypeName(), 0)) !=
431 std::ostringstream
ss;
432 ss << dv_class->GetName() <<
": m_pCont not present, or not a vector.";
433 logfn->
debug (
ss.str().c_str());
442 Int_t nent = infos->GetEntriesFast();
443 for (Int_t i = 0;
i < nent;
i++) {
444 if (i == dv_vers)
continue;
445 TStreamerInfo* si1 =
dynamic_cast<TStreamerInfo*
>(infos->At (i));
447 TStreamerElement* sie1 = si1->GetStreamerElement (
"m_pCont", offset);
448 if (sie1 != 0 && strcmp (sie0->GetTypeName(), sie1->GetTypeName()) != 0){
450 std::ostringstream
ss;
451 ss << dv_class->GetName()
452 <<
": SI slot " <<
i <<
" has m_pCont with type "
453 << sie1->GetTypeName() <<
"; needs adjustment.";
454 logfn->
debug (
ss.str().c_str());
456 diddle_dv_streaminfo (logfn, dv_class, si1, sie0, sie1);
466namespace DataModelAthenaPool {
482 std::lock_guard<std::mutex>
lock (m);
487 TIter next (gROOT->GetListOfClasses());
488 while (TClass* cls =
dynamic_cast<TClass*
> (next())) {
489 if (std::strncmp (cls->GetName(),
"DataVector<", 11) == 0) {
490 if (std::find (s_seen.begin(), s_seen.end(), cls) == s_seen.end()) {
491 test_dv (logfn, cls);
492 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()) ]