Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TBaseClass.cxx
Go to the documentation of this file.
1 // @(#)root/meta:$Id$
2 // Author: Fons Rademakers 08/02/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 #include "TBaseClass.h"
13 #include "TBuffer.h"
14 #include "TClass.h"
15 #include "TInterpreter.h"
16 #include <limits.h>
17 
18 #include "TVirtualMutex.h" // For R__LOCKGUARD
19 
20 /** \class TBaseClass
21 Each class (see TClass) has a linked list of its base class(es).
22 This class describes one single base class.
23 The base class info is obtained via the CINT api.
24  see class TCling.
25 
26 The base class information is used a.o. in to find all inherited methods.
27 */
28 
29 
30 ClassImp(TBaseClass);
31 
32 ////////////////////////////////////////////////////////////////////////////////
33 /// Default TBaseClass ctor. TBaseClasses are constructed in TClass
34 /// via a call to TCling::CreateListOfBaseClasses().
35 
36 TBaseClass::TBaseClass(BaseClassInfo_t *info, TClass *cl) :
37  TDictionary(), fInfo(info), fClass(cl), fDelta(INT_MAX),
38  fProperty(-1), fSTLType(-1)
39 {
40  if (fInfo) SetName(gCling->BaseClassInfo_FullName(fInfo));
41 }
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// TBaseClass dtor deletes adopted CINT BaseClassInfo object.
45 
46 TBaseClass::~TBaseClass()
47 {
48  gCling->BaseClassInfo_Delete(fInfo);
49 }
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Called by the browser, to browse a baseclass.
53 
54 void TBaseClass::Browse(TBrowser *b)
55 {
56  TClass *c = GetClassPointer();
57  if (c) c->Browse(b);
58 }
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 /// Get pointer to the base class TClass.
62 
63 TClass *TBaseClass::GetClassPointer(Bool_t load)
64 {
65  if (!fClassPtr) {
66  if (fInfo) fClassPtr = TClass::GetClass(gCling->BaseClassInfo_ClassInfo(fInfo),load);
67  else fClassPtr = TClass::GetClass(fName, load);
68  }
69  return fClassPtr;
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Get offset from "this" to part of base class.
74 
75 Int_t TBaseClass::GetDelta()
76 {
77  // Initialized to INT_MAX to signal that it's unset; -1 is a valid value
78  // meaning "cannot calculate base offset".
79  if (fDelta == INT_MAX) {
80  R__LOCKGUARD(gInterpreterMutex);
81  if (Property() & kIsVirtualBase)
82  fDelta = -1;
83  else if (fInfo)
84  fDelta = (Int_t)gCling->BaseClassInfo_Offset(fInfo);
85  }
86  return fDelta;
87 }
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 /// Get base class description (comment).
91 
92 const char *TBaseClass::GetTitle() const
93 {
94  TClass *c = ((TBaseClass *)this)->GetClassPointer();
95  return c ? c->GetTitle() : "";
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Return which type (if any) of STL container the data member is.
100 
101 ROOT::ESTLType TBaseClass::IsSTLContainer()
102 {
103  // fSTLType is -1 if not yet evaluated.
104  // fSTLType is -2 if no fInfo was available.
105 
106  if (fSTLType < 0) {
107  if (!fInfo) {
108  fSTLType = -2;
109  } else {
110  const char *type = gCling->BaseClassInfo_TmpltName(fInfo);
111  if (!type) fSTLType = ROOT::kNotSTL;
112  else if (!strcmp(type, "vector")) fSTLType = ROOT::kSTLvector;
113  else if (!strcmp(type, "list")) fSTLType = ROOT::kSTLlist;
114  else if (!strcmp(type, "forward_list")) fSTLType = ROOT::kSTLforwardlist;
115  else if (!strcmp(type, "deque")) fSTLType = ROOT::kSTLdeque;
116  else if (!strcmp(type, "map")) fSTLType = ROOT::kSTLmap;
117  else if (!strcmp(type, "multimap")) fSTLType = ROOT::kSTLmultimap;
118  else if (!strcmp(type, "set")) fSTLType = ROOT::kSTLset;
119  else if (!strcmp(type, "multiset")) fSTLType = ROOT::kSTLmultiset;
120  else if (!strcmp(type, "unordered_set")) fSTLType = ROOT::kSTLunorderedset;
121  else if (!strcmp(type, "unordered_multiset")) fSTLType = ROOT::kSTLunorderedmultiset;
122  else if (!strcmp(type, "unordered_map")) fSTLType = ROOT::kSTLunorderedmap;
123  else if (!strcmp(type, "unordered_multimap")) fSTLType = ROOT::kSTLunorderedmultimap;
124  else fSTLType = ROOT::kNotSTL;
125  }
126  }
127  if (fSTLType == -2) return ROOT::kNotSTL;
128  return (ROOT::ESTLType) fSTLType;
129 }
130 
131 ////////////////////////////////////////////////////////////////////////////////
132 /// Get property description word. For meaning of bits see EProperty.
133 
134 Long_t TBaseClass::Property() const
135 {
136  if (fProperty == -1 && fInfo) {
137  R__LOCKGUARD(gInterpreterMutex);
138  fProperty = gCling->BaseClassInfo_Property(fInfo);
139  }
140  return fProperty;
141 }
142 
143 ////////////////////////////////////////////////////////////////////////////////
144 /// Stream an object of TBaseClass. Triggers the calculation of the
145 /// cache variables to store them.
146 
147 void TBaseClass::Streamer(TBuffer& b) {
148  if (b.IsReading()) {
149  b.ReadClassBuffer(Class(), this);
150  } else {
151  // Writing.
152  // Calculate cache properties first.
153  GetDelta();
154  Property();
155  IsSTLContainer();
156  b.WriteClassBuffer(Class(), this);
157  }
158 }