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