16 #include "TClassEdit.h"
18 #include "TMemberStreamer.h"
19 #include "TStreamerElement.h"
20 #include "TStreamerInfo.h"
21 #include "TRealData.h"
22 #include "TDataMember.h"
23 #include "TMethodCall.h"
24 #include "TInterpreter.h"
50 class DataVectorConvertStreamer
51 :
public TMemberStreamer
63 DataVectorConvertStreamer (TClass*
cl, TClass* from, TClass*
to);
72 virtual void operator() (TBuffer&
b,
void* pmember, Int_t
size=0);
81 void* convert_ptr (
void* from);
105 DataVectorConvertStreamer::DataVectorConvertStreamer (TClass*
cl,
122 DataVectorConvertStreamer::operator() (TBuffer&
b,
132 std::vector<void*>*
obj = (std::vector<void*>*)pmember;
138 m_cl->Streamer (
obj,
b);
141 std::vector<void*>&
v = *
obj;
142 size_t len =
v.size();
143 for (
unsigned i=0;
i < len;
i++)
144 v[
i] = convert_ptr (
v[
i]);
158 void* DataVectorConvertStreamer::convert_ptr (
void* from)
162 if (m_from == m_to || from == 0)
176 TClass* cl_actual = m_from->GetActualClass (from);
179 int offs1 = cl_actual->GetBaseClassOffset (m_from);
180 int offs2 = cl_actual->GetBaseClassOffset (m_to);
181 if (offs1 < 0 || offs2 < 0)
183 return (
char*)from - offs1 + offs2;
189 std::ostringstream
os;
190 os <<
"dynamic_cast<" << m_to->GetName() <<
"*>((" << m_from->GetName() <<
"*)" << from <<
")";
191 std::string
line =
os.str();
192 Long_t ret = gInterpreter->Calc (
line.c_str());
193 return reinterpret_cast<void*
> (ret);
219 const std::string&
name,
222 std::string name2 =
name;
227 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
229 name2 = TClassEdit::ShortType (name2.c_str(), TClassEdit::kInnerClass);
230 name2 = TClassEdit::ShortType (name2.c_str(), TClassEdit::kDropTrailStar);
232 TClass*
cls = gROOT->GetClass (name2.c_str());
233 if (
cls == 0 && logfn) {
234 std::ostringstream
ss;
235 ss << dv_class->GetName() <<
": Can't find class " << name2;
236 logfn->
debug (
ss.str().c_str());
252 int get_member_offset (TClass* dv_class, TDataMember*
dm)
255 meth.InitWithPrototype (dv_class,
"baseOffset",
"const std::type_info&");
256 if (!meth.IsValid()) {
259 TClass* mcls =
dm->GetClass();
261 meth.SetParam (
reinterpret_cast<Long_t
> (mcls->GetTypeInfo()));
264 TRealData* rd = mcls->GetRealData (
dm->GetName());
266 return rd->GetThisOffset() + ret;
287 TStreamerElement* sie0,
288 TStreamerElement* sie1)
292 std::string vec_name = sie1->GetTypeName();
298 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
299 if (std::abs(TClassEdit::IsSTLCont (vec_name.c_str(), 0)) !=
308 std::ostringstream
ss;
309 ss << dv_class->GetName() <<
": Type to be converted is not a vector: "
311 logfn->
debug (
ss.str().c_str());
319 TClass* cl_from = find_class (logfn, dv_class, vec_name,
true);
320 TClass* cl_to = find_class (logfn, dv_class, sie0->GetTypeName(),
true);
321 TClass* vcls = find_class (logfn, dv_class, vec_name);
322 if (cl_from == 0 || cl_to == 0 || vcls == 0)
327 sie1->SetTypeName (sie0->GetTypeName());
328 sie1->TStreamerElement::SetStreamer
329 (
new DataVectorConvertStreamer (vcls, cl_from, cl_to));
332 TIter
next (si1->GetElements());
333 while (TStreamerElement* elem =
dynamic_cast<TStreamerElement*
> (
next())) {
334 elem->SetNewType (elem->GetType());
335 TRealData* rd = dv_class->GetRealData (elem->GetName());
342 int offs = get_member_offset (dv_class, rd->GetDataMember());
344 elem->SetOffset (offs);
346 elem->SetNewType (-2);
349 elem->SetNewType (-2);
370 std::ostringstream
ss;
371 ss <<
"Testing class " << dv_class->GetName()
372 <<
" for possible back-compatibility conversions.";
373 logfn->
debug (
ss.str().c_str());
377 const TObjArray* infos = dv_class->GetStreamerInfos();
380 std::ostringstream
ss;
381 ss << dv_class->GetName() <<
": Can't find TStreamerInfo list.";
382 logfn->
debug (
ss.str().c_str());
388 if (infos->GetEntries() == 0)
392 int dv_vers = dv_class->GetClassVersion();
393 TVirtualStreamerInfo* si0 = dv_class->GetStreamerInfo();
396 std::ostringstream
ss;
397 ss << dv_class->GetName() <<
": Can't find primary shape.";
398 logfn->
debug (
ss.str().c_str());
405 TStreamerElement* sie0 = si0->GetStreamerElement (
"m_pCont",
offset);
406 bool isvec = (sie0 != 0);
411 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
412 if (std::abs(TClassEdit::IsSTLCont (sie0->GetTypeName(), 0)) !=
421 std::ostringstream
ss;
422 ss << dv_class->GetName() <<
": m_pCont not present, or not a vector.";
423 logfn->
debug (
ss.str().c_str());
432 Int_t nent = infos->GetEntriesFast();
433 for (Int_t
i = 0;
i < nent;
i++) {
434 if (
i == dv_vers)
continue;
435 TStreamerInfo* si1 =
dynamic_cast<TStreamerInfo*
>(infos->At (
i));
437 TStreamerElement* sie1 = si1->GetStreamerElement (
"m_pCont",
offset);
438 if (sie1 != 0 && strcmp (sie0->GetTypeName(), sie1->GetTypeName()) != 0){
440 std::ostringstream
ss;
441 ss << dv_class->GetName()
442 <<
": SI slot " <<
i <<
" has m_pCont with type "
443 << sie1->GetTypeName() <<
"; needs adjustment.";
444 logfn->
debug (
ss.str().c_str());
446 diddle_dv_streaminfo (logfn, dv_class, si1, sie0, sie1);
472 std::lock_guard<std::mutex> lock (
m);
477 TIter
next (gROOT->GetListOfClasses());
478 while (TClass*
cls =
dynamic_cast<TClass*
> (
next())) {
479 if (std::strncmp (
cls->GetName(),
"DataVector<", 11) == 0) {
480 if (
std::find (s_seen.begin(), s_seen.end(),
cls) == s_seen.end()) {
481 test_dv (logfn,
cls);
482 s_seen.push_back (
cls);