Logo ROOT  
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
16Helper 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
32void 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
46void TMakeProject::AddInclude(FILE *fp, const char *header, Bool_t system, char *inclist)
47{
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
86TString TMakeProject::GetHeaderName(const char *in_name, const TList *extrainfos, Bool_t includeNested)
87{
88 TString result;
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
162UInt_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
317void 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
364void 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);
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 }
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
427UInt_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
454UInt_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);
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;
489 what = "forward_list";
490 break;
491 case ROOT::kSTLdeque:
492 what = "deque";
493 break;
494 case ROOT::kSTLmap:
496 what = "map";
497 break;
500 what = "unordered_map";
501 break;
502 case ROOT::kSTLset:
504 what = "set";
505 break;
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 (TClassEdit::IsStdPair(incName)) {
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]);
573 TClass *key = TClass::GetClass(inside[1].c_str());
574 if (key) {
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 return ninc;
597}
598
599
600////////////////////////////////////////////////////////////////////////////////
601/// Add to the header file anything that need to appear after the class
602/// declaration (this includes some \#pragma link).
603
604void TMakeProject::GeneratePostDeclaration(FILE *fp, const TVirtualStreamerInfo *info, char *inclist)
605{
606 TIter next(info->GetElements());
607 TStreamerElement *element;
608 while( (element = (TStreamerElement*)next()) ) {
609 Int_t stlType = TClassEdit::IsSTLCont(element->GetTypeName());
610 if (stlType) {
611 std::vector<std::string> inside;
612 int nestedLoc;
613 TClassEdit::GetSplit( element->GetTypeName(), inside, nestedLoc, TClassEdit::kLong64 );
614 Int_t stlkind = TClassEdit::STLKind(inside[0]);
615 TClass *key = TClass::GetClass(inside[1].c_str());
617 if (TClassEdit::IsStdPair(inside[1])) {
618 what = inside[1].c_str();
619 } else if (key) {
620 switch (stlkind) {
621 case ROOT::kSTLmap:
623 {
624 // Already done (see GenerateIncludeForTemplate
625 break;
626 }
627 default:
628 break;
629 }
630 }
631 if (what.Length()) {
632 // Only ask for it if needed.
633 TClass *paircl = TClass::GetClass(what.Data());
634 if (paircl == 0 || !paircl->HasInterpreterInfo()) {
635 AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n",what.Data()), inclist);
636 }
637 }
638 }
639 }
640}
641
642////////////////////////////////////////////////////////////////////////////////
643/// If we have a map, multimap, set or multiset, plus unordered partners,
644/// and the key is a class, we need to replace the
645/// container by a vector since we don't have the
646/// comparator function.
647/// The 'name' is modified to return the change in the name,
648/// if any.
649
650static constexpr int str_length(const char* str)
651{
652 return *str ? 1 + str_length(str + 1) : 0;
653}
654
656{
657 TString newname( name );
658
659 constexpr auto auto_ptr_len = str_length("auto_ptr<");
660 if (strncmp(name, "auto_ptr<", auto_ptr_len) == 0) {
661 newname = "unique_ptr<";
662 newname += (name + auto_ptr_len);
663 } else if (strchr(name,'<')!=0) {
664 std::vector<std::string> inside;
665 int nestedLoc;
666 unsigned int narg = TClassEdit::GetSplit( name, inside, nestedLoc, TClassEdit::kLong64 );
667
668 Int_t stlkind = TMath::Abs(TClassEdit::STLKind(inside[0]));
669
670 for(unsigned int i = 1; i<narg; ++i) {
671 inside[i] = UpdateAssociativeToVector( inside[i].c_str() );
672 }
673
674 if (nestedLoc) narg = nestedLoc;
675
676 // Treat the trailing stars the same as nested loc (i.e. ends up, properly, tacking them up back at the end of the name)
677 if (!inside[narg-1].empty() && inside[narg-1][0] == '*')
678 narg = narg - 1;
679
680 // Remove default allocator if any.
681 static const char* allocPrefix = "std::allocator<";
682 static const unsigned int allocPrefixLen (strlen(allocPrefix));
683 switch (stlkind) {
684 case ROOT::kSTLvector:
685 case ROOT::kSTLlist:
687 case ROOT::kSTLdeque:
688 if (narg>2 && strncmp(inside[2].c_str(),allocPrefix,allocPrefixLen)==0) {
689 --narg;
690 }
691 break;
692 case ROOT::kSTLset:
694 case ROOT::kSTLmap:
696 if (narg>4 && strncmp(inside[4].c_str(),allocPrefix,allocPrefixLen)==0) {
697 --narg;
698 }
699 break;
702 if (narg>5 && strncmp(inside[5].c_str(),allocPrefix,allocPrefixLen)==0) {
703 --narg;
704 }
705 break;
708 if (narg>6 && strncmp(inside[6].c_str(),allocPrefix,allocPrefixLen)==0) {
709 --narg;
710 }
711 break;
712 }
713 if (stlkind!=0) {
714 TClass *key = TClass::GetClass(inside[1].c_str());
715
716 if (key) {
717 // We only need to translate to a vector is the key is a class
718 // (for which we do not know the sorting).
719 std::string what;
720 switch ( stlkind ) {
721 case ROOT::kSTLmap:
725 what = "std::pair<";
726 what += inside[1];
727 what += ",";
728 what += inside[2];
729 if (what[what.size()-1]=='>') {
730 what += " >";
731 } else {
732 what += ">";
733 }
734 inside.clear();
735 inside.push_back("std::vector");
736 inside.push_back(what);
737 narg = 2;
738 break;
739 }
740 case ROOT::kSTLset:
744 inside[0] = "std::vector";
745 break;
746 }
747 }
748 if (strncmp(inside[0].c_str(),"std::",5) != 0) {
749 inside[0] = "std::" + inside[0];
750 }
751 } else {
752 static const char *stlnames[] = { "pair", "greater", "less", "allocator" };
753 for(unsigned int in = 0; in < sizeof(stlnames)/sizeof(stlnames[0]); ++in) {
754 if (strncmp( inside[0].c_str(), stlnames[in], strlen(stlnames[in])) == 0 ) {
755 inside[0] = "std::" + inside[0];
756 break;
757 }
758 }
759 }
760 newname = inside[0];
761 newname.Append("<");
762 newname.Append(inside[1]);
763 for(unsigned int j=2; j<narg; ++j) {
764 if (!inside[j].empty()) {
765 newname.Append(",");
766 newname.Append(inside[j]);
767 }
768 }
769 if (newname[newname.Length()-1]=='>') {
770 newname.Append(" >");
771 } else {
772 newname.Append(">");
773 }
774 if (nestedLoc) newname.Append(inside[nestedLoc]);
775 } else if ( newname == "string" ) {
776 newname = "std::string";
777 }
778 return newname;
779}
const Ssiz_t kNPOS
Definition: RtypesCore.h:113
unsigned char UChar_t
Definition: RtypesCore.h:36
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
const Bool_t kTRUE
Definition: RtypesCore.h:89
void Fatal(const char *location, const char *msgfmt,...)
char name[80]
Definition: TGX11.cxx:109
static constexpr int str_length(const char *str)
If we have a map, multimap, set or multiset, plus unordered partners, and the key is a class,...
#define gROOT
Definition: TROOT.h:406
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
Bool_t HasInterpreterInfo() const
Definition: TClass.h:407
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5667
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition: TClass.cxx:3431
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:2948
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
const char * AsString() const
Return message digest as string.
Definition: TMD5.cxx:220
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 Final()
MD5 finalization, ends an MD5 message-digest operation, writing the the message digest and zeroizing ...
Definition: TMD5.cxx:167
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...
static TString GetHeaderName(const char *name, const TList *extrainfos, Bool_t includeNested=kFALSE)
Return the header name containing the description of name.
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.
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...
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 'clname'.
static void AddUniqueStatement(FILE *fp, const char *statement, char *inclist)
Add an include statement, if it has not already been added.
static void AddInclude(FILE *fp, const char *header, Bool_t system, char *inclist)
Add an include statement, if it has not already been added.
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.
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 #...
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.
static TString UpdateAssociativeToVector(const char *name)
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
const char * GetTypeName() const
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:46
void SetClassVersion(Int_t vers)
Int_t GetClassVersion() const
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:499
const char * Data() const
Definition: TString.h:364
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
TString & Append(const char *cs)
Definition: TString.h:559
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:2311
Abstract Interface class describing Streamer information for one class.
virtual TObjArray * GetElements() const =0
@ kSTLbitset
Definition: ESTLType.h:37
@ kSTLmap
Definition: ESTLType.h:33
@ kSTLunorderedmultiset
Definition: ESTLType.h:43
@ kSTLset
Definition: ESTLType.h:35
@ kSTLmultiset
Definition: ESTLType.h:36
@ kSTLdeque
Definition: ESTLType.h:32
@ kSTLvector
Definition: ESTLType.h:30
@ kSTLunorderedmultimap
Definition: ESTLType.h:45
@ kSTLunorderedset
Definition: ESTLType.h:42
@ kSTLlist
Definition: ESTLType.h:31
@ kSTLforwardlist
Definition: ESTLType.h:41
@ kSTLunorderedmap
Definition: ESTLType.h:44
@ kSTLmultimap
Definition: ESTLType.h:34
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
Definition: TClassEdit.cxx:511
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition: TClassEdit.h:190
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
Definition: TClassEdit.cxx:887
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
@ kDropTrailStar
Definition: TClassEdit.h:76
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
Definition: NeuralNet.icc:546
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
static const char * what
Definition: stlLoader.cc:6