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