Logo ROOT  
Reference Guide
TClassTable.cxx
Go to the documentation of this file.
1// @(#)root/cont:$Id$
2// Author: Fons Rademakers 11/08/95
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TClassTable
13\ingroup Containers
14This class registers for all classes their name, id and dictionary
15function in a hash table. Classes are automatically added by the
16ctor of a special init class when a global of this init class is
17initialized when the program starts (see the ClassImp macro).
18*/
19
20#include "TClassTable.h"
21
22#include "TClass.h"
23#include "TClassEdit.h"
24#include "TProtoClass.h"
25#include "TROOT.h"
26#include "TString.h"
27#include "TError.h"
28#include "TRegexp.h"
29
30#include "TObjString.h"
31#include "TMap.h"
32
33#include "TInterpreter.h"
34
35#include <map>
36#include <memory>
37#include "Riostream.h"
38#include <typeinfo>
39#include <stdlib.h>
40#include <string>
41
42using namespace ROOT;
43
45
46TClassAlt **TClassTable::fgAlternate;
47TClassRec **TClassTable::fgTable;
54
56
57////////////////////////////////////////////////////////////////////////////////
58
59namespace ROOT {
60 class TClassRec {
61 public:
62 TClassRec(TClassRec *next) :
63 fName(0), fId(0), fDict(0), fInfo(0), fProto(0), fNext(next)
64 {}
65
66 ~TClassRec() {
67 // TClassTable::fgIdMap->Remove(r->fInfo->name());
68 delete [] fName;
69 delete fProto;
70 delete fNext;
71 }
72
73 char *fName;
74 Version_t fId;
75 Int_t fBits;
76 DictFuncPtr_t fDict;
77 const std::type_info *fInfo;
78 TProtoClass *fProto;
79 TClassRec *fNext;
80 };
81
82 class TClassAlt {
83 public:
84 TClassAlt(const char*alternate, const char *normName, TClassAlt *next) :
85 fName(alternate), fNormName(normName), fNext(next)
86 {}
87
88 ~TClassAlt() {
89 // Nothing more to delete.
90 }
91
92 const char *fName; // Do not own
93 const char *fNormName; // Do not own
94 std::unique_ptr<TClassAlt> fNext;
95 };
96
97#define R__USE_STD_MAP
98 class TMapTypeToClassRec {
99#if defined R__USE_STD_MAP
100 // This wrapper class allow to avoid putting #include <map> in the
101 // TROOT.h header file.
102 public:
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;
107#ifdef R__WIN32
108 // Window's std::map does NOT defined mapped_type
109 typedef TClassRec* mapped_type;
110#else
111 typedef IdMap_t::mapped_type mapped_type;
112#endif
113
114 private:
115 IdMap_t fMap;
116
117 public:
118 void Add(const key_type &key, mapped_type &obj) {
119 fMap[key] = obj;
120 }
121
122 mapped_type Find(const key_type &key) const {
123
124 IdMap_t::const_iterator iter = fMap.find(key);
125 mapped_type cl = 0;
126 if (iter != fMap.end()) cl = iter->second;
127 return cl;
128 }
129
130 void Remove(const key_type &key) { fMap.erase(key); }
131
132 void Print() {
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);
136 }
137 }
138#else
139 private:
140 TMap fMap;
141 public:
142#ifdef R__COMPLETE_MEM_TERMINATION
143 ~TMapTypeToClassRec() {
144 TIter next(&fMap);
145 TObjString *key;
146 while((key = (TObjString*)next())) {
147 delete key;
148 }
149 }
150#endif
151
152 void Add(const char *key, TClassRec *&obj)
153 {
154 // Add <key,value> pair to the map.
155
156 TObjString *realkey = new TObjString(key);
157 fMap.Add(realkey, (TObject*)obj);
158 }
159
160 TClassRec *Find(const char *key) const {
161 // Find the value corresponding the key.
162 const TPair *a = (const TPair *)fMap.FindObject(key);
163 if (a) return (TClassRec*) a->Value();
164 return 0;
165 }
166
167 void Remove(const char *key) {
168 // Remove the value corresponding the key.
169 TObjString realkey(key);
170 TObject *actual = fMap.Remove(&realkey);
171 delete actual;
172 }
173
174 void Print() {
175 // Print the content of the map.
176 Info("TMapTypeToClassRec::Print", "printing the typeinfo map in TClassTable");
177 TIter next(&fMap);
178 TObjString *key;
179 while((key = (TObjString*)next())) {
180 printf("Key: %s\n",key->String().Data());
181 TClassRec *data = (TClassRec*)fMap.GetValue(key);
182 if (data) {
183 printf(" class: %s %d\n",data->fName,data->fId);
184 } else {
185 printf(" no class: \n");
186 }
187 }
188 }
189#endif
190 };
191
192 static UInt_t ClassTableHash(const char *name, UInt_t size)
193 {
194 auto p = reinterpret_cast<const unsigned char*>( name );
195 UInt_t slot = 0;
196
197 while (*p) slot = slot<<1 ^ *p++;
198 slot %= size;
199
200 return slot;
201 }
202
203 std::vector<std::unique_ptr<TClassRec>> &GetDelayedAddClass()
204 {
205 static std::vector<std::unique_ptr<TClassRec>> delayedAddClass;
206 return delayedAddClass;
207 }
208
209 std::vector<std::pair<const char *, const char *>> &GetDelayedAddClassAlternate()
210 {
211 static std::vector<std::pair<const char *, const char *>> delayedAddClassAlternate;
212 return delayedAddClassAlternate;
213 }
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// TClassTable is a singleton (i.e. only one can exist per application).
218
220{
221 if (gClassTable) return;
222
223 fgSize = 1009; //this is the result of (int)TMath::NextPrime(1000);
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*));
229 gClassTable = this;
230
231 for (auto &&r : GetDelayedAddClass()) {
232 AddClass(r->fName, r->fId, *r->fInfo, r->fDict, r->fBits);
233 };
234 GetDelayedAddClass().clear();
235
236 for (auto &&r : GetDelayedAddClassAlternate()) {
237 AddAlternate(r.first, r.second);
238 }
240}
241
242////////////////////////////////////////////////////////////////////////////////
243/// TClassTable singleton is deleted in Terminate().
244
246{
247 // Try to avoid spurious warning from memory leak checkers.
248 if (gClassTable != this) return;
249
250 for (UInt_t i = 0; i < fgSize; i++) {
251 delete fgTable[i]; // Will delete all the elements in the chain.
252 }
253 delete [] fgTable; fgTable = 0;
254 delete [] fgSortedTable; fgSortedTable = 0;
255 delete fgIdMap; fgIdMap = 0;
256}
257
258////////////////////////////////////////////////////////////////////////////////
259/// Return true fs the table exist.
260/// If the table does not exist but the delayed list does, then
261/// create the table and return true.
262
264 if (!gClassTable || !fgTable) {
265 if (GetDelayedAddClass().size()) {
266 new TClassTable;
267 return kTRUE;
268 }
269 return kFALSE;
270 }
271 return kTRUE;
272}
273
274////////////////////////////////////////////////////////////////////////////////
275/// Print the class table. Before printing the table is sorted
276/// alphabetically. Only classes specified in option are listed.
277/// The default is to list all classes.
278/// Standard wildcarding notation supported.
279
280void TClassTable::Print(Option_t *option) const
281{
282 if (fgTally == 0 || !fgTable)
283 return;
284
285 SortTable();
286
287 int n = 0, ninit = 0, nl = 0;
288
289 int nch = strlen(option);
290 TRegexp re(option, kTRUE);
291
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];
297 if (!r) break;
298 n++;
299 TString s = r->fName;
300 if (nch && strcmp(option,r->fName) && s.Index(re) == kNPOS) continue;
301 nl++;
302 if (TClass::GetClass(r->fName, kFALSE)) {
303 ninit++;
304 Printf("%-35s %6d %7d Yes", r->fName, r->fId, r->fBits);
305 } else
306 Printf("%-35s %6d %7d No", r->fName, r->fId, r->fBits);
307 }
308 Printf("----------------------------------------------------------------");
309 Printf("Listed Classes: %4d Total classes: %4d initialized: %4d",nl, n, ninit);
310 Printf("================================================================\n");
311}
312
313//---- static members --------------------------------------------------------
314
315////////////////////////////////////////////////////////////////////////////////
316/// Returns class at index from sorted class table. Don't use this iterator
317/// while modifying the class table. The class table can be modified
318/// when making calls like TClass::GetClass(), etc.
319/// Returns 0 if index points beyond last class name.
320
322{
323 SortTable();
324 if (index < fgTally) {
325 TClassRec *r = fgSortedTable[index];
326 if (r) return r->fName;
327 }
328 return 0;
329}
330
331//______________________________________________________________________________
333//______________________________________________________________________________
335
336namespace ROOT { class TForNamespace {}; } // Dummy class to give a typeid to namespace (see also TGenericClassInfo)
337
338////////////////////////////////////////////////////////////////////////////////
339/// Add a class to the class table (this is a static function).
340/// Note that the given cname *must* be already normalized.
341
342void TClassTable::Add(const char *cname, Version_t id, const std::type_info &info,
343 DictFuncPtr_t dict, Int_t pragmabits)
344{
345 if (!gClassTable)
346 new TClassTable;
347
348 if (!cname || *cname == 0)
349 ::Fatal("TClassTable::Add()", "Failed to deduce type for '%s'", info.name());
350
351 // check if already in table, if so return
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 ) {
356 // We have a namespace being reloaded.
357 // This okay we just keep the old one.
358 return;
359 }
360 if (!TClassEdit::IsStdClass(cname)) {
361 // Warn only for class that are not STD classes
362 ::Warning("TClassTable::Add", "class %s already in TClassTable", cname);
363 }
364 return;
365 } else if (ROOT::Internal::gROOTLocal && gCling) {
366 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname);
367 if (oldcl) { // && oldcl->GetClassInfo()) {
368 // As a work-around to ROOT-6012, we need to register the class even if
369 // it is not a template instance, because a forward declaration in the header
370 // files loaded by the current dictionary wil also de-activate the update
371 // class info mechanism!
372
373 // The TClass exist and already has a class info, so it must
374 // correspond to a class template instantiation which the interpreter
375 // was able to make with the library containing the TClass Init.
376 // Because it is already known to the interpreter, the update class info
377 // will not be triggered, we need to force it.
378 gCling->RegisterTClassUpdate(oldcl,dict);
379 }
380 }
381
382 if (!r->fName) r->fName = StrDup(cname);
383 r->fId = id;
384 r->fBits = pragmabits;
385 r->fDict = dict;
386 r->fInfo = &info;
387
388 fgIdMap->Add(info.name(),r);
389
391}
392
393////////////////////////////////////////////////////////////////////////////////
394/// Add a class to the class table (this is a static function).
395
397{
398 if (!gClassTable)
399 new TClassTable;
400
401 // By definition the name in the TProtoClass is (must be) the normalized
402 // name, so there is no need to tweak it.
403 const char *cname = proto->GetName();
404
405 // check if already in table, if so return
406 TClassRec *r = FindElementImpl(cname, kTRUE);
407 if (r->fName) {
408 if (r->fProto) delete r->fProto;
409 r->fProto = proto;
410 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname);
411 if (oldcl && oldcl->GetState() == TClass::kHasTClassInit)
412 proto->FillTClass(oldcl);
413 return;
414 } else if (ROOT::Internal::gROOTLocal && gCling) {
415 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname);
416 if (oldcl) { // && oldcl->GetClassInfo()) {
417 // As a work-around to ROOT-6012, we need to register the class even if
418 // it is not a template instance, because a forward declaration in the header
419 // files loaded by the current dictionary wil also de-activate the update
420 // class info mechanism!
421
422 ::Warning("TClassTable::Add(TProtoClass*)","Called for existing class without a prior call add the dictionary function.");
423 }
424 }
425
426 r->fName = StrDup(cname);
427 r->fId = 0;
428 r->fBits = 0;
429 r->fDict = 0;
430 r->fInfo = 0;
431 r->fProto= proto;
432
434}
435
436////////////////////////////////////////////////////////////////////////////////
437
438void TClassTable::AddAlternate(const char *normName, const char *alternate)
439{
440 if (!gClassTable)
441 new TClassTable;
442
443 UInt_t slot = ROOT::ClassTableHash(alternate, fgSize);
444
445 for (const TClassAlt *a = fgAlternate[slot]; a; a = a->fNext.get()) {
446 if (strcmp(alternate,a->fName)==0) {
447 if (strcmp(normName,a->fNormName) != 0) {
448 fprintf(stderr,"Error in TClassTable::AddAlternate: "
449 "Second registration of %s with a different normalized name (old: '%s', new: '%s')\n",
450 alternate, a->fNormName, normName);
451 return;
452 }
453 }
454 }
455
456 fgAlternate[slot] = new TClassAlt(alternate,normName,fgAlternate[slot]);
457}
458
459////////////////////////////////////////////////////////////////////////////////
460
461Bool_t TClassTable::Check(const char *cname, std::string &normname)
462{
463 if (!CheckClassTableInit()) return kFALSE;
464
465 UInt_t slot = ROOT::ClassTableHash(cname, fgSize);
466
467 // Check if 'cname' is a known normalized name.
468 for (TClassRec *r = fgTable[slot]; r; r = r->fNext)
469 if (strcmp(cname,r->fName)==0) return kTRUE;
470
471 // See if 'cname' is register in the list of alternate names
472 for (const TClassAlt *a = fgAlternate[slot]; a; a = a->fNext.get()) {
473 if (strcmp(cname,a->fName)==0) {
474 normname = a->fNormName;
475 return kTRUE;
476 }
477 }
478
479 return kFALSE;
480}
481
482////////////////////////////////////////////////////////////////////////////////
483/// Remove a class from the class table. This happens when a shared library
484/// is unloaded (i.e. the dtor's of the global init objects are called).
485
486void TClassTable::Remove(const char *cname)
487{
488 if (!CheckClassTableInit()) return;
489
490 UInt_t slot = ROOT::ClassTableHash(cname,fgSize);
491
492 TClassRec *r;
493 TClassRec *prev = 0;
494 for (r = fgTable[slot]; r; r = r->fNext) {
495 if (!strcmp(r->fName, cname)) {
496 if (prev)
497 prev->fNext = r->fNext;
498 else
499 fgTable[slot] = r->fNext;
500 fgIdMap->Remove(r->fInfo->name());
501 r->fNext = 0; // Do not delete the others.
502 delete r;
503 fgTally--;
505 break;
506 }
507 prev = r;
508 }
509}
510
511////////////////////////////////////////////////////////////////////////////////
512/// Find a class by name in the class table (using hash of name). Returns
513/// 0 if the class is not in the table. Unless arguments insert is true in
514/// which case a new entry is created and returned.
515
516TClassRec *TClassTable::FindElementImpl(const char *cname, Bool_t insert)
517{
518 UInt_t slot = ROOT::ClassTableHash(cname,fgSize);
519
520 for (TClassRec *r = fgTable[slot]; r; r = r->fNext)
521 if (strcmp(cname,r->fName)==0) return r;
522
523 if (!insert) return 0;
524
525 fgTable[slot] = new TClassRec(fgTable[slot]);
526
527 fgTally++;
528 return fgTable[slot];
529}
530
531////////////////////////////////////////////////////////////////////////////////
532/// Find a class by name in the class table (using hash of name). Returns
533/// 0 if the class is not in the table. Unless arguments insert is true in
534/// which case a new entry is created and returned.
535/// cname can be any spelling of the class name. See FindElementImpl if the
536/// name is already normalized.
537
538TClassRec *TClassTable::FindElement(const char *cname, Bool_t insert)
539{
540 if (!CheckClassTableInit()) return nullptr;
541
542 // The recorded name is normalized, let's make sure we convert the
543 // input accordingly.
544 std::string normalized;
545 TClassEdit::GetNormalizedName(normalized,cname);
546
547 return FindElementImpl(normalized.c_str(), insert);
548}
549
550////////////////////////////////////////////////////////////////////////////////
551/// Returns the ID of a class.
552
554{
555 TClassRec *r = FindElement(cname);
556 if (r) return r->fId;
557 return -1;
558}
559
560////////////////////////////////////////////////////////////////////////////////
561/// Returns the pragma bits as specified in the LinkDef.h file.
562
564{
565 TClassRec *r = FindElement(cname);
566 if (r) return r->fBits;
567 return 0;
568}
569
570////////////////////////////////////////////////////////////////////////////////
571/// Given the class name returns the Dictionary() function of a class
572/// (uses hash of name).
573
575{
576 if (gDebug > 9) {
577 ::Info("GetDict", "searches for %s", cname);
578 fgIdMap->Print();
579 }
580
581 TClassRec *r = FindElement(cname);
582 if (r) return r->fDict;
583 return 0;
584}
585
586////////////////////////////////////////////////////////////////////////////////
587/// Given the std::type_info returns the Dictionary() function of a class
588/// (uses hash of std::type_info::name()).
589
590DictFuncPtr_t TClassTable::GetDict(const std::type_info& info)
591{
592 if (!CheckClassTableInit()) return nullptr;
593
594 if (gDebug > 9) {
595 ::Info("GetDict", "searches for %s at 0x%lx", info.name(), (Long_t)&info);
596 fgIdMap->Print();
597 }
598
599 TClassRec *r = fgIdMap->Find(info.name());
600 if (r) return r->fDict;
601 return 0;
602}
603
604////////////////////////////////////////////////////////////////////////////////
605/// Given the normalized class name returns the Dictionary() function of a class
606/// (uses hash of name).
607
609{
610 if (!CheckClassTableInit()) return nullptr;
611
612 if (gDebug > 9) {
613 ::Info("GetDict", "searches for %s", cname);
614 fgIdMap->Print();
615 }
616
617 TClassRec *r = FindElementImpl(cname,kFALSE);
618 if (r) return r->fDict;
619 return 0;
620}
621
622////////////////////////////////////////////////////////////////////////////////
623/// Given the class name returns the TClassProto object for the class.
624/// (uses hash of name).
625
627{
628 if (gDebug > 9) {
629 ::Info("GetDict", "searches for %s", cname);
630 }
631
632 if (!CheckClassTableInit()) return nullptr;
633
634 if (gDebug > 9) {
635 ::Info("GetDict", "searches for %s", cname);
636 fgIdMap->Print();
637 }
638
639 TClassRec *r = FindElement(cname);
640 if (r) return r->fProto;
641 return 0;
642}
643
644////////////////////////////////////////////////////////////////////////////////
645/// Given the class normalized name returns the TClassProto object for the class.
646/// (uses hash of name).
647
649{
650 if (gDebug > 9) {
651 ::Info("GetDict", "searches for %s", cname);
652 }
653
654 if (!CheckClassTableInit()) return nullptr;
655
656 if (gDebug > 9) {
657 fgIdMap->Print();
658 }
659
660 TClassRec *r = FindElementImpl(cname,kFALSE);
661 if (r) return r->fProto;
662 return 0;
663}
664
665////////////////////////////////////////////////////////////////////////////////
666
667extern "C" {
668 static int ClassComp(const void *a, const void *b)
669 {
670 // Function used for sorting classes alphabetically.
671
672 return strcmp((*(TClassRec **)a)->fName, (*(TClassRec **)b)->fName);
673 }
674}
675
676////////////////////////////////////////////////////////////////////////////////
677/// Returns next class from sorted class table. Don't use this iterator
678/// while modifying the class table. The class table can be modified
679/// when making calls like TClass::GetClass(), etc.
680
682{
683 if (fgCursor < fgTally) {
684 TClassRec *r = fgSortedTable[fgCursor++];
685 return r->fName;
686 } else
687 return 0;
688}
689
690////////////////////////////////////////////////////////////////////////////////
691/// Print the class table. Before printing the table is sorted
692/// alphabetically.
693
695{
696 if (fgTally == 0 || !fgTable)
697 return;
698
699 SortTable();
700
701 int n = 0, ninit = 0;
702
703 Printf("\nDefined classes");
704 Printf("class version bits initialized");
705 Printf("================================================================");
706 UInt_t last = fgTally;
707 for (UInt_t i = 0; i < last; i++) {
708 TClassRec *r = fgSortedTable[i];
709 if (!r) break;
710 n++;
711 // Do not use TClass::GetClass to avoid any risk of autoloading.
712 if (gROOT->GetListOfClasses()->FindObject(r->fName)) {
713 ninit++;
714 Printf("%-35s %6d %7d Yes", r->fName, r->fId, r->fBits);
715 } else
716 Printf("%-35s %6d %7d No", r->fName, r->fId, r->fBits);
717 }
718 Printf("----------------------------------------------------------------");
719 Printf("Total classes: %4d initialized: %4d", n, ninit);
720 Printf("================================================================\n");
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// Sort the class table by ascending class ID's.
725
727{
728 if (!fgSorted) {
729 delete [] fgSortedTable;
730 fgSortedTable = new TClassRec* [fgTally];
731
732 int j = 0;
733 for (UInt_t i = 0; i < fgSize; i++)
734 for (TClassRec *r = fgTable[i]; r; r = r->fNext)
735 fgSortedTable[j++] = r;
736
737 ::qsort(fgSortedTable, fgTally, sizeof(TClassRec *), ::ClassComp);
738 fgSorted = kTRUE;
739 }
740}
741
742////////////////////////////////////////////////////////////////////////////////
743/// Deletes the class table (this static class function calls the dtor).
744
746{
747 if (gClassTable) {
748 for (UInt_t i = 0; i < fgSize; i++)
749 delete fgTable[i]; // Will delete all the elements in the chain.
750
751 delete [] fgTable; fgTable = 0;
752 delete [] fgSortedTable; fgSortedTable = 0;
753 delete fgIdMap; fgIdMap = 0;
754 fgSize = 0;
756 }
757}
758
759////////////////////////////////////////////////////////////////////////////////
760/// Global function called by the ctor of a class's init class
761/// (see the ClassImp macro).
762
763void ROOT::AddClass(const char *cname, Version_t id,
764 const std::type_info& info,
765 DictFuncPtr_t dict,
766 Int_t pragmabits)
767{
768 if (!TROOT::Initialized() && !gClassTable) {
769 auto r = std::unique_ptr<TClassRec>(new TClassRec(nullptr));
770 r->fName = StrDup(cname);
771 r->fId = id;
772 r->fBits = pragmabits;
773 r->fDict = dict;
774 r->fInfo = &info;
775 GetDelayedAddClass().emplace_back(std::move(r));
776 } else {
777 TClassTable::Add(cname, id, info, dict, pragmabits);
778 }
779}
780
781////////////////////////////////////////////////////////////////////////////////
782/// Global function called by GenerateInitInstance.
783/// (see the ClassImp macro).
784
785void ROOT::AddClassAlternate(const char *normName, const char *alternate)
786{
787 if (!TROOT::Initialized() && !gClassTable) {
788 GetDelayedAddClassAlternate().emplace_back(normName, alternate);
789 } else {
790 TClassTable::AddAlternate(normName, alternate);
791 }
792}
793
794////////////////////////////////////////////////////////////////////////////////
795/// Global function to update the version number.
796/// This is called via the RootClassVersion macro.
797///
798/// if cl!=0 and cname==-1, set the new class version if and only is
799/// greater than the existing one and greater or equal to 2;
800/// and also ignore the request if fVersionUsed is true.
801///
802/// Note on class version number:
803/// - If no class has been specified, TClass::GetVersion will return -1
804/// - The Class Version 0 request the whole object to be transient
805/// - The Class Version 1, unless specify via ClassDef indicates that the
806/// I/O should use the TClass checksum to distinguish the layout of the class
807
808void ROOT::ResetClassVersion(TClass *cl, const char *cname, Short_t newid)
809{
810 if (cname && cname!=(void*)-1) {
811 TClassRec *r = TClassTable::FindElement(cname,kFALSE);
812 if (r) r->fId = newid;
813 }
814 if (cl) {
815 if (cl->fVersionUsed) {
816 // Problem, the reset is called after the first usage!
817 if (cname!=(void*)-1)
818 Error("ResetClassVersion","Version number of %s can not be changed after first usage!",
819 cl->GetName());
820 } else {
821 if (newid < 0) {
822 Error("SetClassVersion","The class version (for %s) must be positive (value %d is ignored)",cl->GetName(),newid);
823 }
824 if (cname==(void*)-1) {
825 if (cl->fClassVersion<newid && 2<=newid) {
826 cl->SetClassVersion(newid);
827 }
828 } else {
829 cl->SetClassVersion(newid);
830 }
831 }
832 }
833}
834
835
836////////////////////////////////////////////////////////////////////////////////
837/// Global function called by the dtor of a class's init class
838/// (see the ClassImp macro).
839
840void ROOT::RemoveClass(const char *cname)
841{
842 // don't delete class information since it is needed by the I/O system
843 // to write the StreamerInfo to file
844 if (cname) {
845 // Let's still remove this information to allow reloading later.
846 // Anyway since the shared library has been unloaded, the dictionary
847 // pointer is now invalid ....
848 // We still keep the TClass object around because TFile needs to
849 // get to the TStreamerInfo.
850 if (gROOT && gROOT->GetListOfClasses()) {
851 TObject *pcname;
852 if ((pcname=gROOT->GetListOfClasses()->FindObject(cname))) {
853 TClass *cl = dynamic_cast<TClass*>(pcname);
854 if (cl) cl->SetUnloaded();
855 }
856 }
857 TClassTable::Remove(cname);
858 }
859}
860
861////////////////////////////////////////////////////////////////////////////////
862/// Global function to register the implementation file and line of
863/// a class template (i.e. NOT a concrete class).
864
865TNamed *ROOT::RegisterClassTemplate(const char *name, const char *file,
866 Int_t line)
867{
868 static TList table;
869 static Bool_t isInit = kFALSE;
870 if (!isInit) {
871 table.SetOwner(kTRUE);
872 isInit = kTRUE;
873 }
874
875 TString classname(name);
876 Ssiz_t loc = classname.Index("<");
877 if (loc >= 1) classname.Remove(loc);
878 if (file) {
879 TNamed *obj = new TNamed((const char*)classname, file);
880 obj->SetUniqueID(line);
881 table.Add(obj);
882 return obj;
883 } else {
884 return (TNamed*)table.FindObject(classname);
885 }
886}
ROOT::R::TRInterface & r
Definition: Object.C:4
#define SafeDelete(p)
Definition: RConfig.hxx:543
#define b(i)
Definition: RSha256.hxx:100
const Ssiz_t kNPOS
Definition: RtypesCore.h:113
int Int_t
Definition: RtypesCore.h:43
short Version_t
Definition: RtypesCore.h:63
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
long Long_t
Definition: RtypesCore.h:52
bool Bool_t
Definition: RtypesCore.h:61
short Short_t
Definition: RtypesCore.h:37
R__EXTERN Int_t gDebug
Definition: RtypesCore.h:117
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
TClass *(* DictFuncPtr_t)()
Definition: Rtypes.h:78
#define ClassImp(name)
Definition: Rtypes.h:361
TClassTable * gClassTable
Definition: TClassTable.cxx:44
static int ClassComp(const void *a, const void *b)
ROOT::TMapTypeToTClass IdMap_t
Definition: TClass.h:77
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
XFontStruct * id
Definition: TGX11.cxx:108
char name[80]
Definition: TGX11.cxx:109
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:557
#define gROOT
Definition: TROOT.h:406
void Printf(const char *fmt,...)
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2490
const char * proto
Definition: civetweb.c:16604
This class registers for all classes their name, id and dictionary function in a hash table.
Definition: TClassTable.h:35
static void PrintTable()
Print the class table.
static Int_t GetPragmaBits(const char *name)
Returns the pragma bits as specified in the LinkDef.h file.
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static Version_t GetID(const char *cname)
Returns the ID of a class.
ROOT::TMapTypeToClassRec IdMap_t
Definition: TClassTable.h:41
static void SortTable()
Sort the class table by ascending class ID's.
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static void AddAlternate(const char *normname, const char *alternate)
static ROOT::TClassAlt ** fgAlternate
Definition: TClassTable.h:43
static ROOT::TClassRec * FindElementImpl(const char *cname, Bool_t insert)
Find a class by name in the class table (using hash of name).
static void Terminate()
Deletes the class table (this static class function calls the dtor).
void Print(Option_t *option="") const
Print the class table.
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
TClassTable()
TClassTable is a singleton (i.e. only one can exist per application).
static char * Next()
Returns next class from sorted class table.
static char * At(UInt_t index)
Returns class at index from sorted class table.
static Bool_t Check(const char *cname, std::string &normname)
static void Init()
static void Remove(const char *cname)
Remove a class from the class table.
static ROOT::TClassRec ** fgSortedTable
Definition: TClassTable.h:45
static ROOT::TClassRec ** fgTable
Definition: TClassTable.h:44
static IdMap_t * fgIdMap
Definition: TClassTable.h:46
static Bool_t CheckClassTableInit()
Return true fs the table exist.
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
~TClassTable()
TClassTable singleton is deleted in Terminate().
static Bool_t fgSorted
Definition: TClassTable.h:49
static UInt_t fgTally
Definition: TClassTable.h:48
static UInt_t fgSize
Definition: TClassTable.h:47
static ROOT::TClassRec * FindElement(const char *cname, Bool_t insert=kFALSE)
Find a class by name in the class table (using hash of name).
static UInt_t fgCursor
Definition: TClassTable.h:50
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
EState GetState() const
Definition: TClass.h:485
Version_t fClassVersion
Definition: TClass.h:221
void SetUnloaded()
Call this method to indicate that the shared library containing this class's code has been removed (u...
Definition: TClass.cxx:6233
void SetClassVersion(Version_t version)
Private function.
Definition: TClass.cxx:5638
std::atomic< Bool_t > fVersionUsed
saved remember if fOffsetStreamer has been set.
Definition: TClass.h:259
@ kHasTClassInit
Definition: TClass.h:127
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2948
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void RegisterTClassUpdate(TClass *oldcl, DictFuncPtr_t dict)=0
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:40
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Collectable string class.
Definition: TObjString.h:28
TString & String()
Definition: TObjString.h:48
Mother of all ROOT objects.
Definition: TObject.h:37
UInt_t fBits
bit field status word
Definition: TObject.h:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:877
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:919
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:705
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:865
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:102
Persistent version of a TClass.
Definition: TProtoClass.h:35
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2796
Regular expression class.
Definition: TRegexp.h:31
Basic string class.
Definition: TString.h:131
const char * Data() const
Definition: TString.h:364
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
TLine * line
const Int_t n
Definition: legend1.C:16
void Add(RHist< DIMENSIONS, PRECISION, STAT_TO... > &to, const RHist< DIMENSIONS, PRECISION, STAT_FROM... > &from)
Add two histograms.
Definition: RHist.hxx:323
R__EXTERN TROOT * gROOTLocal
Definition: TROOT.h:379
void Print(std::ostream &os, const OptionType &opt)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: StringConv.hxx:21
std::vector< std::pair< const char *, const char * > > & GetDelayedAddClassAlternate()
std::vector< std::unique_ptr< TClassRec > > & GetDelayedAddClass()
void AddClassAlternate(const char *normName, const char *alternate)
Global function called by GenerateInitInstance.
void RemoveClass(const char *cname)
Global function called by the dtor of a class's init class (see the ClassImp macro).
void AddClass(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Global function called by the ctor of a class's init class (see the ClassImp macro).
TNamed * RegisterClassTemplate(const char *name, const char *file, Int_t line)
Global function to register the implementation file and line of a class template (i....
static UInt_t ClassTableHash(const char *name, UInt_t size)
void ResetClassVersion(TClass *, const char *, Short_t)
Global function to update the version number.
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.
Definition: TClassEdit.cxx:833
static constexpr double s
UInt_t Find(std::list< std::pair< const Node< T > *, Float_t > > &nlist, const Node< T > *node, const T &event, UInt_t nfind)
Definition: file.py:1
auto * a
Definition: textangle.C:12