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