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 "TList.h"
26#include "TROOT.h"
27#include "TString.h"
28#include "TError.h"
29#include "TRegexp.h"
30
31#include "TObjString.h"
32#include "TMap.h"
33
34#include "TInterpreter.h"
35
36#include <map>
37#include <memory>
38#include <typeinfo>
39#include <cstdlib>
40#include <string>
41
42using namespace ROOT;
43
45
54
56
57////////////////////////////////////////////////////////////////////////////////
58
59namespace ROOT {
60 class TClassRec {
61 public:
63 fName(nullptr), fId(0), fDict(nullptr), fInfo(nullptr), fProto(nullptr), fNext(next)
64 {}
65
67 // TClassTable::fgIdMap->Remove(r->fInfo->name());
68 delete [] fName;
69 delete fProto;
70 delete fNext;
71 }
72
73 char *fName;
77 const std::type_info *fInfo;
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
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
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;
107#ifdef R__WIN32
108 // Window's std::map does NOT defined mapped_type
109 typedef TClassRec* mapped_type;
110#else
112#endif
113
114 private:
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 IdMap_t::const_iterator iter = fMap.find(key);
124 mapped_type cl = nullptr;
125 if (iter != fMap.end()) cl = iter->second;
126 return cl;
127 }
128
129 void Remove(const key_type &key) { fMap.erase(key); }
130
131 void Print() {
132 Info("TMapTypeToClassRec::Print", "printing the typeinfo map in TClassTable");
133 for (const_iterator iter = fMap.begin(); iter != fMap.end(); ++iter) {
134 printf("Key: %40s 0x%zx\n", iter->first.c_str(), (size_t)iter->second);
135 }
136 }
137#else
138 private:
139 TMap fMap;
140 public:
141#ifdef R__COMPLETE_MEM_TERMINATION
143 TIter next(&fMap);
144 TObjString *key;
145 while((key = (TObjString*)next())) {
146 delete key;
147 }
148 }
149#endif
150
151 void Add(const char *key, TClassRec *&obj)
152 {
153 // Add <key,value> pair to the map.
154
155 TObjString *realkey = new TObjString(key);
156 fMap.Add(realkey, (TObject*)obj);
157 }
158
159 TClassRec *Find(const char *key) const {
160 // Find the value corresponding the key.
161 const TPair *a = (const TPair *)fMap.FindObject(key);
162 if (a) return (TClassRec*) a->Value();
163 return 0;
164 }
165
166 void Remove(const char *key) {
167 // Remove the value corresponding the key.
168 TObjString realkey(key);
169 TObject *actual = fMap.Remove(&realkey);
170 delete actual;
171 }
172
173 void Print() {
174 // Print the content of the map.
175 Info("TMapTypeToClassRec::Print", "printing the typeinfo map in TClassTable");
176 TIter next(&fMap);
177 TObjString *key;
178 while((key = (TObjString*)next())) {
179 printf("Key: %s\n",key->String().Data());
180 TClassRec *data = (TClassRec*)fMap.GetValue(key);
181 if (data) {
182 printf(" class: %s %d\n",data->fName,data->fId);
183 } else {
184 printf(" no class: \n");
185 }
186 }
187 }
188#endif
189 };
190
191 static UInt_t ClassTableHash(const char *name, UInt_t size)
192 {
193 auto p = reinterpret_cast<const unsigned char*>( name );
194 UInt_t slot = 0;
195
196 while (*p) slot = slot<<1 ^ *p++;
197 slot %= size;
198
199 return slot;
200 }
201
202 std::vector<std::unique_ptr<TClassRec>> &GetDelayedAddClass()
203 {
204 static std::vector<std::unique_ptr<TClassRec>> delayedAddClass;
205 return delayedAddClass;
206 }
207
208 std::vector<std::pair<const char *, const char *>> &GetDelayedAddClassAlternate()
209 {
210 static std::vector<std::pair<const char *, const char *>> delayedAddClassAlternate;
211 return delayedAddClassAlternate;
212 }
213}
214
215////////////////////////////////////////////////////////////////////////////////
216/// TClassTable is a singleton (i.e. only one can exist per application).
217
219{
220 if (gClassTable) return;
221
222 fgSize = 1009; //this is the result of (int)TMath::NextPrime(1000);
223 fgTable = new TClassRec* [fgSize];
225 fgIdMap = new IdMap_t;
226 memset(fgTable, 0, fgSize*sizeof(TClassRec*));
227 memset(fgAlternate, 0, fgSize*sizeof(TClassAlt*));
228 gClassTable = this;
229
230 for (auto &&r : GetDelayedAddClass()) {
231 AddClass(r->fName, r->fId, *r->fInfo, r->fDict, r->fBits);
232 };
233 GetDelayedAddClass().clear();
234
235 for (auto &&r : GetDelayedAddClassAlternate()) {
236 AddAlternate(r.first, r.second);
237 }
239}
240
241////////////////////////////////////////////////////////////////////////////////
242/// TClassTable singleton is deleted in Terminate().
243
245{
246 // Try to avoid spurious warning from memory leak checkers.
247 if (gClassTable != this) return;
248
249 for (UInt_t i = 0; i < fgSize; i++) {
250 delete fgTable[i]; // Will delete all the elements in the chain.
251 }
252 delete [] fgTable; fgTable = nullptr;
253 delete [] fgSortedTable; fgSortedTable = nullptr;
254 delete fgIdMap; fgIdMap = nullptr;
255}
256
257////////////////////////////////////////////////////////////////////////////////
258/// Return true fs the table exist.
259/// If the table does not exist but the delayed list does, then
260/// create the table and return true.
261
263{
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
281{
282 if (fgTally == 0 || !fgTable)
283 return;
284
285 SortTable();
286
287 int n = 0, ninit = 0, nl = 0;
288
289 if (!option) option = "";
290 int nch = strlen(option);
291 TRegexp re(option, kTRUE);
292
293 Printf("\nDefined classes");
294 Printf("class version bits initialized");
295 Printf("================================================================");
296 for (UInt_t i = 0; i < fgTally; i++) {
298 if (!r) break;
299 n++;
300 TString s = r->fName;
301 if (nch && strcmp(option,r->fName) && s.Index(re) == kNPOS) continue;
302 nl++;
303 if (TClass::GetClass(r->fName, kFALSE)) {
304 ninit++;
305 Printf("%-35s %6d %7d Yes", r->fName, r->fId, r->fBits);
306 } else
307 Printf("%-35s %6d %7d No", r->fName, r->fId, r->fBits);
308 }
309 Printf("----------------------------------------------------------------");
310 Printf("Listed Classes: %4d Total classes: %4d initialized: %4d",nl, n, ninit);
311 Printf("================================================================\n");
312}
313
314//---- static members --------------------------------------------------------
315
316////////////////////////////////////////////////////////////////////////////////
317/// Returns class at index from sorted class table. Don't use this iterator
318/// while modifying the class table. The class table can be modified
319/// when making calls like TClass::GetClass(), etc.
320/// Returns 0 if index points beyond last class name.
321
323{
324 SortTable();
325 if (index < fgTally) {
327 if (r) return r->fName;
328 }
329 return nullptr;
330}
331
332//______________________________________________________________________________
334//______________________________________________________________________________
336
337namespace ROOT { class TForNamespace {}; } // Dummy class to give a typeid to namespace (see also TGenericClassInfo)
338
339////////////////////////////////////////////////////////////////////////////////
340/// Add a class to the class table (this is a static function).
341/// Note that the given cname *must* be already normalized.
342
343void TClassTable::Add(const char *cname, Version_t id, const std::type_info &info,
344 DictFuncPtr_t dict, Int_t pragmabits)
345{
346 if (!gClassTable)
347 new TClassTable;
348
349 if (!cname || *cname == 0)
350 ::Fatal("TClassTable::Add()", "Failed to deduce type for '%s'", info.name());
351
352 // check if already in table, if so return
354 if (r->fName && r->fInfo) {
355 if ( strcmp(r->fInfo->name(),typeid(ROOT::TForNamespace).name())==0
356 && strcmp(info.name(),typeid(ROOT::TForNamespace).name())==0 ) {
357 // We have a namespace being reloaded.
358 // This okay we just keep the old one.
359 return;
360 }
362 // Warn only for class that are not STD classes
363 ::Warning("TClassTable::Add", "class %s already in TClassTable", cname);
364 }
365 return;
366 } else if (ROOT::Internal::gROOTLocal && gCling) {
367 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname);
368 if (oldcl) { // && oldcl->GetClassInfo()) {
369 // As a work-around to ROOT-6012, we need to register the class even if
370 // it is not a template instance, because a forward declaration in the header
371 // files loaded by the current dictionary wil also de-activate the update
372 // class info mechanism!
373
374 // The TClass exist and already has a class info, so it must
375 // correspond to a class template instantiation which the interpreter
376 // was able to make with the library containing the TClass Init.
377 // Because it is already known to the interpreter, the update class info
378 // will not be triggered, we need to force it.
379 gCling->RegisterTClassUpdate(oldcl,dict);
380 }
381 }
382
383 if (!r->fName) r->fName = StrDup(cname);
384 r->fId = id;
385 r->fBits = pragmabits;
386 r->fDict = dict;
387 r->fInfo = &info;
388
389 fgIdMap->Add(info.name(),r);
390
392}
393
394////////////////////////////////////////////////////////////////////////////////
395/// Add a class to the class table (this is a static function).
396
398{
399 if (!gClassTable)
400 new TClassTable;
401
402 // By definition the name in the TProtoClass is (must be) the normalized
403 // name, so there is no need to tweak it.
404 const char *cname = proto->GetName();
405
406 // check if already in table, if so return
408 if (r->fName) {
409 if (r->fProto) delete r->fProto;
410 r->fProto = proto;
411 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname);
412 if (oldcl && oldcl->GetState() == TClass::kHasTClassInit)
413 proto->FillTClass(oldcl);
414 return;
415 } else if (ROOT::Internal::gROOTLocal && gCling) {
416 TClass *oldcl = (TClass*)gROOT->GetListOfClasses()->FindObject(cname);
417 if (oldcl) { // && oldcl->GetClassInfo()) {
418 // As a work-around to ROOT-6012, we need to register the class even if
419 // it is not a template instance, because a forward declaration in the header
420 // files loaded by the current dictionary wil also de-activate the update
421 // class info mechanism!
422
423 ::Warning("TClassTable::Add(TProtoClass*)","Called for existing class without a prior call add the dictionary function.");
424 }
425 }
426
427 r->fName = StrDup(cname);
428 r->fId = 0;
429 r->fBits = 0;
430 r->fDict = nullptr;
431 r->fInfo = nullptr;
432 r->fProto= proto;
433
435}
436
437////////////////////////////////////////////////////////////////////////////////
438
439void TClassTable::AddAlternate(const char *normName, const char *alternate)
440{
441 if (!gClassTable)
442 new TClassTable;
443
444 UInt_t slot = ROOT::ClassTableHash(alternate, fgSize);
445
446 for (const TClassAlt *a = fgAlternate[slot]; a; a = a->fNext.get()) {
447 if (strcmp(alternate,a->fName)==0) {
448 if (strcmp(normName,a->fNormName) != 0) {
449 fprintf(stderr,"Error in TClassTable::AddAlternate: "
450 "Second registration of %s with a different normalized name (old: '%s', new: '%s')\n",
451 alternate, a->fNormName, normName);
452 return;
453 }
454 }
455 }
456
457 fgAlternate[slot] = new TClassAlt(alternate,normName,fgAlternate[slot]);
458}
459
460////////////////////////////////////////////////////////////////////////////////
461
462Bool_t TClassTable::Check(const char *cname, std::string &normname)
463{
464 if (!CheckClassTableInit()) return kFALSE;
465
467
468 // Check if 'cname' is a known normalized name.
469 for (TClassRec *r = fgTable[slot]; r; r = r->fNext)
470 if (strcmp(cname,r->fName)==0) return kTRUE;
471
472 // See if 'cname' is register in the list of alternate names
473 for (const TClassAlt *a = fgAlternate[slot]; a; a = a->fNext.get()) {
474 if (strcmp(cname,a->fName)==0) {
475 normname = a->fNormName;
476 return kTRUE;
477 }
478 }
479
480 return kFALSE;
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// Remove a class from the class table. This happens when a shared library
485/// is unloaded (i.e. the dtor's of the global init objects are called).
486
487void TClassTable::Remove(const char *cname)
488{
489 if (!CheckClassTableInit()) return;
490
492
493 TClassRec *r;
494 TClassRec *prev = nullptr;
495 for (r = fgTable[slot]; r; r = r->fNext) {
496 if (!strcmp(r->fName, cname)) {
497 if (prev)
498 prev->fNext = r->fNext;
499 else
500 fgTable[slot] = r->fNext;
501 fgIdMap->Remove(r->fInfo->name());
502 r->fNext = nullptr; // Do not delete the others.
503 delete r;
504 fgTally--;
506 break;
507 }
508 prev = r;
509 }
510}
511
512////////////////////////////////////////////////////////////////////////////////
513/// Find a class by name in the class table (using hash of name). Returns
514/// 0 if the class is not in the table. Unless arguments insert is true in
515/// which case a new entry is created and returned.
516
518{
520
521 for (TClassRec *r = fgTable[slot]; r; r = r->fNext)
522 if (strcmp(cname,r->fName)==0) return r;
523
524 if (!insert) return nullptr;
525
526 fgTable[slot] = new TClassRec(fgTable[slot]);
527
528 fgTally++;
529 return fgTable[slot];
530}
531
532////////////////////////////////////////////////////////////////////////////////
533/// Find a class by name in the class table (using hash of name). Returns
534/// 0 if the class is not in the table. Unless arguments insert is true in
535/// which case a new entry is created and returned.
536/// cname can be any spelling of the class name. See FindElementImpl if the
537/// name is already normalized.
538
540{
541 if (!CheckClassTableInit()) return nullptr;
542
543 // The recorded name is normalized, let's make sure we convert the
544 // input accordingly.
545 std::string normalized;
547
548 return FindElementImpl(normalized.c_str(), insert);
549}
550
551////////////////////////////////////////////////////////////////////////////////
552/// Returns the ID of a class.
553
555{
557 if (r) return r->fId;
558 return -1;
559}
560
561////////////////////////////////////////////////////////////////////////////////
562/// Returns the pragma bits as specified in the LinkDef.h file.
563
565{
567 if (r) return r->fBits;
568 return 0;
569}
570
571////////////////////////////////////////////////////////////////////////////////
572/// Given the class name returns the Dictionary() function of a class
573/// (uses hash of name).
574
576{
577 if (gDebug > 9) {
578 ::Info("GetDict", "searches for %s", cname);
579 fgIdMap->Print();
580 }
581
583 if (r) return r->fDict;
584 return nullptr;
585}
586
587////////////////////////////////////////////////////////////////////////////////
588/// Given the std::type_info returns the Dictionary() function of a class
589/// (uses hash of std::type_info::name()).
590
591DictFuncPtr_t TClassTable::GetDict(const std::type_info& info)
592{
593 if (!CheckClassTableInit()) return nullptr;
594
595 if (gDebug > 9) {
596 ::Info("GetDict", "searches for %s at 0x%zx", info.name(), (size_t)&info);
597 fgIdMap->Print();
598 }
599
600 TClassRec *r = fgIdMap->Find(info.name());
601 if (r) return r->fDict;
602 return nullptr;
603}
604
605////////////////////////////////////////////////////////////////////////////////
606/// Given the normalized class name returns the Dictionary() function of a class
607/// (uses hash of name).
608
610{
611 if (!CheckClassTableInit()) return nullptr;
612
613 if (gDebug > 9) {
614 ::Info("GetDict", "searches for %s", cname);
615 fgIdMap->Print();
616 }
617
619 if (r) return r->fDict;
620 return nullptr;
621}
622
623////////////////////////////////////////////////////////////////////////////////
624/// Given the class name returns the TClassProto object for the class.
625/// (uses hash of name).
626
628{
629 if (gDebug > 9) {
630 ::Info("GetDict", "searches for %s", cname);
631 }
632
633 if (!CheckClassTableInit()) return nullptr;
634
635 if (gDebug > 9) {
636 ::Info("GetDict", "searches for %s", cname);
637 fgIdMap->Print();
638 }
639
641 if (r) return r->fProto;
642 return nullptr;
643}
644
645////////////////////////////////////////////////////////////////////////////////
646/// Given the class normalized name returns the TClassProto object for the class.
647/// (uses hash of name).
648
650{
651 if (gDebug > 9) {
652 ::Info("GetDict", "searches for %s", cname);
653 }
654
655 if (!CheckClassTableInit()) return nullptr;
656
657 if (gDebug > 9) {
658 fgIdMap->Print();
659 }
660
662 if (r) return r->fProto;
663 return nullptr;
664}
665
666////////////////////////////////////////////////////////////////////////////////
667
668extern "C" {
669 static int ClassComp(const void *a, const void *b)
670 {
671 // Function used for sorting classes alphabetically.
672
673 return strcmp((*(TClassRec **)a)->fName, (*(TClassRec **)b)->fName);
674 }
675}
676
677////////////////////////////////////////////////////////////////////////////////
678/// Returns next class from sorted class table. Don't use this iterator
679/// while modifying the class table. The class table can be modified
680/// when making calls like TClass::GetClass(), etc.
681
683{
684 if (fgCursor < fgTally) {
686 return r->fName;
687 }
688
689 return nullptr;
690}
691
692////////////////////////////////////////////////////////////////////////////////
693/// Print the class table. Before printing the table is sorted
694/// alphabetically.
695
697{
698 if (fgTally == 0 || !fgTable)
699 return;
700
701 SortTable();
702
703 int n = 0, ninit = 0;
704
705 Printf("\nDefined classes");
706 Printf("class version bits initialized");
707 Printf("================================================================");
708 UInt_t last = fgTally;
709 for (UInt_t i = 0; i < last; i++) {
711 if (!r) break;
712 n++;
713 // Do not use TClass::GetClass to avoid any risk of autoloading.
714 if (gROOT->GetListOfClasses()->FindObject(r->fName)) {
715 ninit++;
716 Printf("%-35s %6d %7d Yes", r->fName, r->fId, r->fBits);
717 } else
718 Printf("%-35s %6d %7d No", r->fName, r->fId, r->fBits);
719 }
720 Printf("----------------------------------------------------------------");
721 Printf("Total classes: %4d initialized: %4d", n, ninit);
722 Printf("================================================================\n");
723}
724
725////////////////////////////////////////////////////////////////////////////////
726/// Sort the class table by ascending class ID's.
727
729{
730 if (!fgSorted) {
731 delete [] fgSortedTable;
733
734 int j = 0;
735 for (UInt_t i = 0; i < fgSize; i++)
736 for (TClassRec *r = fgTable[i]; r; r = r->fNext)
737 fgSortedTable[j++] = r;
738
739 ::qsort(fgSortedTable, fgTally, sizeof(TClassRec *), ::ClassComp);
740 fgSorted = kTRUE;
741 }
742}
743
744////////////////////////////////////////////////////////////////////////////////
745/// Deletes the class table (this static class function calls the dtor).
746
748{
749 if (gClassTable) {
750 for (UInt_t i = 0; i < fgSize; i++)
751 delete fgTable[i]; // Will delete all the elements in the chain.
752
753 delete [] fgTable; fgTable = nullptr;
754 delete [] fgSortedTable; fgSortedTable = nullptr;
755 delete fgIdMap; fgIdMap = nullptr;
756 fgSize = 0;
758 }
759}
760
761////////////////////////////////////////////////////////////////////////////////
762/// Global function called by the ctor of a class's init class
763/// (see the ClassImp macro).
764
765void ROOT::AddClass(const char *cname, Version_t id,
766 const std::type_info& info,
767 DictFuncPtr_t dict,
768 Int_t pragmabits)
769{
770 if (!TROOT::Initialized() && !gClassTable) {
771 auto r = std::unique_ptr<TClassRec>(new TClassRec(nullptr));
772 r->fName = StrDup(cname);
773 r->fId = id;
774 r->fBits = pragmabits;
775 r->fDict = dict;
776 r->fInfo = &info;
777 GetDelayedAddClass().emplace_back(std::move(r));
778 } else {
779 TClassTable::Add(cname, id, info, dict, pragmabits);
780 }
781}
782
783////////////////////////////////////////////////////////////////////////////////
784/// Global function called by GenerateInitInstance.
785/// (see the ClassImp macro).
786
787void ROOT::AddClassAlternate(const char *normName, const char *alternate)
788{
789 if (!TROOT::Initialized() && !gClassTable) {
790 GetDelayedAddClassAlternate().emplace_back(normName, alternate);
791 } else {
792 TClassTable::AddAlternate(normName, alternate);
793 }
794}
795
796////////////////////////////////////////////////////////////////////////////////
797/// Global function to update the version number.
798/// This is called via the RootClassVersion macro.
799///
800/// if cl!=0 and cname==-1, set the new class version if and only is
801/// greater than the existing one and greater or equal to 2;
802/// and also ignore the request if fVersionUsed is true.
803///
804/// Note on class version number:
805/// - If no class has been specified, TClass::GetVersion will return -1
806/// - The Class Version 0 request the whole object to be transient
807/// - The Class Version 1, unless specify via ClassDef indicates that the
808/// I/O should use the TClass checksum to distinguish the layout of the class
809
810void ROOT::ResetClassVersion(TClass *cl, const char *cname, Short_t newid)
811{
812 if (cname && cname!=(void*)-1) {
814 if (r) r->fId = newid;
815 }
816 if (cl) {
817 if (cl->fVersionUsed) {
818 // Problem, the reset is called after the first usage!
819 if (cname!=(void*)-1)
820 Error("ResetClassVersion","Version number of %s can not be changed after first usage!",
821 cl->GetName());
822 } else {
823 if (newid < 0) {
824 Error("SetClassVersion","The class version (for %s) must be positive (value %d is ignored)",cl->GetName(),newid);
825 }
826 if (cname==(void*)-1) {
827 if (cl->fClassVersion<newid && 2<=newid) {
828 cl->SetClassVersion(newid);
829 }
830 } else {
831 cl->SetClassVersion(newid);
832 }
833 }
834 }
835}
836
837
838////////////////////////////////////////////////////////////////////////////////
839/// Global function called by the dtor of a class's init class
840/// (see the ClassImp macro).
841
842void ROOT::RemoveClass(const char *cname)
843{
844 // don't delete class information since it is needed by the I/O system
845 // to write the StreamerInfo to file
846 if (cname) {
847 // Let's still remove this information to allow reloading later.
848 // Anyway since the shared library has been unloaded, the dictionary
849 // pointer is now invalid ....
850 // We still keep the TClass object around because TFile needs to
851 // get to the TStreamerInfo.
852 if (gROOT && gROOT->GetListOfClasses()) {
853 TObject *pcname;
854 if ((pcname=gROOT->GetListOfClasses()->FindObject(cname))) {
855 TClass *cl = dynamic_cast<TClass*>(pcname);
856 if (cl) cl->SetUnloaded();
857 }
858 }
860 }
861}
862
863////////////////////////////////////////////////////////////////////////////////
864/// Global function to register the implementation file and line of
865/// a class template (i.e. NOT a concrete class).
866
867TNamed *ROOT::RegisterClassTemplate(const char *name, const char *file,
868 Int_t line)
869{
870 static TList table;
871 static Bool_t isInit = kFALSE;
872 if (!isInit) {
873 table.SetOwner(kTRUE);
874 isInit = kTRUE;
875 }
876
877 TString classname(name);
878 Ssiz_t loc = classname.Index("<");
879 if (loc >= 1) classname.Remove(loc);
880 if (file) {
881 TNamed *obj = new TNamed((const char*)classname, file);
882 obj->SetUniqueID(line);
883 table.Add(obj);
884 return obj;
885 }
886
887 return (TNamed*)table.FindObject(classname);
888}
#define SafeDelete(p)
Definition: RConfig.hxx:547
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition: RtypesCore.h:63
const Ssiz_t kNPOS
Definition: RtypesCore.h:124
short Version_t
Definition: RtypesCore.h:65
const Bool_t kFALSE
Definition: RtypesCore.h:101
unsigned int UInt_t
Definition: RtypesCore.h:46
short Short_t
Definition: RtypesCore.h:39
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
TClass *(* DictFuncPtr_t)()
Definition: Rtypes.h:80
#define ClassImp(name)
Definition: Rtypes.h:375
TClassTable * gClassTable
Definition: TClassTable.cxx:44
static int ClassComp(const void *a, const void *b)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition: TError.cxx:221
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:188
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
char name[80]
Definition: TGX11.cxx:110
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:565
Int_t gDebug
Definition: TROOT.cxx:585
#define gROOT
Definition: TROOT.h:406
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition: TString.cxx:2482
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2536
const char * proto
Definition: civetweb.c:17502
const char * fName
Definition: TClassTable.cxx:92
TClassAlt(const char *alternate, const char *normName, TClassAlt *next)
Definition: TClassTable.cxx:84
std::unique_ptr< TClassAlt > fNext
Definition: TClassTable.cxx:94
const char * fNormName
Definition: TClassTable.cxx:93
DictFuncPtr_t fDict
Definition: TClassTable.cxx:76
TClassRec(TClassRec *next)
Definition: TClassTable.cxx:62
const std::type_info * fInfo
Definition: TClassTable.cxx:77
TClassRec * fNext
Definition: TClassTable.cxx:79
TProtoClass * fProto
Definition: TClassTable.cxx:78
IdMap_t::size_type size_type
IdMap_t::mapped_type mapped_type
void Add(const key_type &key, mapped_type &obj)
IdMap_t::key_type key_type
std::map< std::string, TClassRec * > IdMap_t
IdMap_t::const_iterator const_iterator
void Remove(const key_type &key)
mapped_type Find(const key_type &key) const
IdMap_t::size_type size_type
Definition: TClass.cxx:373
IdMap_t::mapped_type mapped_type
Definition: TClass.cxx:378
IdMap_t::const_iterator const_iterator
Definition: TClass.cxx:372
IdMap_t::key_type key_type
Definition: TClass.cxx:371
This class registers for all classes their name, id and dictionary function in a hash table.
Definition: TClassTable.h:36
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:42
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:44
static ROOT::TClassRec * FindElementImpl(const char *cname, Bool_t insert)
Find a class by name in the class table (using hash of name).
void Print(Option_t *option="") const override
Print the class table.
static void Terminate()
Deletes the class table (this static class function calls the dtor).
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:46
static ROOT::TClassRec ** fgTable
Definition: TClassTable.h:45
static IdMap_t * fgIdMap
Definition: TClassTable.h:47
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:50
static UInt_t fgTally
Definition: TClassTable.h:49
static UInt_t fgSize
Definition: TClassTable.h:48
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:51
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:81
EState GetState() const
Definition: TClass.h:486
Version_t fClassVersion
Definition: TClass.h:222
void SetUnloaded()
Call this method to indicate that the shared library containing this class's code has been removed (u...
Definition: TClass.cxx:6298
void SetClassVersion(Version_t version)
Private function.
Definition: TClass.cxx:5664
std::atomic< Bool_t > fVersionUsed
saved remember if fOffsetStreamer has been set.
Definition: TClass.h:260
@ kHasTClassInit
Definition: TClass.h:128
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:2968
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:38
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition: TList.cxx:578
void Add(TObject *obj) override
Definition: TList.h:81
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
const char * GetName() const override
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:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:956
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:998
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:785
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:944
Class used by TMap to store (key,value) pairs.
Definition: TMap.h:102
Persistent version of a TClass.
Definition: TProtoClass.h:38
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2834
Regular expression class.
Definition: TRegexp.h:31
Basic string class.
Definition: TString.h:136
const char * Data() const
Definition: TString.h:369
TString & Remove(Ssiz_t pos)
Definition: TString.h:674
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:640
TLine * line
const Int_t n
Definition: legend1.C:16
R__EXTERN TROOT * gROOTLocal
Definition: TROOT.h:379
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
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:854
static constexpr double s
Definition: file.py:1
TArc a
Definition: textangle.C:12