Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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(nullptr),
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 false;
161 // Purposely do not test on the name!
162 if ( strcmp(GetTitle(),other->GetTitle()) ) return false;
163 // if ( fBranchName != other->fBranchName ) return false;
164 // if ( fSubBranchPrefix != other->fSubBranchPrefix ) return false;
165
166 if (fIsClones != other->fIsClones) return false;
167 if (fIsClones != kOut) {
168 if (fContainerName != other->fContainerName) return false;
169 }
170
172 TBranchProxyDescriptor *othdesc;
173
174 if ( fListOfBaseProxies.GetSize() != other->fListOfBaseProxies.GetSize() ) return false;
176 TIter othnext(&other->fListOfBaseProxies);
177 while ( (desc=(TBranchProxyDescriptor*)next()) ) {
178 othdesc=(TBranchProxyDescriptor*)othnext();
179 if (!desc->IsEquivalent(othdesc,true) ) return false;
180 }
181
182 if ( fListOfSubProxies.GetSize() != other->fListOfSubProxies.GetSize() ) return false;
183 next = &fListOfSubProxies;
184 othnext = &(other->fListOfSubProxies);
185
186 while ( (desc=(TBranchProxyDescriptor*)next()) ) {
187 othdesc=(TBranchProxyDescriptor*)othnext();
188 if (!desc->IsEquivalent(othdesc,true)) return false;
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 false;
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());
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
230 bool TBranchProxyClassDescriptor::IsLoaded(const char *classname)
231 {
232 TClass *cl = TClass::GetClass(classname);
233 while (cl) {
234 if (cl->IsLoaded()) return true;
235 if (!cl->GetCollectionProxy()) return false;
236 if (!cl->GetCollectionProxy()->GetValueClass()) return true; // stl container of simple type are always 'loaded'
237 cl = cl->GetCollectionProxy()->GetValueClass();
238 }
239 return false;
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 wroteFirst = false;
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 = false;
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()) ) {
474 }
475 fprintf(hf,"%-*s};\n",offset," ");
476
477 //TBranchProxyDescriptor::OutputDecl(hf,offset,maxVarname);
478 }
479
480} // namespace Internal
481} // namespace ROOT
int main()
Definition Prototype.cxx:12
#define ClassImp(name)
Definition Rtypes.h:382
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
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.
bool IsClones() const
Return true if this proxy is for a TClonesArray.
TBranchProxyClassDescriptor(const TBranchProxyClassDescriptor &b)
void OutputDecl(FILE *hf, int offset, UInt_t)
Output the declaration and implementation of this emulation class.
virtual bool IsEquivalent(const TBranchProxyClassDescriptor *other)
Return true if this description is the 'same' as the other decription.
void NameToSymbol()
Make the typename a proper class name without having the really deal with namespace and templates.
bool IsSTL() const
Return true if this proxy is for a TClonesArray.
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 IsLoaded() const
Return true if the class needed by the branch is loaded.
void AddDescriptor(TBranchProxyDescriptor *desc, bool isBase)
Add a descriptor to this proxy.
bool IsSplit() const
Return true if the branch is split.
void OutputDecl(FILE *hf, int offset, UInt_t maxVarname)
Output the declaration corresponding to this proxy.
const char * GetBranchName()
Get the branch name.
bool IsEquivalent(const TBranchProxyDescriptor *other, bool inClass=false)
Return true if this description is the 'same' as the other description.
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.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
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:4523
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5979
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2964
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:3035
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
void Reset()
void Add(TObject *obj) override
Definition TList.h:81
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:355
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
TString & Prepend(const char *cs)
Definition TString.h:673
TString & Remove(Ssiz_t pos)
Definition TString.h:685
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
virtual TClass * GetValueClass() const =0
If the value type is a user-defined class, return a pointer to the TClass representing the value type...
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.