Logo ROOT   6.10/09
Reference Guide
TMakeProject.cxx
Go to the documentation of this file.
1 // @(#)root/io:$Id$
2 // Author: Rene Brun 12/10/2000
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 /*
13 \class TMakeProject TMakeProject.cxx
14 \ingroup IO
15 
16 Helper class implementing the TFile::MakeProject.
17 **/
18 
19 #include <ctype.h>
20 #include "TMakeProject.h"
21 #include "TClass.h"
22 #include "TClassEdit.h"
23 #include "TROOT.h"
24 #include "TMD5.h"
25 #include "TStreamerInfo.h"
26 #include "TStreamerElement.h"
27 #include "TError.h"
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 /// Add an include statement, if it has not already been added.
31 
32 void TMakeProject::AddUniqueStatement(FILE *fp, const char *statement, char *inclist)
33 {
34  if (!strstr(inclist, statement)) {
35  if (strlen(inclist)+strlen(statement) >= 50000) {
36  Fatal("AddUniqueStatement","inclist too short need %u instead of 500000",UInt_t(strlen(inclist)+strlen(statement)));
37  }
38  strcat(inclist, statement);
39  fprintf(fp, "%s", statement);
40  }
41 }
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Add an include statement, if it has not already been added.
45 
46 void TMakeProject::AddInclude(FILE *fp, const char *header, Bool_t system, char *inclist)
47 {
48  TString what;
49  if (system) {
50  what.Form("#include <%s>\n", header);
51  } else {
52  what.Form("#include \"%s\"\n", header);
53  }
54  AddUniqueStatement(fp, what.Data(), inclist);
55 }
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 /// Chop the name by replacing the ending (before a potential extension) with
59 /// a md5 summary of the name.
60 
62 {
63  Ssiz_t len = name.Length();
64  Bool_t has_extension = name.EndsWith(".h");
65  if (has_extension)
66  len -= 2;
67  if (len >= limit) {
68  if (has_extension) {
69  name.Remove(name.Length()-2);
70  }
71  TMD5 md;
72  md.Update((const UChar_t*)name.Data(),name.Length());
73  md.Final();
74  name.Remove( limit - 32 - 5); // Chop the part longer than 255 and keep space for the md5 and leave space for an extension
75  name.Append( md.AsString() );
76  if (has_extension) {
77  name.Append( ".h" );
78  }
79  }
80 
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Return the header name containing the description of name.
85 
86 TString TMakeProject::GetHeaderName(const char *in_name, const TList *extrainfos, Bool_t includeNested)
87 {
89  std::string strname( TClassEdit::GetLong64_Name( in_name ) );
90  const char *name = strname.c_str();
91  Int_t len = strlen(name);
92  Int_t nest = 0;
93  for (Int_t i = 0; i < len; ++i) {
94  switch (name[i]) {
95  case '<':
96  ++nest;
97  result.Append('_');
98  break;
99  case '>':
100  --nest;
101  result.Append('_');
102  break;
103  case ':':
104  if (nest == 0 && name[i+1] == ':') {
105  TString nsname(name, i);
106  TClass *cl = gROOT->GetClass(nsname);
107  Bool_t definedInParent = !includeNested && cl && (cl->Size() != 0 || (cl->Size()==0 && !cl->HasInterpreterInfo() /*empty 'base' class on file*/));
108  if (!definedInParent && cl==0 && extrainfos!=0) {
109  TStreamerInfo *clinfo = (TStreamerInfo*)extrainfos->FindObject(nsname);
110  if (clinfo && clinfo->GetClassVersion() == -5) {
111  definedInParent = kTRUE;
112  }
113  }
114  if (definedInParent) {
115  // The requested class is actually nested inside
116  // the class whose name we already 'copied' to
117  // result. The declaration will be in the same
118  // header file as the outer class.
119  if (strcmp(name + strlen(name) - 2, ".h") == 0) {
120  result.Append(".h");
121  }
122  ChopFileName(result,127);
123  return result;
124  }
125 #ifndef WIN32
126  }
127  result.Append('_');
128 #else
129  }
130  if (name[i+1] == '/') {
131  // don't replace the colon ':' in the case it's part of the drive name in a Windows path
132  // e.g. don't convert from "c:/root/..." to "c_/root/..."
133  result.Append(name[i]);
134  } else {
135  result.Append('_');
136  }
137 #endif
138  break;
139  case ',':
140  case '*':
141  case '[':
142  case ']':
143  case ' ':
144  case '(':
145  case ')':
146  result.Append('_');
147  break;
148  case '/':
149  case '\\':
150  default:
151  result.Append(name[i]);
152  }
153  }
154  ChopFileName(result,127);
155  return result;
156 }
157 
158 ////////////////////////////////////////////////////////////////////////////////
159 /// Write the start of the class (forward) declaration.
160 /// If 'implementEmptyClass' is 3 then never add a #pragma
161 
162 UInt_t TMakeProject::GenerateClassPrefix(FILE *fp, const char *clname, Bool_t top, TString &protoname,
163  UInt_t *numberOfClasses, Int_t implementEmptyClass, Bool_t needGenericTemplate)
164 {
165  // First open the namespace (if any)
166  Int_t numberOfNamespaces = 0;
167  const char *fullname = clname;
168 
169  Bool_t istemplate = kFALSE;
170  if (strchr(clname, ':')) {
171  // We might have a namespace in front of the classname.
172  Int_t len = strlen(clname);
173  const char *name = clname;
174  UInt_t nest = 0;
175  for (Int_t cur = 0; cur < len; ++cur) {
176  switch (clname[cur]) {
177  case '<':
178  ++nest;
179  istemplate = kTRUE;
180  break;
181  case '>':
182  if (nest) --nest;
183  break;
184  case ':': {
185  if (nest == 0 && clname[cur+1] == ':') {
186  // We have a scope
187  TString nsname(clname, cur);
188  TClass *cl = gROOT->GetClass(nsname);
189  if (top) {
190  if (cl == 0 || (cl && cl->Size() == 0)) {
191  TString last(name, cur - (name - clname));
192  if ((numberOfClasses == 0 || *numberOfClasses == 0) && strchr(last.Data(), '<') == 0) {
193  fprintf(fp, "namespace %s {\n", last.Data());
194  ++numberOfNamespaces;
195  } else {
196  TString headername(GetHeaderName(last,0));
197  fprintf(fp, "#ifndef %s_h\n", headername.Data());
198  fprintf(fp, "#define %s_h\n", headername.Data());
199  GenerateClassPrefix(fp, last.Data(), top, protoname, 0);
200  fprintf(fp, "{\n");
201  fprintf(fp, "public:\n");
202  if (numberOfClasses) ++(*numberOfClasses);
203  istemplate = kFALSE;
204  }
205  name = clname + cur + 2;
206  }
207  } else {
208  istemplate = kFALSE;
209  name = clname + cur + 2;
210  }
211  }
212  break;
213  }
214  }
215  }
216  clname = name;
217  } else {
218  istemplate = strstr(clname, "<") != 0;
219  }
220 
221  protoname = clname;
222 
223  if (implementEmptyClass==1) {
224  TString headername(GetHeaderName(fullname,0));
225  fprintf(fp, "#ifndef %s_h\n", headername.Data());
226  fprintf(fp, "#define %s_h\n", headername.Data());
227  }
228  if (istemplate) {
229  std::vector<const char*> argtype;
230 
231  Ssiz_t pos = protoname.First('<');
232  UInt_t nparam = 1;
233  if (pos != kNPOS) {
234  if (isdigit(protoname[pos+1])) {
235  argtype.push_back("int");
236  } else {
237  argtype.push_back("typename");
238  }
239  UInt_t nest = 0;
240  for (Ssiz_t i = pos; i < protoname.Length(); ++i) {
241  switch (protoname[i]) {
242  case '<':
243  ++nest;
244  break;
245  case '>':
246  if (nest) --nest;
247  break;
248  case ',':
249  if (nest == 1) {
250  if (isdigit(protoname[i+1])) {
251  argtype.push_back("int");
252  } else {
253  argtype.push_back("typename");
254  }
255  ++nparam;
256  }
257  break;
258  }
259  }
260  protoname.Remove(pos);
261  }
262 
263  // Forward declaration of template.
264  fprintf(fp, "template <");
265  for (UInt_t p = 0; p < nparam; ++p) {
266  if (p >= argtype.size() ) {
267  fprintf(fp, "/* missing */ T%d", p);
268  } else {
269  fprintf(fp, "%s T%d", argtype[p], p);
270  }
271  if (p != (nparam - 1)) fprintf(fp, ", ");
272  }
273  if (needGenericTemplate) {
274  fprintf(fp, "> class %s", protoname.Data());
275  } else {
276  fprintf(fp, "> class %s;\n", protoname.Data());
277  fprintf(fp, "template <> ");
278  }
279  }
280 
281  if (implementEmptyClass) {
282  if (istemplate) {
283  if (!needGenericTemplate) {
284  fprintf(fp, "class %s", clname);
285  }
286  fprintf(fp, " {\n");
287  if (numberOfClasses) ++(*numberOfClasses);
288  fprintf(fp, "public:\n");
289  fprintf(fp, "operator int() { return 0; };\n");
290  } else {
291  fprintf(fp, "enum %s { kDefault_%s };\n", clname, clname);
292  // The nesting space of this class may not be #pragma declared (and without it
293  // the dictionary is broken), so for now skip those
294  if (implementEmptyClass==1) {
295  if (strchr(fullname, ':') == 0) {
296  // yes this is too aggressive, this needs to be fixed properly by moving the #pragma out of band.
297  fprintf(fp, "#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", fullname);
298  }
299  fprintf(fp, "#endif\n");
300  }
301  }
302  } else {
303  if (!(istemplate && needGenericTemplate)) {
304  fprintf(fp, "class %s", clname);
305  }
306  }
307  return numberOfNamespaces;
308 }
309 
310 ////////////////////////////////////////////////////////////////////////////////
311 /// Generate an empty StreamerInfo for the given type (no recursion) if it is not
312 /// not known in the list of class.
313 ///
314 /// If the type itself is a template,
315 /// we mark it with version 1 (a class) otherwise we mark it as version -3 (an enum).
316 
317 void TMakeProject::GenerateMissingStreamerInfo(TList *extrainfos, const char *clname, Bool_t iscope)
318 {
319  if (!TClassEdit::IsStdClass(clname) && !TClass::GetClass(clname) && gROOT->GetType(clname) == 0) {
320 
321  TStreamerInfo *info = (TStreamerInfo*)extrainfos->FindObject(clname);
322  if (!info) {
323  // The class does not exist, let's create it
324  TStreamerInfo *newinfo = new TStreamerInfo();
325  newinfo->SetName(clname);
326  if (clname[strlen(clname)-1]=='>') {
327  newinfo->SetTitle("Generated by MakeProject as an empty class template instantiation");
328  newinfo->SetClassVersion(1);
329  } else if (iscope) {
330  newinfo->SetTitle("Generated by MakeProject as a namespace");
331  newinfo->SetClassVersion(-4 /*namespace*/);
332  } else {
333  newinfo->SetTitle("Generated by MakeProject as an enum");
334  newinfo->SetClassVersion(-3 /*enum*/);
335  }
336  extrainfos->Add(newinfo);
337  } else {
338  if (iscope) {
339  if (info->GetClassVersion() == -3) {
340  // This was marked as an enum but is also used as a scope,
341  // so it was actually a class.
342  info->SetTitle("Generated by MakeProject as an empty class");
343  info->SetClassVersion(-5 /*class*/);
344  }
345  } else {
346  if (info->GetClassVersion() == -4) {
347  // This was marked as a 'namespace' but it is also used as a template parameter,
348  // so it was actually a class.
349  info->SetTitle("Generated by MakeProject as an empty class");
350  info->SetClassVersion(-5 /*class*/);
351  }
352  }
353  }
354  }
355 }
356 
357 ////////////////////////////////////////////////////////////////////////////////
358 /// Generate an empty StreamerInfo for types that are used in templates parameters
359 /// but are not known in the list of class.
360 ///
361 /// If the type itself is a template, we mark it with version 1 (a class)
362 /// otherwise we mark it as version -3 (an enum).
363 
364 void TMakeProject::GenerateMissingStreamerInfos(TList *extrainfos, const char *clname)
365 {
366  UInt_t len = strlen(clname);
367  UInt_t nest = 0;
368  UInt_t last = 0;
369  //Bool_t istemplate = kFALSE; // mark whether the current right most entity is a class template.
370 
371  for (UInt_t i = 0; i < len; ++i) {
372  switch (clname[i]) {
373  case ':':
374  if (nest == 0 && clname[i+1] == ':') {
375  TString incName(clname, i);
376  GenerateMissingStreamerInfo(extrainfos, incName.Data(), kTRUE);
377  //istemplate = kFALSE;
378  }
379  break;
380  case '<':
381  ++nest;
382  if (nest == 1) last = i + 1;
383  break;
384  case '>':
385  if (nest == 0) return; // The name is not well formed, give up.
386  --nest; /* intentional fall through to the next case */
387  case ',':
388  if ((clname[i] == ',' && nest == 1) || (clname[i] == '>' && nest == 0)) {
389  TString incName(clname + last, i - last);
390  incName = TClassEdit::ShortType(incName.Data(), TClassEdit::kDropTrailStar | TClassEdit::kLong64);
391  if (clname[i] == '>' && nest == 1) incName.Append(">");
392 
393  if (isdigit(incName[0])) {
394  // Not a class name, nothing to do.
395  } else {
396  GenerateMissingStreamerInfos(extrainfos,incName.Data());
397  }
398  last = i + 1;
399  }
400  }
401  }
402  GenerateMissingStreamerInfo(extrainfos,TClassEdit::ShortType(clname, TClassEdit::kDropTrailStar | TClassEdit::kLong64).c_str(),kFALSE);
403 }
404 
405 ////////////////////////////////////////////////////////////////////////////////
406 /// Generate an empty StreamerInfo for types that are used in templates parameters
407 /// but are not known in the list of class.
408 ///
409 /// If the type itself is a template,
410 /// we mark it with version 1 (a class) otherwise we mark it as version -3 (an enum).
411 
413 {
414  if (element->IsBase()) {
415  TClass *elemCl = element->GetClassPointer();
416  if (elemCl) GenerateMissingStreamerInfos(extrainfos,elemCl->GetName());
417  else GenerateMissingStreamerInfos(extrainfos,element->GetTypeName());
418  } else {
419  GenerateMissingStreamerInfos(extrainfos,element->GetTypeName());
420  }
421 
422 }
423 
424 ////////////////////////////////////////////////////////////////////////////////
425 /// Insert a (complete) forward declaration for the class 'clname'
426 
427 UInt_t TMakeProject::GenerateForwardDeclaration(FILE *fp, const char *clname, char *inclist, Bool_t implementEmptyClass, Bool_t needGenericTemplate, const TList *extrainfos)
428 {
429  UInt_t ninc = 0;
430 
431  if (strchr(clname, '<')) {
432  ninc += GenerateIncludeForTemplate(fp, clname, inclist, kTRUE, extrainfos);
433  }
434  TString protoname;
435  UInt_t numberOfClasses = 0;
436  UInt_t numberOfNamespaces = GenerateClassPrefix(fp, clname, kTRUE, protoname, &numberOfClasses, implementEmptyClass, needGenericTemplate);
437 
438  if (!implementEmptyClass) fprintf(fp, ";\n");
439  for (UInt_t i = 0;i < numberOfClasses;++i) {
440  fprintf(fp, "}; // end of class.\n");
441  fprintf(fp, "#endif\n");
442  }
443  for (UInt_t i = 0;i < numberOfNamespaces;++i) {
444  fprintf(fp, "} // end of namespace.\n");
445  }
446 
447  return ninc;
448 }
449 
450 ////////////////////////////////////////////////////////////////////////////////
451 /// Add to the header file, the \#include needed for the argument of
452 /// this template.
453 
454 UInt_t TMakeProject::GenerateIncludeForTemplate(FILE *fp, const char *clname, char *inclist, Bool_t forward, const TList *extrainfos)
455 {
456  UInt_t ninc = 0;
457  UInt_t len = strlen(clname);
458  UInt_t nest = 0;
459  UInt_t last = 0;
460 
461 
462  for (UInt_t i = 0; i < len; ++i) {
463  switch (clname[i]) {
464  case '<':
465  ++nest;
466  if (nest == 1) last = i + 1;
467  break;
468  case '>':
469  if (nest==0) return ninc; // the name is not well formed, give up.
470  --nest; /* intentional fall through to the next case */
471  case ',':
472  if ((clname[i] == ',' && nest == 1) || (clname[i] == '>' && nest == 0)) {
473  TString incName(clname + last, i - last);
474  incName = TClassEdit::ShortType(incName.Data(), TClassEdit::kDropTrailStar | TClassEdit::kLong64);
475  if (clname[i] == '>' && nest == 1) incName.Append(">");
476  Int_t stlType;
477  if (isdigit(incName[0])) {
478  // Not a class name, nothing to do.
479  } else if ((stlType = TClassEdit::IsSTLCont(incName))) {
480  const char *what = "";
481  switch (TMath::Abs(stlType)) {
482  case ROOT::kSTLvector:
483  what = "vector";
484  break;
485  case ROOT::kSTLlist:
486  what = "list";
487  break;
488  case ROOT::kSTLforwardlist:
489  what = "forward_list";
490  break;
491  case ROOT::kSTLdeque:
492  what = "deque";
493  break;
494  case ROOT::kSTLmap:
495  case ROOT::kSTLmultimap:
496  what = "map";
497  break;
498  case ROOT::kSTLunorderedmap:
499  case ROOT::kSTLunorderedmultimap:
500  what = "unordered_map";
501  break;
502  case ROOT::kSTLset:
503  case ROOT::kSTLmultiset:
504  what = "set";
505  break;
506  case ROOT::kSTLunorderedset:
507  case ROOT::kSTLunorderedmultiset:
508  what = "unordered_set";
509  break;
510  case ROOT::kSTLbitset:
511  what = "bitset";
512  break;
513  default:
514  what = "undetermined_stl_container";
515  break;
516  }
517  AddInclude(fp, what, kTRUE, inclist);
518  fprintf(fp, "namespace std {} using namespace std;\n");
519  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
520  } else if (strncmp(incName.Data(), "pair<", strlen("pair<")) == 0) {
521  AddInclude(fp, "utility", kTRUE, inclist);
522  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
523  } else if (strncmp(incName.Data(), "auto_ptr<", strlen("auto_ptr<")) == 0) {
524  AddInclude(fp, "memory", kTRUE, inclist);
525  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
526  } else if (TClassEdit::IsStdClass(incName)) {
527  // Do nothing.
528  } else {
529  TClass *cl = gROOT->GetClass(incName);
530  if (!forward && cl) {
531  if (cl->HasInterpreterInfo()) {
532  // We have the real dictionary for this class.
533 
534  const char *include = cl->GetDeclFileName();
535  if (include && include[0]) {
536 
537  if (strncmp(include, "include/", 8) == 0) {
538  include += 8;
539  }
540  if (strncmp(include, "include\\", 9) == 0) {
541  include += 9;
542  }
543  TMakeProject::AddInclude(fp, include, kFALSE, inclist);
544  }
545  GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
546  } else {
547  incName = GetHeaderName(incName,extrainfos);
548  incName.Append(".h");
549  AddInclude(fp, incName, kFALSE, inclist);
550  }
551  } else if (incName.Length() && incName[0] != ' ' && gROOT->GetType(incName) == 0) {
552  Bool_t emptyclass = !cl;
553  if (emptyclass && extrainfos) {
554  TStreamerInfo *info = (TStreamerInfo*)extrainfos->FindObject(incName);
555  if (info && info->GetClassVersion() == -5) {
556  emptyclass = kFALSE;
557  }
558  }
559  GenerateForwardDeclaration(fp, incName, inclist, emptyclass, kFALSE, extrainfos);
560  }
561  }
562  last = i + 1;
563  }
564  }
565  }
566 
567  Int_t stlType = TClassEdit::IsSTLCont(clname);
568  if (stlType) {
569  std::vector<std::string> inside;
570  int nestedLoc;
571  TClassEdit::GetSplit( clname, inside, nestedLoc, TClassEdit::kLong64 );
572  Int_t stlkind = TClassEdit::STLKind(inside[0].c_str());
573  TClass *key = TClass::GetClass(inside[1].c_str());
574  if (key) {
575  TString what;
576  switch (stlkind) {
577  case ROOT::kSTLmap:
578  case ROOT::kSTLmultimap: {
579  what = "pair<";
580  what += UpdateAssociativeToVector( inside[1].c_str() );
581  what += ",";
582  what += UpdateAssociativeToVector( inside[2].c_str() );
583  what += " >";
584  what.ReplaceAll("std::","");
585  // Only ask for it if needed.
586  TClass *paircl = TClass::GetClass(what.Data());
587  if (paircl == 0 || !paircl->HasInterpreterInfo()) {
588  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", what.Data()), inclist);
589  }
590  break;
591  }
592  }
593  }
594  }
595 
596  if (strncmp(clname, "auto_ptr<", strlen("auto_ptr<")) == 0) {
597  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", clname), inclist);
598  }
599  return ninc;
600 }
601 
602 
603 ////////////////////////////////////////////////////////////////////////////////
604 /// Add to the header file anything that need to appear after the class
605 /// declaration (this includes some \#pragma link).
606 
607 void TMakeProject::GeneratePostDeclaration(FILE *fp, const TVirtualStreamerInfo *info, char *inclist)
608 {
609  TIter next(info->GetElements());
610  TStreamerElement *element;
611  while( (element = (TStreamerElement*)next()) ) {
612  Int_t stlType = TClassEdit::IsSTLCont(element->GetTypeName());
613  if (stlType) {
614  std::vector<std::string> inside;
615  int nestedLoc;
616  TClassEdit::GetSplit( element->GetTypeName(), inside, nestedLoc, TClassEdit::kLong64 );
617  Int_t stlkind = TClassEdit::STLKind(inside[0].c_str());
618  TClass *key = TClass::GetClass(inside[1].c_str());
619  TString what;
620  if (strncmp(inside[1].c_str(),"pair<",strlen("pair<"))==0) {
621  what = inside[1].c_str();
622  } else if (key) {
623  switch (stlkind) {
624  case ROOT::kSTLmap:
625  case ROOT::kSTLmultimap:
626  {
627  // Already done (see GenerateIncludeForTemplate
628  break;
629  }
630  default:
631  break;
632  }
633  }
634  if (what.Length()) {
635  // Only ask for it if needed.
636  TClass *paircl = TClass::GetClass(what.Data());
637  if (paircl == 0 || !paircl->HasInterpreterInfo()) {
638  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n",what.Data()), inclist);
639  }
640  }
641  }
642  }
643 }
644 
645 ////////////////////////////////////////////////////////////////////////////////
646 /// If we have a map, multimap, set or multiset, plus unordered partners,
647 /// and the key is a class, we need to replace the
648 /// container by a vector since we don't have the
649 /// comparator function.
650 /// The 'name' is modified to return the change in the name,
651 /// if any.
652 
654 {
655  TString newname( name );
656 
657  if (strchr(name,'<')!=0) {
658  std::vector<std::string> inside;
659  int nestedLoc;
660  unsigned int narg = TClassEdit::GetSplit( name, inside, nestedLoc, TClassEdit::kLong64 );
661  if (nestedLoc) --narg;
662  Int_t stlkind = TMath::Abs(TClassEdit::STLKind(inside[0].c_str()));
663 
664  for(unsigned int i = 1; i<narg; ++i) {
665  inside[i] = UpdateAssociativeToVector( inside[i].c_str() );
666  }
667  // Remove default allocator if any.
668  static const char* allocPrefix = "std::allocator<";
669  static const unsigned int allocPrefixLen (strlen(allocPrefix));
670  switch (stlkind) {
671  case ROOT::kSTLvector:
672  case ROOT::kSTLlist:
673  case ROOT::kSTLforwardlist:
674  case ROOT::kSTLdeque:
675  if (narg>2 && strncmp(inside[2].c_str(),allocPrefix,allocPrefixLen)==0) {
676  --narg;
677  }
678  break;
679  case ROOT::kSTLset:
680  case ROOT::kSTLmultiset:
681  case ROOT::kSTLmap:
682  case ROOT::kSTLmultimap:
683  if (narg>4 && strncmp(inside[4].c_str(),allocPrefix,allocPrefixLen)==0) {
684  --narg;
685  }
686  break;
687  case ROOT::kSTLunorderedset:
688  case ROOT::kSTLunorderedmultiset:
689  if (narg>5 && strncmp(inside[5].c_str(),allocPrefix,allocPrefixLen)==0) {
690  --narg;
691  }
692  break;
693  case ROOT::kSTLunorderedmap:
694  case ROOT::kSTLunorderedmultimap:
695  if (narg>6 && strncmp(inside[6].c_str(),allocPrefix,allocPrefixLen)==0) {
696  --narg;
697  }
698  break;
699  }
700  if (stlkind!=0) {
701  TClass *key = TClass::GetClass(inside[1].c_str());
702 
703  if (key) {
704  // We only need to translate to a vector is the key is a class
705  // (for which we do not know the sorting).
706  std::string what;
707  switch ( stlkind ) {
708  case ROOT::kSTLmap:
709  case ROOT::kSTLunorderedmap:
710  case ROOT::kSTLmultimap:
711  case ROOT::kSTLunorderedmultimap: {
712  what = "std::pair<";
713  what += inside[1];
714  what += ",";
715  what += inside[2];
716  if (what[what.size()-1]=='>') {
717  what += " >";
718  } else {
719  what += ">";
720  }
721  inside.clear();
722  inside.push_back("std::vector");
723  inside.push_back(what);
724  narg = 2;
725  break;
726  }
727  case ROOT::kSTLset:
728  case ROOT::kSTLunorderedset:
729  case ROOT::kSTLmultiset:
730  case ROOT::kSTLunorderedmultiset:
731  inside[0] = "std::vector";
732  break;
733  }
734  }
735  if (strncmp(inside[0].c_str(),"std::",5) != 0) {
736  inside[0] = "std::" + inside[0];
737  }
738  } else {
739  static const char *stlnames[] = { "pair", "greater", "less", "allocator" };
740  for(unsigned int in = 0; in < sizeof(stlnames)/sizeof(stlnames[0]); ++in) {
741  if (strncmp( inside[0].c_str(), stlnames[in], strlen(stlnames[in])) == 0 ) {
742  inside[0] = "std::" + inside[0];
743  break;
744  }
745  }
746  }
747  newname = inside[0];
748  newname.Append("<");
749  newname.Append(inside[1]);
750  for(unsigned int j=2; j<narg; ++j) {
751  if (!inside[j].empty()) {
752  newname.Append(",");
753  newname.Append(inside[j]);
754  }
755  }
756  if (newname[newname.Length()-1]=='>') {
757  newname.Append(" >");
758  } else {
759  newname.Append(">");
760  }
761  if (nestedLoc) newname.Append(inside[nestedLoc]);
762  } else if ( newname == "string" ) {
763  newname = "std::string";
764  }
765  return newname;
766 }
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
static void GenerateMissingStreamerInfo(TList *extrainfos, const char *clname, Bool_t iscope)
Generate an empty StreamerInfo for the given type (no recursion) if it is not not known in the list o...
const char * GetDeclFileName() const
Definition: TClass.h:376
void Final()
MD5 finalization, ends an MD5 message-digest operation, writing the the message digest and zeroizing ...
Definition: TMD5.cxx:167
void Fatal(const char *location, const char *msgfmt,...)
static TString GetHeaderName(const char *name, const TList *extrainfos, Bool_t includeNested=kFALSE)
Return the header name containing the description of name.
const Ssiz_t kNPOS
Definition: RtypesCore.h:115
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:640
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
static void ChopFileName(TString &name, Int_t limit)
Chop the name by replacing the ending (before a potential extension) with a md5 summary of the name...
Bool_t HasInterpreterInfo() const
Definition: TClass.h:364
#define gROOT
Definition: TROOT.h:375
const char * AsString() const
Return message digest as string.
Definition: TMD5.cxx:220
Basic string class.
Definition: TString.h:129
int Int_t
Definition: RtypesCore.h:41
static void GeneratePostDeclaration(FILE *fp, const TVirtualStreamerInfo *info, char *inclist)
Add to the header file anything that need to appear after the class declaration (this includes some #...
bool Bool_t
Definition: RtypesCore.h:59
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:501
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2345
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
TString & Append(const char *cs)
Definition: TString.h:497
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2231
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:477
static UInt_t GenerateForwardDeclaration(FILE *fp, const char *clname, char *inclist, Bool_t implementEmptyClass, Bool_t needGenericTemplate, const TList *extrainfos)
Insert a (complete) forward declaration for the class &#39;clname&#39;.
static void AddInclude(FILE *fp, const char *header, Bool_t system, char *inclist)
Add an include statement, if it has not already been added.
A doubly linked list.
Definition: TList.h:43
void Update(const UChar_t *buf, UInt_t len)
Update TMD5 object to reflect the concatenation of another buffer full of bytes.
Definition: TMD5.cxx:108
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2332
unsigned int UInt_t
Definition: RtypesCore.h:42
static void AddUniqueStatement(FILE *fp, const char *statement, char *inclist)
Add an include statement, if it has not already been added.
Ssiz_t Length() const
Definition: TString.h:388
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5348
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:71
void SetClassVersion(Int_t vers)
static void GenerateMissingStreamerInfos(TList *extrainfos, TStreamerElement *element)
Generate an empty StreamerInfo for types that are used in templates parameters but are not known in t...
const Bool_t kFALSE
Definition: RtypesCore.h:92
static UInt_t GenerateIncludeForTemplate(FILE *fp, const char *clname, char *inclist, Bool_t forward, const TList *extrainfos)
Add to the header file, the #include needed for the argument of this template.
TString & Remove(Ssiz_t pos)
Definition: TString.h:621
int Ssiz_t
Definition: RtypesCore.h:63
virtual TObjArray * GetElements() const =0
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
Definition: NeuralNet.icc:544
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
Int_t GetClassVersion() const
static TString UpdateAssociativeToVector(const char *name)
If we have a map, multimap, set or multiset, plus unordered partners, and the key is a class...
const char * GetTypeName() const
virtual void Add(TObject *obj)
Definition: TList.h:77
double result[121]
unsigned char UChar_t
Definition: RtypesCore.h:34
Abstract Interface class describing Streamer information for one class.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:155
const Bool_t kTRUE
Definition: RtypesCore.h:91
static UInt_t GenerateClassPrefix(FILE *fp, const char *clname, Bool_t top, TString &protoname, UInt_t *numberOfClasses, Int_t implementEmptyClass=kFALSE, Bool_t needGenericTemplate=kFALSE)
Write the start of the class (forward) declaration.
const char * Data() const
Definition: TString.h:347