44 TClassTable *gClassTable;
46 TClassAlt **TClassTable::fgAlternate;
47 TClassRec **TClassTable::fgTable;
48 TClassRec **TClassTable::fgSortedTable;
49 UInt_t TClassTable::fgSize;
50 UInt_t TClassTable::fgTally;
51 Bool_t TClassTable::fgSorted;
52 UInt_t TClassTable::fgCursor;
53 TClassTable::IdMap_t *TClassTable::fgIdMap;
55 ClassImp(TClassTable);
62 TClassRec(TClassRec *next) :
63 fName(0), fId(0), fDict(0), fInfo(0), fProto(0), fNext(next)
77 const std::type_info *fInfo;
84 TClassAlt(
const char*alternate,
const char *normName, TClassAlt *next) :
85 fName(alternate), fNormName(normName), fNext(next)
93 const char *fNormName;
94 std::unique_ptr<TClassAlt> fNext;
97 #define R__USE_STD_MAP
98 class TMapTypeToClassRec {
99 #if defined R__USE_STD_MAP
103 typedef std::map<std::string, TClassRec*> IdMap_t;
104 typedef IdMap_t::key_type key_type;
105 typedef IdMap_t::const_iterator const_iterator;
106 typedef IdMap_t::size_type size_type;
109 typedef TClassRec* mapped_type;
111 typedef IdMap_t::mapped_type mapped_type;
118 void Add(
const key_type &key, mapped_type &obj) {
122 mapped_type Find(
const key_type &key)
const {
124 IdMap_t::const_iterator iter = fMap.find(key);
126 if (iter != fMap.end()) cl = iter->second;
130 void Remove(
const key_type &key) { fMap.erase(key); }
133 Info(
"TMapTypeToClassRec::Print",
"printing the typeinfo map in TClassTable");
134 for (const_iterator iter = fMap.begin(); iter != fMap.end(); ++iter) {
135 printf(
"Key: %40s 0x%lx\n", iter->first.c_str(), (
unsigned long)iter->second);
142 #ifdef R__COMPLETE_MEM_TERMINATION
143 ~TMapTypeToClassRec() {
146 while((key = (TObjString*)next())) {
152 void Add(
const char *key, TClassRec *&obj)
156 TObjString *realkey =
new TObjString(key);
157 fMap.Add(realkey, (TObject*)obj);
160 TClassRec *Find(
const char *key)
const {
162 const TPair *a = (
const TPair *)fMap.FindObject(key);
163 if (a)
return (TClassRec*) a->Value();
167 void Remove(
const char *key) {
169 TObjString realkey(key);
170 TObject *actual = fMap.Remove(&realkey);
176 Info(
"TMapTypeToClassRec::Print",
"printing the typeinfo map in TClassTable");
179 while((key = (TObjString*)next())) {
180 printf(
"Key: %s\n",key->String().Data());
181 TClassRec *data = (TClassRec*)fMap.GetValue(key);
183 printf(
" class: %s %d\n",data->fName,data->fId);
185 printf(
" no class: \n");
192 static UInt_t ClassTableHash(
const char *name, UInt_t size)
194 auto p =
reinterpret_cast<const unsigned char*
>( name );
197 while (*p) slot = slot<<1 ^ *p++;
203 std::vector<std::unique_ptr<TClassRec>> &GetDelayedAddClass()
205 static std::vector<std::unique_ptr<TClassRec>> delayedAddClass;
206 return delayedAddClass;
209 std::vector<std::pair<const char *, const char *>> &GetDelayedAddClassAlternate()
211 static std::vector<std::pair<const char *, const char *>> delayedAddClassAlternate;
212 return delayedAddClassAlternate;
219 TClassTable::TClassTable()
221 if (gClassTable)
return;
224 fgTable =
new TClassRec* [fgSize];
225 fgAlternate =
new TClassAlt* [fgSize];
226 fgIdMap =
new IdMap_t;
227 memset(fgTable, 0, fgSize*
sizeof(TClassRec*));
228 memset(fgAlternate, 0, fgSize*
sizeof(TClassAlt*));
231 for (
auto &&r : GetDelayedAddClass()) {
232 AddClass(r->fName, r->fId, *r->fInfo, r->fDict, r->fBits);
234 GetDelayedAddClass().clear();
236 for (
auto &&r : GetDelayedAddClassAlternate()) {
237 AddAlternate(r.first, r.second);
239 GetDelayedAddClassAlternate().clear();
245 TClassTable::~TClassTable()
248 if (gClassTable !=
this)
return;
250 for (UInt_t i = 0; i < fgSize; i++) {
253 delete [] fgTable; fgTable = 0;
254 delete [] fgSortedTable; fgSortedTable = 0;
255 delete fgIdMap; fgIdMap = 0;
263 inline Bool_t TClassTable::CheckClassTableInit() {
264 if (!gClassTable || !fgTable) {
265 if (GetDelayedAddClass().size()) {
280 void TClassTable::Print(Option_t *option)
const
282 if (fgTally == 0 || !fgTable)
287 int n = 0, ninit = 0, nl = 0;
289 int nch = strlen(option);
290 TRegexp re(option, kTRUE);
292 Printf(
"\nDefined classes");
293 Printf(
"class version bits initialized");
294 Printf(
"================================================================");
295 for (UInt_t i = 0; i < fgTally; i++) {
296 TClassRec *r = fgSortedTable[i];
299 TString s = r->fName;
300 if (nch && strcmp(option,r->fName) && s.Index(re) == kNPOS)
continue;
302 if (TClass::GetClass(r->fName, kFALSE)) {
304 Printf(
"%-35s %6d %7d Yes", r->fName, r->fId, r->fBits);
306 Printf(
"%-35s %6d %7d No", r->fName, r->fId, r->fBits);
308 Printf(
"----------------------------------------------------------------");
309 Printf(
"Listed Classes: %4d Total classes: %4d initialized: %4d",nl, n, ninit);
310 Printf(
"================================================================\n");
321 char *TClassTable::At(UInt_t index)
324 if (index < fgTally) {
325 TClassRec *r = fgSortedTable[index];
326 if (r)
return r->fName;
332 int TClassTable::Classes() {
return fgTally; }
334 void TClassTable::Init() { fgCursor = 0; SortTable(); }
336 namespace ROOT {
class TForNamespace {}; }
342 void TClassTable::Add(
const char *cname, Version_t
id,
const std::type_info &info,
343 DictFuncPtr_t dict, Int_t pragmabits)
348 if (!cname || *cname == 0)
349 ::Fatal(
"TClassTable::Add()",
"Failed to deduce type for '%s'", info.name());
352 TClassRec *r = FindElementImpl(cname, kTRUE);
353 if (r->fName && r->fInfo) {
354 if ( strcmp(r->fInfo->name(),
typeid(ROOT::TForNamespace).name())==0
355 && strcmp(info.name(),
typeid(ROOT::TForNamespace).name())==0 ) {
360 if (!TClassEdit::IsStdClass(cname)) {
362 ::Warning(
"TClassTable::Add",
"class %s already in TClassTable", cname);
365 }
else if (ROOT::Internal::gROOTLocal && gCling) {
366 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname);
378 gCling->RegisterTClassUpdate(oldcl,dict);
382 if (!r->fName) r->fName = StrDup(cname);
384 r->fBits = pragmabits;
388 fgIdMap->Add(info.name(),r);
396 void TClassTable::Add(TProtoClass *proto)
403 const char *cname = proto->GetName();
406 TClassRec *r = FindElementImpl(cname, kTRUE);
408 if (r->fProto)
delete r->fProto;
411 }
else if (ROOT::Internal::gROOTLocal && gCling) {
412 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname);
419 ::Warning(
"TClassTable::Add(TProtoClass*)",
"Called for existing class without a prior call add the dictionary function.");
423 r->fName = StrDup(cname);
435 void TClassTable::AddAlternate(
const char *normName,
const char *alternate)
440 UInt_t slot = ROOT::ClassTableHash(alternate, fgSize);
442 for (
const TClassAlt *a = fgAlternate[slot]; a; a = a->fNext.get()) {
443 if (strcmp(alternate,a->fName)==0) {
444 if (strcmp(normName,a->fNormName) != 0) {
445 fprintf(stderr,
"Error in TClassTable::AddAlternate: "
446 "Second registration of %s with a different normalized name (old: '%s', new: '%s')\n",
447 alternate, a->fNormName, normName);
453 fgAlternate[slot] =
new TClassAlt(alternate,normName,fgAlternate[slot]);
458 Bool_t TClassTable::Check(
const char *cname, std::string &normname)
460 if (!CheckClassTableInit())
return kFALSE;
462 UInt_t slot = ROOT::ClassTableHash(cname, fgSize);
465 for (TClassRec *r = fgTable[slot]; r; r = r->fNext)
466 if (strcmp(cname,r->fName)==0)
return kTRUE;
469 for (
const TClassAlt *a = fgAlternate[slot]; a; a = a->fNext.get()) {
470 if (strcmp(cname,a->fName)==0) {
471 normname = a->fNormName;
483 void TClassTable::Remove(
const char *cname)
485 if (!CheckClassTableInit())
return;
487 UInt_t slot = ROOT::ClassTableHash(cname,fgSize);
491 for (r = fgTable[slot]; r; r = r->fNext) {
492 if (!strcmp(r->fName, cname)) {
494 prev->fNext = r->fNext;
496 fgTable[slot] = r->fNext;
497 fgIdMap->Remove(r->fInfo->name());
513 TClassRec *TClassTable::FindElementImpl(
const char *cname, Bool_t insert)
515 UInt_t slot = ROOT::ClassTableHash(cname,fgSize);
517 for (TClassRec *r = fgTable[slot]; r; r = r->fNext)
518 if (strcmp(cname,r->fName)==0)
return r;
520 if (!insert)
return 0;
522 fgTable[slot] =
new TClassRec(fgTable[slot]);
525 return fgTable[slot];
535 TClassRec *TClassTable::FindElement(
const char *cname, Bool_t insert)
537 if (!CheckClassTableInit())
return nullptr;
541 std::string normalized;
542 TClassEdit::GetNormalizedName(normalized,cname);
544 return FindElementImpl(normalized.c_str(), insert);
550 Version_t TClassTable::GetID(
const char *cname)
552 TClassRec *r = FindElement(cname);
553 if (r)
return r->fId;
560 Int_t TClassTable::GetPragmaBits(
const char *cname)
562 TClassRec *r = FindElement(cname);
563 if (r)
return r->fBits;
571 DictFuncPtr_t TClassTable::GetDict(
const char *cname)
574 ::Info(
"GetDict",
"searches for %s", cname);
578 TClassRec *r = FindElement(cname);
579 if (r)
return r->fDict;
587 DictFuncPtr_t TClassTable::GetDict(
const std::type_info& info)
589 if (!CheckClassTableInit())
return nullptr;
592 ::Info(
"GetDict",
"searches for %s at 0x%lx", info.name(), (Long_t)&info);
596 TClassRec *r = fgIdMap->Find(info.name());
597 if (r)
return r->fDict;
605 DictFuncPtr_t TClassTable::GetDictNorm(
const char *cname)
607 if (!CheckClassTableInit())
return nullptr;
610 ::Info(
"GetDict",
"searches for %s", cname);
614 TClassRec *r = FindElementImpl(cname,kFALSE);
615 if (r)
return r->fDict;
623 TProtoClass *TClassTable::GetProto(
const char *cname)
626 ::Info(
"GetDict",
"searches for %s", cname);
629 if (!CheckClassTableInit())
return nullptr;
632 ::Info(
"GetDict",
"searches for %s", cname);
636 TClassRec *r = FindElement(cname);
637 if (r)
return r->fProto;
645 TProtoClass *TClassTable::GetProtoNorm(
const char *cname)
648 ::Info(
"GetDict",
"searches for %s", cname);
651 if (!CheckClassTableInit())
return nullptr;
657 TClassRec *r = FindElementImpl(cname,kFALSE);
658 if (r)
return r->fProto;
665 static int ClassComp(
const void *a,
const void *b)
669 return strcmp((*(TClassRec **)a)->fName, (*(TClassRec **)b)->fName);
678 char *TClassTable::Next()
680 if (fgCursor < fgTally) {
681 TClassRec *r = fgSortedTable[fgCursor++];
691 void TClassTable::PrintTable()
693 if (fgTally == 0 || !fgTable)
698 int n = 0, ninit = 0;
700 Printf(
"\nDefined classes");
701 Printf(
"class version bits initialized");
702 Printf(
"================================================================");
703 UInt_t last = fgTally;
704 for (UInt_t i = 0; i < last; i++) {
705 TClassRec *r = fgSortedTable[i];
709 if (gROOT->GetListOfClasses()->FindObject(r->fName)) {
711 Printf(
"%-35s %6d %7d Yes", r->fName, r->fId, r->fBits);
713 Printf(
"%-35s %6d %7d No", r->fName, r->fId, r->fBits);
715 Printf(
"----------------------------------------------------------------");
716 Printf(
"Total classes: %4d initialized: %4d", n, ninit);
717 Printf(
"================================================================\n");
723 void TClassTable::SortTable()
726 delete [] fgSortedTable;
727 fgSortedTable =
new TClassRec* [fgTally];
730 for (UInt_t i = 0; i < fgSize; i++)
731 for (TClassRec *r = fgTable[i]; r; r = r->fNext)
732 fgSortedTable[j++] = r;
734 ::qsort(fgSortedTable, fgTally,
sizeof(TClassRec *), ::ClassComp);
742 void TClassTable::Terminate()
745 for (UInt_t i = 0; i < fgSize; i++)
748 delete [] fgTable; fgTable = 0;
749 delete [] fgSortedTable; fgSortedTable = 0;
750 delete fgIdMap; fgIdMap = 0;
752 SafeDelete(gClassTable);
760 void ROOT::AddClass(
const char *cname, Version_t
id,
761 const std::type_info& info,
765 if (!TROOT::Initialized() && !gClassTable) {
766 auto r = std::unique_ptr<TClassRec>(
new TClassRec(
nullptr));
767 r->fName = StrDup(cname);
769 r->fBits = pragmabits;
772 GetDelayedAddClass().emplace_back(std::move(r));
774 TClassTable::Add(cname,
id, info, dict, pragmabits);
782 void ROOT::AddClassAlternate(
const char *normName,
const char *alternate)
784 if (!TROOT::Initialized() && !gClassTable) {
785 GetDelayedAddClassAlternate().emplace_back(normName, alternate);
787 TClassTable::AddAlternate(normName, alternate);
805 void ROOT::ResetClassVersion(TClass *cl,
const char *cname, Short_t newid)
807 if (cname && cname!=(
void*)-1) {
808 TClassRec *r = TClassTable::FindElement(cname,kFALSE);
809 if (r) r->fId = newid;
812 if (cl->fVersionUsed) {
814 if (cname!=(
void*)-1)
815 Error(
"ResetClassVersion",
"Version number of %s can not be changed after first usage!",
819 Error(
"SetClassVersion",
"The class version (for %s) must be positive (value %d is ignored)",cl->GetName(),newid);
821 if (cname==(
void*)-1) {
822 if (cl->fClassVersion<newid && 2<=newid) {
823 cl->SetClassVersion(newid);
826 cl->SetClassVersion(newid);
837 void ROOT::RemoveClass(
const char *cname)
847 if (gROOT && gROOT->GetListOfClasses()) {
849 if ((pcname=gROOT->GetListOfClasses()->FindObject(cname))) {
850 TClass *cl =
dynamic_cast<TClass*
>(pcname);
851 if (cl) cl->SetUnloaded();
854 TClassTable::Remove(cname);
862 TNamed *ROOT::RegisterClassTemplate(
const char *name,
const char *file,
866 static Bool_t isInit = kFALSE;
868 table.SetOwner(kTRUE);
872 TString classname(name);
873 Ssiz_t loc = classname.Index(
"<");
874 if (loc >= 1) classname.Remove(loc);
876 TNamed *obj =
new TNamed((
const char*)classname, file);
877 obj->SetUniqueID(line);
881 return (TNamed*)table.FindObject(classname);