Logo ROOT  
Reference Guide
TBranchProxyClassDescriptor.cxx
Go to the documentation of this file.
1// @(#)root/treeplayer:$Id$
2// Author: Philippe Canal 06/06/2004
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers and al. *
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 TBranchProxyClassDescriptor
13Hold the processed information about a TClass used in a TBranch while
14TTreeProxyGenerator is parsing the TTree information.
15Also contains the routine use to generate the appropriate code
16fragment in the result of MakeProxy.
17*/
18
21
22#include "TClass.h"
23#include "TClassEdit.h"
24#include "TError.h"
27
29
30namespace ROOT {
31namespace Internal {
32
33 ////////////////////////////////////////////////////////////////////////////////
34 /// Make the typename a proper class name without having the really deal with
35 /// namespace and templates.
36
38
39 fRawSymbol = TClassEdit::ShortType(GetName(),2); // Drop default allocator from the name.
40 fRawSymbol.ReplaceAll(":","_");
41 fRawSymbol.ReplaceAll("<","_");
42 fRawSymbol.ReplaceAll(">","_");
43 fRawSymbol.ReplaceAll(",","Cm");
44 fRawSymbol.ReplaceAll(" ","");
45 fRawSymbol.ReplaceAll("*","st");
46 fRawSymbol.ReplaceAll("&","rf");
47 if (IsClones())
48 fRawSymbol.Prepend("TClaPx_");
49 else if (IsSTL())
50 fRawSymbol.Prepend("TStlPx_");
51 else
52 fRawSymbol.Prepend("TPx_");
53 if (fRawSymbol.Length() && fRawSymbol[fRawSymbol.Length()-1]=='.')
55
57 }
58
59 ////////////////////////////////////////////////////////////////////////////////
60 /// Constructor.
61
64 const char *branchname,
65 ELocation isclones,
66 UInt_t splitlevel,
67 const TString &containerName) :
69 fIsClones(isclones),
70 fContainerName(containerName),
71 fIsLeafList(false),
72 fSplitLevel(splitlevel),
73 fBranchName(branchname),
74 fSubBranchPrefix(branchname),
75 fInfo(info),
76 fMaxDatamemberType(3)
77 {
78 R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
81 }
82
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Constructor for a branch constructed from a leaf list.
85
87 TNamed(branchname,branchname),
88 fIsClones(kOut),
89 fContainerName(),
90 fIsLeafList(true),
91 fSplitLevel(0),
92 fBranchName(branchname),
93 fSubBranchPrefix(branchname),
94 fInfo(0),
95 fMaxDatamemberType(3)
96 {
99 }
100
101 ////////////////////////////////////////////////////////////////////////////////
102 /// Constructor.
103
105 const char *branchname,
106 const char *branchPrefix, ELocation isclones,
107 UInt_t splitlevel,
108 const TString &containerName) :
110 fIsClones(isclones),
111 fContainerName(containerName),
112 fIsLeafList(true),
113 fSplitLevel(splitlevel),
114 fBranchName(branchname),
115 fSubBranchPrefix(branchPrefix),
116 fInfo(info),
117 fMaxDatamemberType(3)
118 {
119 R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
120 NameToSymbol();
122 }
123
124 ////////////////////////////////////////////////////////////////////////////////
125 /// Get the branch name
126
128 {
129 return fBranchName.Data();
130 }
131
132 ////////////////////////////////////////////////////////////////////////////////
133 /// Get the prefix from the branch name
134
136 {
137 return fSubBranchPrefix.Data();
138 }
139
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Get the real symbol name
142
144 {
145 return fRawSymbol;
146 }
147
148 ////////////////////////////////////////////////////////////////////////////////
149 /// Return the split level of the branch.
150
152 return fSplitLevel;
153 }
154
155 ////////////////////////////////////////////////////////////////////////////////
156 /// Return true if this description is the 'same' as the other decription.
157
159 {
160 if ( !other ) return kFALSE;
161 // Purposely do not test on the name!
162 if ( strcmp(GetTitle(),other->GetTitle()) ) return kFALSE;
163 // if ( fBranchName != other->fBranchName ) return kFALSE;
164 // if ( fSubBranchPrefix != other->fSubBranchPrefix ) return kFALSE;
165
166 if (fIsClones != other->fIsClones) return kFALSE;
167 if (fIsClones != kOut) {
168 if (fContainerName != other->fContainerName) return kFALSE;
169 }
170
172 TBranchProxyDescriptor *othdesc;
173
174 if ( fListOfBaseProxies.GetSize() != other->fListOfBaseProxies.GetSize() ) return kFALSE;
176 TIter othnext(&other->fListOfBaseProxies);
177 while ( (desc=(TBranchProxyDescriptor*)next()) ) {
178 othdesc=(TBranchProxyDescriptor*)othnext();
179 if (!desc->IsEquivalent(othdesc,kTRUE) ) return kFALSE;
180 }
181
182 if ( fListOfSubProxies.GetSize() != other->fListOfSubProxies.GetSize() ) return kFALSE;
183 next = &fListOfSubProxies;
184 othnext = &(other->fListOfSubProxies);
185
186 while ( (desc=(TBranchProxyDescriptor*)next()) ) {
187 othdesc=(TBranchProxyDescriptor*)othnext();
188 if (!desc->IsEquivalent(othdesc,kTRUE)) return kFALSE;
189 if (desc->IsSplit()) {
190 TString leftname ( desc->GetBranchName() );
191 TString rightname( othdesc->GetBranchName() );
192
193 if (leftname.Index(GetBranchName())==0) leftname.Remove( 0,strlen(GetBranchName()));
194 if (leftname.Length() && leftname[0]=='.') leftname.Remove(0,1);
195 if (rightname.Index(other->GetBranchName())==0) rightname.Remove(0,strlen(other->GetBranchName()));
196 if (rightname.Length() && rightname[0]=='.') rightname.Remove(0,1);
197 if (leftname != rightname ) return kFALSE;
198 }
199 }
200 return true;
201 }
202
203 ////////////////////////////////////////////////////////////////////////////////
204 /// Add a descriptor to this proxy.
205
207 {
208 if (desc) {
209 if (isBase) {
211 } else {
213 UInt_t len = strlen(desc->GetTypeName());
214 if ((len+2)>fMaxDatamemberType) fMaxDatamemberType = len+2;
215 }
216 }
217 }
218
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Return true if the class needed by the branch is loaded
221
223 {
224 return IsLoaded(GetTitle());
225 }
226
227 ////////////////////////////////////////////////////////////////////////////////
228 /// Return true if the class needed by the branch is loaded
229
231 {
232 TClass *cl = TClass::GetClass(classname);
233 while (cl) {
234 if (cl->IsLoaded()) return kTRUE;
235 if (!cl->GetCollectionProxy()) return kFALSE;
236 if (!cl->GetCollectionProxy()->GetValueClass()) return kTRUE; // stl container of simple type are always 'loaded'
237 cl = cl->GetCollectionProxy()->GetValueClass();
238 }
239 return kFALSE;
240 }
241
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Return true if this proxy is for a TClonesArray.
244
246 {
248 }
249
250 ////////////////////////////////////////////////////////////////////////////////
251 /// Return true if this proxy is for a TClonesArray.
252
254 {
256 }
257
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Return whether the branch is inside, nested in or outside of a TClonesArray
260
262 {
263 return fIsClones;
264 }
265
266 ////////////////////////////////////////////////////////////////////////////////
267 /// Return the name of the container holding this class, if any.
268
270 {
271 return fContainerName;
272 }
273
274 ////////////////////////////////////////////////////////////////////////////////
275 /// Output the declaration and implementation of this emulation class
276
277 void TBranchProxyClassDescriptor::OutputDecl(FILE *hf, int offset, UInt_t /* maxVarname */)
278 {
280
281
282 // Start the class declaration with the eventual list of base classes
283 fprintf(hf,"%-*sstruct %s\n", offset," ", GetName() );
284
286 fprintf(hf,"%-*s : ", offset," ");
287
289
290 desc = (TBranchProxyDescriptor*)next();
291 fprintf(hf,"public %s", desc->GetTypeName());
292
293 while ( (desc = (TBranchProxyDescriptor*)next()) ) {
294 fprintf(hf,",\n%-*spublic %s", offset+5," ", desc->GetTypeName());
295 }
296
297 fprintf(hf,"\n");
298 }
299 fprintf(hf,"%-*s{\n", offset," ");
300
301
302 // Write the constructor
303 fprintf(hf,"%-*s %s(TBranchProxyDirector* director,const char *top,const char *mid=0) :",
304 offset," ", GetName());
305
306 Bool_t wroteFirst = kFALSE;
307
309
311
312 desc = (TBranchProxyDescriptor*)next();
313 fprintf(hf,"\n%-*s%-*s(director, top, mid)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
314 wroteFirst = true;
315
316 while ( (desc = (TBranchProxyDescriptor*)next()) ) {
317 fprintf(hf,",\n%-*s%-*s(director, top, mid)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
318 }
319
320 }
321 fprintf(hf,"%s\n%-*s %-*s(top,mid)",wroteFirst?",":"",offset," ",fMaxDatamemberType,"ffPrefix");
322 wroteFirst = true;
323
324 TString objInit = "top, mid";
325 if ( GetIsClones() == kInsideClones || GetIsClones() == kInsideSTL ) {
328 if (desc && desc->IsSplit()) {
329
330 // In the case of a split sub object is TClonesArray, the
331 // object itself does not have its own branch, so we need to
332 // use its first (semantic) sub-branch as a proxy
333
335 TString sub = desc->GetBranchName();
336 sub.Remove(0,main.Length()+1);
337
338 objInit = "ffPrefix, ";
339 objInit += "\"";
340 objInit += sub;
341 objInit += "\"";
342
343 objInit = "top, \"\", mid";
344 }
345 }
346 }
347
348 fprintf(hf,"%s\n%-*s %-*s(director, %s)",
349 ",",offset," ",fMaxDatamemberType,"obj",objInit.Data());
350
352 while ( (desc = (TBranchProxyDescriptor*)next()) ) {
353 fprintf(hf,",");
355 }
356 fprintf(hf,"\n%-*s {};\n",offset," ");
357
358
359 // Write the 2nd constructor
360 fprintf(hf,"%-*s %s(TBranchProxyDirector* director, TBranchProxy *parent, const char *membername, const char *top=0, const char *mid=0) :",
361 offset," ", GetName());
362
363 wroteFirst = kFALSE;
364
366
367 TIter nextbase(&fListOfBaseProxies);
368
369 // This is guarantee to return a non zero value due to the if (fListOfBaseProxies.GetSize())
370 desc = (TBranchProxyDescriptor*)nextbase();
371 fprintf(hf,"\n%-*s%-*s(director, parent, membername, top, mid)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
372 wroteFirst = true;
373
374 while ( (desc = (TBranchProxyDescriptor*)nextbase()) ) {
375 fprintf(hf,",\n%-*s%-*s(director, parent, membername, top, mid)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
376 }
377
378 }
379 fprintf(hf,"%s\n%-*s %-*s(top,mid)",wroteFirst?",":"",offset," ",fMaxDatamemberType,"ffPrefix");
380 wroteFirst = true;
381
382 if ( true || IsLoaded() || IsClones() || IsSTL() ) {
383 fprintf(hf,"%s\n%-*s %-*s(director, parent, membername, top, mid)",
384 ",",offset," ",fMaxDatamemberType,"obj");
385 }
386
387 next.Reset();
388 while ( (desc = (TBranchProxyDescriptor*)next()) ) {
389 fprintf(hf,",");
391 }
392 fprintf(hf,"\n%-*s {};\n",offset," ");
393
394
395 // Declare the data members.
396 fprintf(hf,"%-*s%-*s %s;\n", offset+3," ", fMaxDatamemberType, "ROOT::Internal::TBranchProxyHelper", "ffPrefix");
397
398 // If the real class is available, make it available via the arrow operator:
399 if (IsLoaded()) {
400
401 const char *type = GetTitle(); /* IsClones() ? "TClonesArray" : GetTitle(); */
402 fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
403 //Can the real type contain a leading 'const'? If so the following is incorrect.
404 if ( IsClones() ) {
405 fprintf(hf,"%-*sconst %s* operator[](Int_t i) { return obj.At(i); }\n", offset+3," ",type);
406 fprintf(hf,"%-*sconst %s* operator[](UInt_t i) { return obj.At(i); }\n", offset+3," ",type);
407 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
408 fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
409 fprintf(hf,"%-*sTClaObjProxy<%s > obj;\n", offset+3, " ", type);
410 } else if ( IsSTL() ) {
412 fprintf(hf,"%-*sconst %s& At(UInt_t i) {\n",offset+3," ",type);
415 if (cl->GetMethodWithPrototype(cl->GetName(),"TRootIOCtor*")) {
416 fprintf(hf,"%-*s static %s default_val((TRootIOCtor*)0);\n",offset+3," ",type);
417 } else {
418 fprintf(hf,"%-*s static %s default_val;\n",offset+3," ",type);
419 }
420 fprintf(hf,"%-*s if (!obj.Read()) return default_val;\n",offset+3," ");
421 if (stlCl->GetCollectionProxy()->GetValueClass() == cl) {
422 fprintf(hf,"%-*s %s *temp = & obj.GetPtr()->at(i);\n",offset+3," ",type);
423 } else {
424 fprintf(hf,"%-*s %s *temp = (%s *)( obj.GetProxy()->GetStlStart(i) );\n",offset+3," ",type,type);
425 }
426 //fprintf(hf,"%-*s %s *temp = (%s *)( obj.GetPtr()->at(i)) + obj.GetOffset() );\n",offset+3," ",type,type);
427 //fprintf(hf,"%-*s %s *temp = (%s *)(void*)(&obj.At(i));\n",offset+3," ",type,type);
428 fprintf(hf,"%-*s if (temp) return *temp; else return default_val;\n",offset+3," ");
429 fprintf(hf,"%-*s}\n",offset+3," ");
430
431 fprintf(hf,"%-*sconst %s& operator[](Int_t i) { return At(i); }\n", offset+3," ",type);
432 fprintf(hf,"%-*sconst %s& operator[](UInt_t i) { return At(i); }\n", offset+3," ",type);
433 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetPtr()->size(); }\n",offset+3," ");
434 fprintf(hf,"%-*sconst %s* operator->() { return obj.GetPtr(); }\n", offset+3," ",fContainerName.Data());
435 fprintf(hf,"%-*soperator %s*() { return obj.GetPtr(); }\n", offset+3," ",fContainerName.Data());
436 fprintf(hf,"%-*sTObjProxy<%s > obj;\n", offset+3, " ", fContainerName.Data());
437 } else {
438 fprintf(hf,"%-*sconst %s& operator[](Int_t i) { return obj.At(i); }\n", offset+3," ",type);
439 fprintf(hf,"%-*sconst %s& operator[](UInt_t i) { return obj.At(i); }\n", offset+3," ",type);
440 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
441 fprintf(hf,"%-*sTStlObjProxy<%s > obj;\n", offset+3, " ", type);
442 }
443 } else {
444 fprintf(hf,"%-*sconst %s* operator->() { return obj.GetPtr(); }\n", offset+3," ",type);
445 fprintf(hf,"%-*sTObjProxy<%s > obj;\n", offset+3, " ", type);
446 }
447
448 } else if ( IsClones()) {
449
450 fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
451 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
452 fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
453 fprintf(hf,"%-*sTClaProxy obj;\n", offset+3," ");
454
455 } else if ( IsSTL()) {
456
457 fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
458 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
459 // fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
460 fprintf(hf,"%-*sTStlProxy obj;\n", offset+3," ");
461
462 } else {
463
464 fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
465 fprintf(hf,"%-*sTBranchProxy obj;\n", offset+3," ");
466
467 }
468
469 fprintf(hf,"\n");
470
471 next.Reset();
472 while( (desc = ( TBranchProxyDescriptor *)next()) ) {
473 desc->OutputDecl(hf,offset+3,fMaxDatamemberType);
474 }
475 fprintf(hf,"%-*s};\n",offset," ");
476
477 //TBranchProxyDescriptor::OutputDecl(hf,offset,maxVarname);
478 }
479
480} // namespace Internal
481} // namespace ROOT
unsigned int UInt_t
Definition: RtypesCore.h:46
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
#define R__ASSERT(e)
Definition: TError.h:118
int type
Definition: TGX11.cxx:121
int main(int argc, char *argv[])
Definition: cef_main.cxx:54
Bool_t IsLoaded() const
Return true if the class needed by the branch is loaded.
const char * GetBranchName() const
Get the branch name.
const char * GetRawSymbol() const
Get the real symbol name.
const char * GetSubBranchPrefix() const
Get the prefix from the branch name.
ELocation GetIsClones() const
Return whether the branch is inside, nested in or outside of a TClonesArray.
TBranchProxyClassDescriptor(const TBranchProxyClassDescriptor &b)
Bool_t IsClones() const
Return true if this proxy is for a TClonesArray.
void AddDescriptor(TBranchProxyDescriptor *desc, Bool_t isBase)
Add a descriptor to this proxy.
void OutputDecl(FILE *hf, int offset, UInt_t)
Output the declaration and implementation of this emulation class.
void NameToSymbol()
Make the typename a proper class name without having the really deal with namespace and templates.
virtual Bool_t IsEquivalent(const TBranchProxyClassDescriptor *other)
Return true if this description is the 'same' as the other decription.
UInt_t GetSplitLevel() const
Return the split level of the branch.
TString GetContainerName() const
Return the name of the container holding this class, if any.
Bool_t IsSTL() const
Return true if this proxy is for a TClonesArray.
void OutputDecl(FILE *hf, int offset, UInt_t maxVarname)
Output the declaration corresponding to this proxy.
const char * GetBranchName()
Get the branch name.
const char * GetTypeName()
Get the name of the type of the data member.
void OutputInit(FILE *hf, int offset, UInt_t maxVarname, const char *prefix)
Output the initialization corresponding to this proxy.
Bool_t IsSplit() const
Return true if the branch is split.
Bool_t IsEquivalent(const TBranchProxyDescriptor *other, Bool_t inClass=kFALSE)
Return true if this description is the 'same' as the other description.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
TMethod * GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition: TClass.cxx:4449
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5905
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2884
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:2955
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:184
void Reset()
Definition: TCollection.h:254
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:357
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Basic string class.
Definition: TString.h:136
Ssiz_t Length() const
Definition: TString.h:410
const char * Data() const
Definition: TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:692
TString & Prepend(const char *cs)
Definition: TString.h:661
TString & Remove(Ssiz_t pos)
Definition: TString.h:673
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:639
virtual TClass * GetValueClass() const =0
Abstract Interface class describing Streamer information for one class.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.