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