32using std::string, std::string_view, std::vector, std::set;
38struct ShuttingDownSignaler :
public T {
41 ShuttingDownSignaler() =
default;
42 ShuttingDownSignaler(T &&in) :
T(std::move(in)) {}
44 ~ShuttingDownSignaler()
46 if (gInterpreterHelper)
53void RemoveSpace(std::string_view &s)
55 while (!s.empty() && s[0] ==
' ')
63size_t StdLen(
const std::string_view
name)
66 if (
name.compare(0, 5,
"std::") == 0) {
71 if (gInterpreterHelper) {
72 for (
size_t i = 5; i <
name.length(); ++i) {
76 std::string scope(
name.data(), i);
80 static ShuttingDownSignaler<std::set<std::string>> gInlined;
81 static std::atomic_flag spinFlag = ATOMIC_FLAG_INIT;
86 isInlined = (gInlined.find(scope) != gInlined.end());
91 if (i + 1 <
name.length() &&
name[i + 1] ==
':') {
95 std::string scoperesult;
101 gInlined.insert(scope);
104 if (i + 1 <
name.length() &&
name[i + 1] ==
':') {
122void RemoveStd(std::string &
name,
size_t pos = 0)
126 name.erase(pos, len);
134void RemoveStd(std::string_view &
name)
136 size_t len = StdLen(
name);
138 name.remove_prefix(len);
145void RemoveScopeResolution(std::string &
name)
147 if (
name.length() > 2 &&
name[0] ==
':' &&
name[1] ==
':') {
158 if (0 == strncmp(clName,
"complex<", 8)) {
159 const char *clNamePlus8 = clName + 8;
160 if (0 == strcmp(
"float>", clNamePlus8)) {
163 if (0 == strcmp(
"double>", clNamePlus8)) {
166 if (0 == strcmp(
"int>", clNamePlus8)) {
169 if (0 == strcmp(
"long>", clNamePlus8)) {
184 if (
this == gInterpreterHelper)
185 gInterpreterHelper =
nullptr;
192 gInterpreterHelper = helper;
255 if (k<0) kind = -kind;
261 if(kind>2) kind = - kind;
292 if (
fElements[narg-1].empty() ==
false &&
296 || 0 ==
fElements[narg-1].compare(0,6,
"const*")
297 || 0 ==
fElements[narg-1].compare(0,6,
"const&")
298 || 0 ==
fElements[narg-1].compare(0,6,
"const[")
299 || 0 ==
fElements[narg-1].compare(
"const")
302 if ((mode&1)==0) tailLoc = narg-1;
304 else { assert(
fElements[narg-1].empty()); };
314 const int iall =
STLArgs(kind);
318 while(narg-1>iall) {
fElements.pop_back(); narg--;}
330 bool allocRemoved =
false;
336 if (narg-1 == iall+1) {
338 bool dropAlloc =
false;
392 if (!allocRemoved && narg-1 == iall+1) {
396 if (narg-1 == iall) narg--;
419 bool predRemoved =
false;
437 unsigned int offset = (0==strncmp(
"const ",
fElements[0].c_str(),6)) ? 6 : 0;
438 offset += (0==strncmp(
"std::",
fElements[0].c_str()+offset,5)) ? 5 : 0;
439 if (0 == strcmp(
fElements[0].c_str()+offset,
"__shared_ptr"))
442 static const std::string sharedPtrDef = std::to_string(__gnu_cxx::__default_lock_policy);
444 static const std::string sharedPtrDef = std::to_string(2);
454 for (
int i=1;i<narg; i++) {
460 unsigned int offset = (0==strncmp(
"const ",
fElements[i].c_str(),6)) ? 6 : 0;
471 if (gInterpreterHelper &&
474 if (!typeresult.empty() && typeresult !=
fElements[i]) {
482 unsigned int tailOffset = 0;
483 if (tailLoc &&
fElements[tailLoc].compare(0,5,
"const") == 0) {
496 int nargNonDefault = 0;
497 std::string nonDefName = answ;
499 std::string nameSuperLong =
fName;
500 if (gInterpreterHelper)
502 while (++nargNonDefault < narg) {
505 const char* closeTemplate =
" >";
506 if (nonDefName[nonDefName.length() - 1] !=
'>')
508 string nondef = nonDefName + closeTemplate;
509 if (gInterpreterHelper &&
512 if (nargNonDefault>1) nonDefName +=
",";
515 if (nargNonDefault < narg)
516 narg = nargNonDefault;
520 {
for (
int i=1;i<narg-1; i++) { answ +=
fElements[i]; answ+=
",";} }
521 if (narg>1) { answ +=
fElements[narg-1]; }
524 if ( answ.at(answ.size()-1) ==
'>') {
536 if (tailLoc) answ +=
fElements[tailLoc].c_str()+tailOffset;
552 if (type.length() == 0)
555 if (type.compare(0,6,
"const ")==0) { offset += 6; }
556 offset += StdLen(type.substr(offset));
557 const auto len = type.length() - offset;
562 static const char *stls[] =
563 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
564 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",
nullptr};
565 static const size_t stllen[] =
566 { 3, 6, 4, 5, 3, 8, 3, 8, 6,
567 12, 13, 18, 13, 18, 0};
583 for (
int k = 1; stls[k]; ++k) {
584 if (len == stllen[k]) {
585 if (type.compare(offset, len, stls[k]) == 0)
589 if (type.compare(offset, len,
"ROOT::VecOps::RVec") == 0)
599 static const char stln[] =
601 { 1, 1, 1, 1, 3, 3, 2, 2, 1,
604 assert(std::size_t(kind) <
sizeof(stln) &&
"index is out of bounds");
614 for(
size_t i = 0; i < full.length(); ++i) {
616 case '<': { ++level;
break; }
618 if (level == 0)
return i;
623 if (level == 0)
return i;
629 return full.length();
636 return pos +
findNameEnd( {full.data()+pos,full.length()-pos} );
645 string_view
a( allocname );
648 constexpr auto length = std::char_traits<char>::length;
649 constexpr static int clalloclen = length(
"class ");
650 if (
a.compare(0,clalloclen,
"class ") == 0) {
651 a.remove_prefix(clalloclen);
655 if (
a==
"alloc")
return true;
656 if (
a==
"__default_alloc_template<true,0>")
return true;
657 if (
a==
"__malloc_alloc_template<0>")
return true;
659 constexpr static int alloclen = length(
"allocator<");
660 if (
a.compare(0,alloclen,
"allocator<") != 0) {
663 a.remove_prefix(alloclen);
668 string_view k = classname;
671 if (
a.compare(0,k.length(),k) != 0) {
675 std::string valuepart;
678 std::string norm_value;
681 if (valuepart != norm_value) {
684 a.remove_prefix(end);
686 a.remove_prefix(k.length());
691 if (
a.compare(0, 1,
">") != 0) {
703 const char *keyclassname,
704 const char *valueclassname)
706 if (
IsDefAlloc(allocname,keyclassname))
return true;
708 string_view
a( allocname );
712 constexpr auto length = std::char_traits<char>::length;
713 constexpr static int alloclen = length(
"allocator<");
714 if (
a.compare(0,alloclen,
"allocator<") != 0) {
717 a.remove_prefix(alloclen);
722 constexpr static int pairlen = length(
"pair<");
723 if (
a.compare(0,pairlen,
"pair<") != 0) {
726 a.remove_prefix(pairlen);
728 const static int constlen = strlen(
"const");
729 if (
a.compare(0,constlen+1,
"const ") == 0) {
730 a.remove_prefix(constlen+1);
736 string_view k = keyclassname;
738 if (k.compare(0,constlen+1,
"const ") == 0) {
739 k.remove_prefix(constlen+1);
742 if (
a.compare(0,k.length(),k) != 0) {
746 std::string alloc_keypart;
749 std::string norm_key;
752 if (alloc_keypart != norm_key) {
753 if ( norm_key[norm_key.length()-1] ==
'*' ) {
757 norm_key +=
" const";
759 if (alloc_keypart != norm_key) {
763 a.remove_prefix(end);
766 a.remove_prefix(k.length());
768 if (
a.compare(0, constlen,
"const") == 0) {
769 a.remove_prefix(constlen);
779 string_view
v = valueclassname;
782 if (
a.compare(0,
v.length(),
v) != 0) {
786 std::string valuepart;
789 std::string norm_value;
792 if (valuepart != norm_value) {
795 a.remove_prefix(end);
797 a.remove_prefix(
v.length());
802 if (
a.compare(0, 1,
">") != 0) {
813static bool IsDefElement(
const char *elementName,
const char* defaultElementName,
const char *classname)
815 string c = elementName;
817 size_t pos = StdLen(
c);
819 const int elementlen = strlen(defaultElementName);
820 if (
c.compare(pos,elementlen,defaultElementName) != 0) {
825 string k = classname;
826 if (
c.compare(pos,k.length(),k) != 0) {
835 std::string norm_key;
838 if (keypart != norm_key) {
846 if (
c.compare(pos,1,
">")!=0 &&
c.compare(pos,2,
" >")!=0) {
897 norm_name = std::string(
name);
906 if (gInterpreterHelper) {
914 std::string typeresult;
916 if (!typeresult.empty()) {
917 norm_name = typeresult;
929 std::string first, second;
932 norm_name = splitname.
fElements[0] +
"<" + first +
"," + second;
933 if (!second.empty() && second.back() ==
'>')
943 RemoveScopeResolution(norm_name);
945 if (gInterpreterHelper) {
947 std::string typeresult;
951 if (!typeresult.empty()) {
959 RemoveScopeResolution(norm_name);
981 static const char* longlong_s =
"long long";
982 static const char* ulonglong_s =
"unsigned long long";
983 static const unsigned int longlong_len = strlen(longlong_s);
984 static const unsigned int ulonglong_len = strlen(ulonglong_s);
986 string result = original;
989 while( (pos = result.find(ulonglong_s,pos) ) >=0 ) {
990 result.replace(pos, ulonglong_len,
"ULong64_t");
993 while( (pos = result.find(longlong_s,pos) ) >=0 ) {
994 result.replace(pos, longlong_len,
"Long64_t");
1004 const char *lastPos = original;
1007 for(
auto cursor = original; *cursor !=
'\0'; ++cursor) {
1008 if ( *cursor ==
'<' || *cursor ==
'(') ++depth;
1009 else if ( *cursor ==
'>' || *cursor ==
')' ) --depth;
1010 else if ( *cursor ==
':' ) {
1011 if (depth==0 && *(cursor+1) ==
':' && *(cursor+2) !=
'\0') {
1026 const char *t = full.c_str();
1027 const unsigned int tlen( full.size() );
1029 const char *starloc = t + tlen - 1;
1030 bool hasconst =
false;
1031 if ( (*starloc)==
't'
1032 && (starloc-t) > 4 && 0 == strncmp((starloc-4),
"const",5)
1033 && ( (*(starloc-5)) ==
' ' || (*(starloc-5)) ==
'*' || (*(starloc-5)) ==
'&'
1034 || (*(starloc-5)) ==
'>' || (*(starloc-5)) ==
']') ) {
1037 if ((*starloc-1)==
' ') {
1043 if ( hasconst || (*starloc)==
'*' || (*starloc)==
'&' || (*starloc)==
']' ) {
1044 bool isArray = ( (*starloc)==
']' );
1045 while( t<=(starloc-1) && ((*(starloc-1))==
'*' || (*(starloc-1))==
'&' || (*(starloc-1))==
't' || isArray)) {
1048 isArray = ! ( (*starloc)==
'[' );
1049 }
else if ( (*(starloc-1))==
't' ) {
1050 if ( (starloc-1-t) > 5 && 0 == strncmp((starloc-5),
"const",5)
1051 && ( (*(starloc-6)) ==
' ' || (*(starloc-6)) ==
'*' || (*(starloc-6)) ==
'&'
1052 || (*(starloc-6)) ==
'>' || (*(starloc-6)) ==
']')) {
1063 if ((*(starloc-1))==
' ') {
1068 const unsigned int starlen = strlen(starloc);
1069 full.erase(tlen-starlen,starlen);
1070 }
else if (hasconst) {
1072 const unsigned int starlen = strlen(starloc);
1073 full.erase(tlen-starlen,starlen);
1093 if (strlen(type)==0)
return 0;
1095 int cleantypeMode = 1 ;
1104 bool isString =
false;
1105 bool isStdString =
false;
1106 bool isConst =
false;
1107 size_t prefix_offset = 0;
1109 if (full.compare(prefix_offset, 6,
"const ") == 0) {
1110 prefix_offset += isConst =
true;
1112 if (full.compare(prefix_offset, 5,
"std::") == 0) {
1116 if (full.compare(prefix_offset, 9,
"__cxx11::") == 0) {
1119 if (full.compare(prefix_offset, 17,
"basic_string<char") == 0) {
1121 prefix_offset += 17;
1125 size_t offset = prefix_offset;
1126 if ( full[offset] ==
'>' ) {
1128 }
else if (full[offset] ==
',') {
1130 if (full.compare(offset, 5,
"std::") == 0) {
1133 constexpr auto char_traits_s =
"char_traits<char>";
1136 static constexpr unsigned int char_traits_len = std::char_traits<char>::length(char_traits_s);
1137 if (full.compare(offset, char_traits_len, char_traits_s) == 0) {
1138 offset += char_traits_len;
1139 if ( full[offset] ==
'>') {
1141 }
else if (full[offset] ==
' ' && full[offset+1] ==
'>') {
1144 }
else if (full[offset] ==
',') {
1146 if (full.compare(offset, 5,
"std::") == 0) {
1149 static const char* allocator_s =
"allocator<char>";
1150 static const unsigned int allocator_len = strlen(allocator_s);
1151 if (full.compare(offset, allocator_len, allocator_s) == 0) {
1152 offset += allocator_len;
1153 if ( full[offset] ==
'>') {
1155 }
else if (full[offset] ==
' ' && full[offset+1] ==
'>') {
1176 output.push_back(
string());
1178 if (isStdString && !(mode &
kDropStd)) {
1179 output.push_back(
"const std::string");
1181 output.push_back(
"const string");
1184 if (isStdString && !(mode &
kDropStd)) {
1185 output.push_back(
"std::string");
1187 output.push_back(
"string");
1190 if (offset < full.length()) {
1193 string right( full.substr(offset) );
1196 output.back().append(right.c_str()+1);
1197 output.push_back(stars);
1199 output.push_back(
"");
1201 return output.size();
1207 unsigned int offset = (0==strncmp(
"const ",full.c_str(),6)) ? 6 : 0;
1208 RemoveStd( full, offset );
1212 if ( !full.empty() ) {
1216 const char *
c = strchr(full.c_str(),
'<');
1219 output.push_back(
string(full,0,
c - full.c_str()));
1221 const char *cursor =
c + 1;
1223 int parenthesis = 0;
1224 for ( ; *cursor !=
'\0' && !(level == 0 && parenthesis == 0 && *cursor ==
'>'); ++cursor) {
1225 if (*cursor ==
'(') {
1228 }
else if (*cursor ==
')') {
1235 case '<': ++level;
break;
1236 case '>': --level;
break;
1239 output.push_back(std::string(
c+1,cursor));
1246 if (*(cursor-1) ==
' ') {
1247 output.push_back(std::string(
c+1,cursor-1));
1249 output.push_back(std::string(
c+1,cursor));
1252 if (*(cursor+1)==
':') {
1255 nestedLoc = output.size();
1256 output.push_back((cursor+1));
1258 }
else if (level >= 0) {
1260 output.push_back(std::string(
c+1,cursor));
1264 output.push_back(
string());
1265 output.push_back(full);
1268 if (!output.empty()) output.push_back(stars);
1269 return output.size();
1291 constexpr static std::array<const char *, 3> remove{
"class",
"const",
"volatile"};
1292 constexpr static auto lengths = []()
constexpr {
1293 std::array<std::size_t, std::size(remove)>
ret{};
1294 for (std::size_t i = 0; i < remove.size(); i++)
1295 ret[i] = std::char_traits<char>::length(remove[i]);
1300 result.reserve(strlen(typeDesc)*2);
1302 std::vector<char> parensStack;
1305 for(
c=typeDesc;*
c;
c++) {
1308 if (!isalnum(
c[ 1]) &&
c[ 1] !=
'_')
continue;
1310 if (kbl && (mode>=2 || parensStack.empty())) {
1312 size_t n = (mode) ? std::size(remove) : 1;
1315 for (
size_t k = 0; k <
n; k++) {
1316 auto rlen = lengths[k];
1319 if (strncmp(remove[k],
c,rlen))
continue;
1322 if (isalnum(
c[rlen]) ||
c[rlen]==
'_' ||
c[rlen]==
'$')
continue;
1324 c+=rlen-1; done = 1;
break;
1329 kbl = (!isalnum(
c[ 0]) &&
c[ 0]!=
'_' &&
c[ 0]!=
'$' &&
c[0]!=
'[' &&
c[0]!=
']' &&
c[0]!=
'-' &&
c[0]!=
'@');
1333 if (*
c ==
'<' || *
c ==
'(')
1334 parensStack.push_back(*
c);
1336 if (parensStack.empty() && !isalnum(*
c)) {
1337 if (!strchr(
"*&:._$ []-@",*
c))
break;
1341 if (
c[0]==
'>' && result.size() && result[result.size()-1]==
'>') result+=
" ";
1345 if (*
c ==
'>' && !parensStack.empty() && parensStack.back() ==
'<')
1346 parensStack.pop_back();
1347 else if (*
c ==
')' && !parensStack.empty() && parensStack.back() ==
'(')
1348 parensStack.pop_back();
1385 size_t len = strlen(type);
1386 if (len < 2 || strncmp(type+len-2,
"_t",2) != 0)
return false;
1388 unsigned char offset = 0;
1389 if (strncmp(type,
"const ",6)==0) { offset += 6; }
1390 static const char *names[] = {
"CallFunc_t",
"ClassInfo_t",
"BaseClassInfo_t",
1391 "DataMemberInfo_t",
"FuncTempInfo_t",
"MethodInfo_t",
"MethodArgInfo_t",
1392 "TypeInfo_t",
"TypedefInfo_t",
nullptr};
1394 for(
int k=1;names[k];k++) {
if (strcmp(type+offset,names[k])==0)
return true;}
1403 size_t offset = StdLen(classname);
1404 if ( strncmp(classname+offset,
"bitset<",std::char_traits<char>::length(
"bitset<"))==0)
return true;
1422 if (type.compare(0,6,
"const ",6) == 0)
1423 type.remove_prefix(6);
1425 while(type[type.length()-1]==
'*' ||
1426 type[type.length()-1]==
'&' ||
1427 type[type.length()-1]==
' ') {
1428 type.remove_suffix(1);
1441 auto pos = type.find(
'<');
1445 for (
decltype(type.length()) level = 1;
c < type.length(); ++
c) {
1446 if (type[
c] ==
'<') ++level;
1447 if (type[
c] ==
'>') --level;
1448 if (level == 0)
break;
1450 if (
c != (type.length()-1) ) {
1454 return STLKind(type.substr(0,pos));
1470 if (!strchr(type,
'<'))
return 0;
1481 constexpr auto length = std::char_traits<char>::length;
1482 classname += StdLen( classname );
1483 if ( strcmp(classname,
"string")==0 )
return true;
1484 if ( strncmp(classname,
"bitset<",length(
"bitset<"))==0)
return true;
1485 if (
IsStdPair(classname) )
return true;
1486 if ( strcmp(classname,
"allocator")==0)
return true;
1487 if ( strncmp(classname,
"allocator<",length(
"allocator<"))==0)
return true;
1488 if ( strncmp(classname,
"greater<",length(
"greater<"))==0)
return true;
1489 if ( strncmp(classname,
"less<",length(
"less<"))==0)
return true;
1490 if ( strncmp(classname,
"equal_to<",length(
"equal_to<"))==0)
return true;
1491 if ( strncmp(classname,
"hash<",length(
"hash<"))==0)
return true;
1492 if ( strncmp(classname,
"auto_ptr<",length(
"auto_ptr<"))==0)
return true;
1494 if ( strncmp(classname,
"vector<",length(
"vector<"))==0)
return true;
1495 if ( strncmp(classname,
"list<",length(
"list<"))==0)
return true;
1496 if ( strncmp(classname,
"forward_list<",length(
"forward_list<"))==0)
return true;
1497 if ( strncmp(classname,
"deque<",length(
"deque<"))==0)
return true;
1498 if ( strncmp(classname,
"map<",length(
"map<"))==0)
return true;
1499 if ( strncmp(classname,
"multimap<",length(
"multimap<"))==0)
return true;
1500 if ( strncmp(classname,
"set<",length(
"set<"))==0)
return true;
1501 if ( strncmp(classname,
"multiset<",length(
"multiset<"))==0)
return true;
1502 if ( strncmp(classname,
"unordered_set<",length(
"unordered_set<"))==0)
return true;
1503 if ( strncmp(classname,
"unordered_multiset<",length(
"unordered_multiset<"))==0)
return true;
1504 if ( strncmp(classname,
"unordered_map<",length(
"unordered_map<"))==0)
return true;
1505 if ( strncmp(classname,
"unordered_multimap<",length(
"unordered_multimap<"))==0)
return true;
1506 if ( strncmp(classname,
"bitset<",length(
"bitset<"))==0)
return true;
1507 if ( strncmp(classname,
"ROOT::VecOps::RVec<",length(
"ROOT::VecOps::RVec<"))==0)
return true;
1526 unsigned int cursor,
1528 unsigned int start_of_type,
1529 unsigned int end_of_type,
1530 unsigned int mod_start_of_type,
1532 std::string &result)
1534 std::string type(modified && (mod_start_of_type < result.length()) ?
1535 result.substr(mod_start_of_type, string::npos)
1536 :
string(tname, start_of_type, end_of_type == 0 ? cursor - start_of_type : end_of_type - start_of_type));
1541 if (!typeresult.empty()) {
1544 result.replace(mod_start_of_type, string::npos,
1549 result += string(tname,0,start_of_type);
1550 if (constprefix && typeresult.compare(0,6,
"const ",6) == 0) {
1551 result += typeresult.substr(6,string::npos);
1553 result += typeresult;
1556 }
else if (modified) {
1557 result.replace(mod_start_of_type, string::npos,
1561 if (end_of_type != 0 && end_of_type!=cursor) {
1562 result += std::string(tname,end_of_type,cursor-end_of_type);
1569 if (end_of_type != 0 && end_of_type!=cursor) {
1570 result += std::string(tname,end_of_type,cursor-end_of_type);
1580 unsigned int &cursor,
1582 std::string &result)
1589 bool constprefix =
false;
1591 if (tname[cursor]==
' ') {
1594 result += string(tname,0,cursor);
1596 while (tname[cursor]==
' ') ++cursor;
1600 if (cursor < len && strncmp(tname+cursor,
"class ",6) == 0) {
1603 if (cursor < len && strncmp(tname+cursor,
"const ",6) == 0) {
1605 if (modified) result +=
"const ";
1609 if (len > 2 && cursor < len && strncmp(tname+cursor,
"::",2) == 0) {
1613 unsigned int start_of_type = cursor;
1614 unsigned int end_of_type = 0;
1615 unsigned int mod_start_of_type = result.length();
1616 unsigned int prevScope = cursor;
1617 for ( ; cursor<len; ++cursor) {
1618 switch (tname[cursor]) {
1620 if ((cursor+1)>=len || tname[cursor+1]!=
':') {
1622 if (modified) result += (tname+prevScope);
1627 scope = result.substr(mod_start_of_type, string::npos);
1628 scope += std::string(tname+prevScope,cursor-prevScope);
1630 scope = std::string(tname, start_of_type, cursor - start_of_type);
1632 std::string scoperesult;
1633 bool isInlined =
false;
1637 if (!scoperesult.empty()) {
1640 if (constprefix && scoperesult.compare(0,6,
"const ",6) != 0) mod_start_of_type -= 6;
1641 result.replace(mod_start_of_type, string::npos,
1646 mod_start_of_type = start_of_type;
1647 result += string(tname,0,start_of_type);
1649 result += scoperesult;
1652 }
else if (modified) {
1653 result += std::string(tname+prevScope,cursor+2-prevScope);
1657 if (modified) result += std::string(tname+prevScope,cursor+2-prevScope);
1658 }
else if (isInlined) {
1662 mod_start_of_type = start_of_type;
1663 result += string(tname,0,start_of_type);
1665 result += string(tname,start_of_type,prevScope - start_of_type);
1667 }
else if (modified) {
1668 result += std::string(tname+prevScope,cursor+2-prevScope);
1672 prevScope = cursor+1;
1682 auto next = cursor + 1;
1683 for (; next != cursor && nStars < 2 && next < len; next++) {
1684 if (
' ' == tname[next]) {
1687 }
else if (
'*' == tname[next]) {
1689 }
else if (
')' == tname[next]) {
1707 result += std::string(tname+prevScope,cursor+1-prevScope);
1713 }
while( cursor<len && tname[cursor] ==
',' );
1715 while (cursor<len && tname[cursor+1]==
' ') ++cursor;
1720 if (cursor+2<len && tname[cursor+1]==
':' && tname[cursor+2]==
':') {
1721 if (modified) result +=
"::";
1723 prevScope = cursor+1;
1725 if ( (cursor+1)<len && tname[cursor+1] ==
',') {
1727 if (modified) result +=
',';
1730 if ( (cursor+1)<len && tname[cursor+1] ==
'>') {
1732 if (modified) result +=
" >";
1735 if ( (cursor+1)<len && tname[cursor+1] ==
')') {
1737 if (modified) result +=
")";
1740 if ( (cursor+1) >= len) {
1743 if (tname[cursor] !=
' ')
break;
1744 if (modified) prevScope = cursor+1;
1751 end_of_type = cursor;
1753 while ((cursor+1)<len && tname[cursor+1] ==
' ') ++cursor;
1755 auto next = cursor+1;
1756 if (next < len && strncmp(tname+next,
"const",5) == 0 && ((next+5)==len || tname[next+5] ==
' ' || tname[next+5] ==
'*' || tname[next+5] ==
'&' || tname[next+5] ==
',' || tname[next+5] ==
'>' || tname[next+5] ==
')' || tname[next+5] ==
']'))
1761 result += string(tname,0,start_of_type);
1763 mod_start_of_type = start_of_type + 6;
1764 result += string(tname,start_of_type,end_of_type-start_of_type);
1765 }
else if (mod_start_of_type < result.length()) {
1766 result.insert(mod_start_of_type,
"const ");
1767 mod_start_of_type += 6;
1770 mod_start_of_type += 6;
1771 result += string(tname,start_of_type,end_of_type-start_of_type);
1774 end_of_type = cursor+1;
1775 prevScope = end_of_type;
1776 if ((next+5)==len || tname[next+5] ==
',' || tname[next+5] ==
'>' || tname[next+5] ==
')' || tname[next+5] ==
'[') {
1779 }
else if (next!=len && tname[next] !=
'*' && tname[next] !=
'&') {
1789 if (tname[cursor] !=
' ') end_of_type = cursor;
1791 auto next = cursor+1;
1792 if (next < len && strncmp(tname+next,
"const",5) == 0) {
1793 if ((next+5)==len || tname[next+5] ==
' ' || tname[next+5] ==
'*' || tname[next+5] ==
'&' || tname[next+5] ==
',' || tname[next+5] ==
'>' || tname[next+5] ==
')' || tname[next+5] ==
'[') {
1798 (tname[next] ==
' ' || tname[next] ==
'*' || tname[next] ==
'&')) {
1801 if (next < len && strncmp(tname+next,
"const",5) == 0) {
1802 if ((next+5)==len || tname[next+5] ==
' ' || tname[next+5] ==
'*' || tname[next+5] ==
'&' || tname[next+5] ==
',' || tname[next+5] ==
'>'|| tname[next+5] ==
')' || tname[next+5] ==
'[') {
1814 if (modified && prevScope) {
1815 result += std::string(tname+prevScope,(end_of_type == 0 ? cursor : end_of_type)-prevScope);
1819 if (modified) result +=
',';
1824 char c = tname[cursor];
1825 if (modified && prevScope) {
1826 result += std::string(tname+prevScope,(end_of_type == 0 ? cursor : end_of_type)-prevScope);
1830 if (modified) result +=
c;
1838 if (prevScope && modified) result += std::string(tname+prevScope,(end_of_type == 0 ? cursor : end_of_type)-prevScope);
1855 if (!tname || *tname == 0)
1857 if (!gInterpreterHelper)
1866 if (result.empty())
return tname;
1870 unsigned int len = strlen(tname);
1872 unsigned int cursor = 0;
1873 bool modified =
false;
1876 if (!modified)
return tname;
1890 static const char* sSTLtypes[] = {
1903 "basic_istringstream",
1906 "basic_ostringstream",
1910 "basic_stringstream",
1939 "istreambuf_iterator",
1948 "localedef utility",
1965 "moneypunct_byname",
1977 "ostreambuf_iterator",
1983 "pointer_to_binary_function",
1984 "pointer_to_unary_function",
1988 "raw_storage_iterator",
2007 "unordered_multimap",
2008 "unordered_multiset",
2015 if (!tname || *tname == 0)
return "";
2017 auto initSetSTLtypes = []() {
2018 std::set<std::string> iSetSTLtypes;
2020 const size_t nSTLtypes =
sizeof(sSTLtypes) /
sizeof(
const char*);
2021 for (
size_t i = 0; i < nSTLtypes; ++i)
2022 iSetSTLtypes.insert(sSTLtypes[i]);
2023 return iSetSTLtypes;
2025 static ShuttingDownSignaler<std::set<std::string>> sSetSTLtypes{ initSetSTLtypes() };
2028 size_t len = strlen(tname);
2030 ret.reserve(len + 20);
2034 bool precScope =
false;
2035 while (!(isalnum(tname[
b]) || tname[
b] ==
'_') &&
b < len) {
2036 precScope = (
b < len - 2) && (tname[
b] ==
':') && (tname[
b + 1] ==
':');
2048 while (
e < len && (isalnum(tname[
e]) || tname[
e] ==
'_'))
2052 set<string>::const_iterator iSTLtype = sSetSTLtypes.find(
id);
2053 if (iSTLtype != sSetSTLtypes.end())
2076 if (!mother)
return false;
2077 bool isSTLContOrArray =
true;
2078 while (
nullptr != mother){
2084 return isSTLContOrArray;
2092 if (clName.back() !=
'>') {
2097 std::vector<std::string>
v;
2102 auto argsEnd =
v.end();
2103 auto argsBeginPlusOne = ++
v.begin();
2104 auto argPos = std::find_if(argsBeginPlusOne, argsEnd,
2105 [](std::string& arg){return (!arg.empty() && arg.front() ==
':');});
2106 if (argPos != argsEnd) {
2107 const int length = clName.size();
2108 int wedgeBalance = 0;
2109 int lastOpenWedge = 0;
2110 for (
int i=length-1;i>-1;i--) {
2111 auto&
c = clName.at(i);
2115 }
else if (
c ==
'>') {
2117 }
else if (
c ==
':' && 0 == wedgeBalance) {
2119 auto nameToClean = clName.substr(0,i-1);
2128 cleanName += clName.substr(i+1,lastOpenWedge-i-1);
2131 auto lastTemplate = &clName.data()[i+1];
2143 unsigned int nargs =
v.size() - 2;
2144 for (
unsigned int i=0;i<nargs;++i) {
2180 name += node->ToString() +
",";
2184 name +=
name.back() ==
'>' ?
" >" :
">";
2217 std::string& typeNameBuf,
2218 std::array<int, 5>& maxIndices,
2228 for (ndim = 1;ndim <=5 ; ndim++) {
2229 maxIndices[ndim-1] = std::atoi(childNodes->back()->GetName().c_str());
2230 auto& frontNode = childNodes->front();
2231 typeNameBuf = frontNode->GetName();
2233 typeNameBuf = frontNode->ToString();
2236 childNodes = frontNode->GetChildNodes();
2249 const char* mangled_name = ti.name();
2255struct FunctionSplitInfo {
2257 std::string fReturnType;
2260 std::string fScopeName;
2263 std::string fFunctionName;
2267 std::vector<std::string> fFunctionTemplateArguments;
2270 std::vector<std::string> fFunctionParameters;
2277 std::size_t FindNonNestedNeedles(std::string_view haystack, string_view needles)
2279 std::stack<char> expected;
2280 for (std::size_t pos = 0, end = haystack.length(); pos < end; ++pos) {
2281 char c = haystack[pos];
2282 if (expected.empty()) {
2283 if (needles.find(
c) != std::string_view::npos)
2286 if (
c == expected.top()) {
2292 case '<': expected.emplace(
'>');
break;
2293 case '(': expected.emplace(
')');
break;
2294 case '[': expected.emplace(
']');
break;
2297 return std::string_view::npos;
2301 std::size_t FindNonNestedDoubleColons(std::string_view haystack)
2303 std::size_t lenHaystack = haystack.length();
2304 std::size_t prevAfterColumn = 0;
2306 std::size_t posColumn = FindNonNestedNeedles(haystack.substr(prevAfterColumn),
":");
2307 if (posColumn == std::string_view::npos)
2308 return std::string_view::npos;
2309 prevAfterColumn += posColumn;
2311 if (prevAfterColumn + 1 >= lenHaystack)
2312 return std::string_view::npos;
2315 if (haystack[prevAfterColumn] ==
':')
2316 return prevAfterColumn - 1;
2320 return std::string_view::npos;
2323 std::string_view StripSurroundingSpace(std::string_view str)
2325 while (!str.empty() && std::isspace(str[0]))
2326 str.remove_prefix(1);
2327 while (!str.empty() && std::isspace(str.back()))
2328 str.remove_suffix(1);
2332 std::string
ToString(std::string_view sv)
2336 return std::string(sv.data(), sv.length());
2349 std::size_t posArgs = FindNonNestedNeedles(decl,
"(");
2350 std::string_view declNoArgs = decl.substr(0, posArgs);
2352 std::size_t prevAfterWhiteSpace = 0;
2353 static const char whitespace[] =
" \t\n";
2354 while (declNoArgs.length() > prevAfterWhiteSpace) {
2355 std::size_t posWS = FindNonNestedNeedles(declNoArgs.substr(prevAfterWhiteSpace), whitespace);
2356 if (posWS == std::string_view::npos)
2358 prevAfterWhiteSpace += posWS + 1;
2359 while (declNoArgs.length() > prevAfterWhiteSpace
2360 && strchr(whitespace, declNoArgs[prevAfterWhiteSpace]))
2361 ++prevAfterWhiteSpace;
2365 std::size_t endReturn = prevAfterWhiteSpace;
2366 while (declNoArgs.length() > endReturn
2367 && strchr(
"&* \t \n", declNoArgs[endReturn]))
2373 std::string_view scopeFunctionTmplt = declNoArgs.substr(endReturn);
2374 std::size_t prevAtScope = FindNonNestedDoubleColons(scopeFunctionTmplt);
2375 while (prevAtScope != std::string_view::npos
2376 && scopeFunctionTmplt.length() > prevAtScope + 2) {
2377 std::size_t posScope = FindNonNestedDoubleColons(scopeFunctionTmplt.substr(prevAtScope + 2));
2378 if (posScope == std::string_view::npos)
2380 prevAtScope += posScope + 2;
2383 std::size_t afterScope = prevAtScope + 2;
2384 if (prevAtScope == std::string_view::npos) {
2389 result.
fScopeName =
ToString(StripSurroundingSpace(scopeFunctionTmplt.substr(0, prevAtScope)));
2390 std::string_view funcNameTmplArgs = scopeFunctionTmplt.substr(afterScope);
2393 std::size_t posTmpltOpen = FindNonNestedNeedles(funcNameTmplArgs,
"<");
2394 if (posTmpltOpen != std::string_view::npos) {
2398 std::string_view tmpltArgs = funcNameTmplArgs.substr(posTmpltOpen + 1);
2399 std::size_t posTmpltClose = FindNonNestedNeedles(tmpltArgs,
">");
2400 if (posTmpltClose != std::string_view::npos) {
2401 tmpltArgs = tmpltArgs.substr(0, posTmpltClose);
2402 std::size_t prevAfterArg = 0;
2403 while (tmpltArgs.length() > prevAfterArg) {
2404 std::size_t posComma = FindNonNestedNeedles(tmpltArgs.substr(prevAfterArg),
",");
2405 if (posComma == std::string_view::npos) {
2409 prevAfterArg += posComma + 1;
2419 if (posArgs != std::string_view::npos) {
2421 std::string_view params = decl.substr(posArgs + 1);
2422 std::size_t posEndArgs = FindNonNestedNeedles(params,
")");
2423 if (posEndArgs != std::string_view::npos) {
2424 params = params.substr(0, posEndArgs);
2425 std::size_t prevAfterArg = 0;
2426 while (params.length() > prevAfterArg) {
2427 std::size_t posComma = FindNonNestedNeedles(params.substr(prevAfterArg),
",");
2428 if (posComma == std::string_view::npos) {
2433 prevAfterArg += posComma + 1;
static const char * ToString(ENameCycleError err)
static void R__FindTrailing(std::string &full, std::string &stars)
static void ResolveTypedefImpl(const char *tname, unsigned int len, unsigned int &cursor, bool &modified, std::string &result)
static size_t findNameEnd(const std::string_view full)
static bool IsDefElement(const char *elementName, const char *defaultElementName, const char *classname)
return whether or not 'elementName' is the STL default Element for type 'classname'
static void ResolveTypedefProcessType(const char *tname, unsigned int, unsigned int cursor, bool constprefix, unsigned int start_of_type, unsigned int end_of_type, unsigned int mod_start_of_type, bool &modified, std::string &result)
An helper class to dismount the name and remount it changed whenever necessary.
NameCleanerForIO(const std::string &clName="", TClassEdit::EModType mode=TClassEdit::kNone, NameCleanerForIO *mother=nullptr)
NameCleanerForIO * fMother
const std::string & GetName()
std::vector< std::unique_ptr< NameCleanerForIO > > fArgumentNodes
const std::vector< std::unique_ptr< NameCleanerForIO > > * GetChildNodes() const
bool AreAncestorsSTLContOrArray()
A spin mutex-as-code-guard class.
A RAII helper to remove and readd enclosing _Atomic() It expects no spaces at the beginning or end of...
virtual bool CheckInClassTable(const std::string &, std::string &)=0
virtual bool GetPartiallyDesugaredNameWithScopeHandling(const std::string &, std::string &, bool=true)=0
virtual ~TInterpreterLookupHelper()
virtual bool IsAlreadyPartiallyDesugaredName(const std::string &, const std::string &)=0
virtual bool IsDeclaredScope(const std::string &, bool &)=0
virtual void ShuttingDownSignal()=0
virtual void GetPartiallyDesugaredName(std::string &)=0
virtual bool ExistingTypeCheck(const std::string &, std::string &)=0
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
bool IsDefComp(const char *comp, const char *classname)
return whether or not 'compare' is the STL default comparator for type 'classname'
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
bool IsStdArray(std::string_view name)
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsDefHash(const char *hashname, const char *classname)
return whether or not 'hashname' is the STL default hash for type 'classname'
bool IsStdPair(std::string_view name)
bool IsInterpreterDetail(const char *type)
Return true if the type is one the interpreter details which are only forward declared (ClassInfo_t e...
std::string InsertStd(const char *tname)
bool SplitFunction(std::string_view decl, FunctionSplitInfo &result)
Split a function declaration into its different parts.
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
bool IsDefPred(const char *predname, const char *classname)
return whether or not 'predname' is the STL default predicate for type 'classname'
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
bool IsVectorBool(const char *name)
void Init(TClassEdit::TInterpreterLookupHelper *helper)
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 CleanType(const char *typeDesc, int mode=0, const char **tail=nullptr)
Cleanup type description, redundant blanks removed and redundant tail ignored return *tail = pointer ...
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
char * DemangleName(const char *mangled_name, int &errorCode)
bool IsArtificial(std::string_view name)
bool GetStdArrayProperties(const char *typeName, std::string &typeNameBuf, std::array< int, 5 > &maxIndices, int &ndim)
std::string GetNameForIO(const std::string &templateInstanceName, TClassEdit::EModType mode=TClassEdit::kNone, bool *hasChanged=nullptr)
int STLArgs(int kind)
Return number of arguments for STL container before allocator.
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.
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.
bool IsDefAlloc(const char *alloc, const char *classname)
return whether or not 'allocname' is the STL default allocator for type 'classname'
bool IsUniquePtr(std::string_view name)
bool IsSTLBitset(const char *type)
Return true is the name is std::bitset<number> or bitset<number>.
ROOT::ESTLType UnderlyingIsSTLCont(std::string_view type)
Return the type of STL collection, if any, that is the underlying type of the given type.
EComplexType GetComplexType(const char *)
Result of splitting a function declaration into fReturnType fScopeName::fFunctionName<fFunctionTempla...
std::string fFunctionName
Name of the function.
std::vector< std::string > fFunctionTemplateArguments
Template arguments of the function template specialization, if any; will contain one element "" for f...
std::string fScopeName
Name of the scope qualification of the function, possibly empty.
std::vector< std::string > fFunctionParameters
Function parameters.
std::string fReturnType
Return type of the function, might be empty if the function declaration string did not provide it.
bool IsTemplate()
Check if the type is a template.
int IsSTLCont(int testAlloc=0) const
type : type name: vector<list<classA,allocator>,allocator> testAlloc: if true, we test allocator,...
TSplitType(const char *type2split, EModType mode=TClassEdit::kNone)
default constructor
std::vector< std::string > fElements
ROOT::ESTLType IsInSTL() const
type : type name: vector<list<classA,allocator>,allocator>[::iterator] result: 0 : not stl container ...
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.