00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "RConfigure.h"
00013 #include "RConfig.h"
00014 #include "Api.h"
00015
00016 #include "RStl.h"
00017 #include "TClassEdit.h"
00018 using namespace TClassEdit;
00019 #include <stdio.h>
00020
00021
00022 void WriteClassInit(G__ClassInfo &cl);
00023 void WriteAuxFunctions(G__ClassInfo &cl);
00024 int ElementStreamer(G__TypeInfo &ti,const char *R__t,int rwmode,const char *tcl=0);
00025
00026 #ifndef ROOT_Varargs
00027 #include "Varargs.h"
00028 #endif
00029 void Error(const char *location, const char *va_(fmt), ...);
00030 void Warning(const char *location, const char *va_(fmt), ...);
00031
00032
00033
00034
00035
00036 ROOT::RStl& ROOT::RStl::inst()
00037 {
00038
00039
00040 static ROOT::RStl instance;
00041 return instance;
00042
00043 }
00044
00045 void ROOT::RStl::GenerateTClassFor(const string& stlclassname)
00046 {
00047
00048
00049 G__ClassInfo cl(TClassEdit::ShortType(stlclassname.c_str(),
00050 TClassEdit::kDropTrailStar).c_str());
00051
00052 if ( ! cl.IsValid() ) {
00053 Error("RStl::GenerateTClassFor","%s not in the CINT dictionary",
00054 stlclassname.c_str());
00055 return;
00056 }
00057
00058 string registername( TClassEdit::ShortType(cl.Name(),
00059 TClassEdit::kDropStlDefault ) );
00060
00061
00062
00063
00064 int nestedLoc=0;
00065 vector<string> splitName;
00066 TClassEdit::GetSplit(registername.c_str(),splitName,nestedLoc);
00067
00068 if ( TClassEdit::STLKind( splitName[0].c_str() ) == TClassEdit::kVector ) {
00069 if ( splitName[1] == "bool" || splitName[1]=="Bool_t") {
00070 Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
00071 }
00072 }
00073
00074 fList.insert(registername);
00075
00076
00077 for(unsigned int i=1 ; i<splitName.size(); ++i) {
00078 if ( TClassEdit::IsSTLCont( splitName[i].c_str()) != 0 ) {
00079 GenerateTClassFor( splitName[i] );
00080 }
00081 }
00082
00083
00084
00085 }
00086
00087 void ROOT::RStl::Print()
00088 {
00089
00090 fprintf(stderr,"ROOT::RStl singleton\n");
00091 set<string>::iterator iter;
00092 for(iter = fList.begin(); iter != fList.end(); ++iter) {
00093 fprintf(stderr, "need TClass for %s\n", (*iter).c_str());
00094 }
00095 }
00096
00097 string ROOT::RStl::DropDefaultArg(const string &classname)
00098 {
00099
00100
00101 G__ClassInfo cl(classname.c_str());
00102
00103 if ( cl.TmpltName() == 0 ) return classname;
00104
00105 if ( TClassEdit::STLKind( cl.TmpltName() ) == 0 ) return classname;
00106
00107 return TClassEdit::ShortType( cl.Fullname(),
00108 TClassEdit::kDropStlDefault );
00109
00110 }
00111
00112 void ROOT::RStl::WriteClassInit(FILE* )
00113 {
00114
00115
00116
00117
00118 set<string>::iterator iter;
00119 G__ClassInfo cl;
00120 for(iter = fList.begin(); iter != fList.end(); ++iter) {
00121 cl.Init( (*iter).c_str() );
00122
00123 ::WriteClassInit( cl );
00124 ::WriteAuxFunctions( cl );
00125 }
00126 }
00127
00128 void ROOT::RStl::WriteStreamer(FILE *file, G__ClassInfo &stlcl)
00129 {
00130
00131
00132
00133 string streamerName = "stl_streamer_";
00134
00135 string shortTypeName = GetLong64_Name( TClassEdit::ShortType(stlcl.Name(),TClassEdit::kDropStlDefault) );
00136 string noConstTypeName( TClassEdit::CleanType(shortTypeName.c_str(),2) );
00137
00138 streamerName += G__map_cpp_name((char *)shortTypeName.c_str());
00139 string typedefName = G__map_cpp_name((char *)shortTypeName.c_str());
00140
00141 int nestedLoc=0;
00142 vector<string> splitName;
00143 TClassEdit::GetSplit(shortTypeName.c_str(),splitName,nestedLoc);
00144
00145 int stltype = TClassEdit::STLKind(splitName[0].c_str());
00146
00147 G__TypeInfo firstType(splitName[1].c_str());
00148 G__TypeInfo secondType;
00149 const char *tclFirst=0,*tclSecond=0;
00150 string firstFullName, secondFullName;
00151
00152 if (ElementStreamer(firstType,0,0)) {
00153 tclFirst = "R__tcl1";
00154 const char *name = firstType.Fullname();
00155 if (name) {
00156
00157
00158 firstFullName = TClassEdit::ShortType(name,TClassEdit::kDropStlDefault);
00159 } else {
00160
00161 firstFullName = firstType.TrueName();
00162 }
00163 }
00164 if (stltype==kMap || stltype==kMultiMap) {
00165 secondType.Init( splitName[2].c_str());
00166
00167 if (ElementStreamer(secondType,0,0)) {
00168 tclSecond="R__tcl2";
00169 const char *name = secondType.Fullname();
00170 if (name) {
00171
00172
00173 secondFullName = TClassEdit::ShortType(name,TClassEdit::kDropStlDefault);
00174 } else {
00175
00176 secondFullName = secondType.TrueName();
00177 }
00178 }
00179 }
00180
00181 fprintf(file, "//___________________________________________________________");
00182 fprintf(file, "_____________________________________________________________\n");
00183 fprintf(file, "namespace ROOT {\n");
00184 fprintf(file, " typedef %s %s;\n",shortTypeName.c_str(), typedefName.c_str());
00185 fprintf(file, " static void %s(TBuffer &R__b, void *R__p)\n",streamerName.c_str());
00186 fprintf(file, " {\n");
00187 fprintf(file, " if (gDebug>1) Info(__FILE__,\"Running compiled streamer for %s at %%p\",R__p);\n",shortTypeName.c_str());
00188 fprintf(file, " %s &R__stl = *(%s *)R__p;\n",shortTypeName.c_str(),shortTypeName.c_str());
00189 fprintf(file, " if (R__b.IsReading()) {\n");
00190 fprintf(file, " R__stl.clear();\n");
00191
00192 if (tclFirst)
00193 fprintf(file, " TClass *R__tcl1 = TBuffer::GetClass(typeid(%s));\n",
00194 firstFullName.c_str());
00195 if (tclSecond)
00196 fprintf(file, " TClass *R__tcl2 = TBuffer::GetClass(typeid(%s));\n",
00197 secondFullName.c_str());
00198
00199 fprintf(file, " int R__i, R__n;\n");
00200 fprintf(file, " R__b >> R__n;\n");
00201
00202 if (stltype==kVector) {
00203 fprintf(file," R__stl.reserve(R__n);\n");
00204 }
00205 fprintf(file, " for (R__i = 0; R__i < R__n; R__i++) {\n");
00206
00207 ElementStreamer(firstType,"R__t",0,tclFirst);
00208 if (stltype == kMap || stltype == kMultiMap) {
00209 ElementStreamer(secondType,"R__t2",0,tclSecond);
00210 }
00211 switch (stltype) {
00212
00213 case kMap:
00214 case kMultiMap:
00215 fprintf(file, " R__stl.insert(make_pair(R__t,R__t2));\n");
00216 break;
00217 case kSet:
00218 case kMultiSet:
00219 fprintf(file, " R__stl.insert(R__t);\n");
00220 break;
00221 case kVector:
00222 case kList:
00223 case kDeque:
00224 fprintf(file, " R__stl.push_back(R__t);\n");
00225 break;
00226
00227 default:
00228 assert(0);
00229 }
00230 fprintf(file, " }\n");
00231
00232 fprintf(file, " } else {\n");
00233
00234 fprintf(file, " int R__n=(&R__stl) ? int(R__stl.size()) : 0;\n");
00235 fprintf(file, " R__b << R__n;\n");
00236 fprintf(file, " if(R__n) {\n");
00237
00238 if (tclFirst) {
00239 fprintf(file, " TClass *R__tcl1 = TBuffer::GetClass(typeid(%s));\n",
00240 firstFullName.c_str());
00241 fprintf(file, " if (R__tcl1==0) {\n");
00242 fprintf(file, " Error(\"%s streamer\",\"Missing the TClass object for %s!\");\n",
00243 shortTypeName.c_str(), firstFullName.c_str());
00244 fprintf(file, " return;\n");
00245 fprintf(file, " }\n");
00246 }
00247 if (tclSecond) {
00248 fprintf(file, " TClass *R__tcl2 = TBuffer::GetClass(typeid(%s));\n",
00249 secondFullName.c_str());
00250 fprintf(file, " if (R__tcl2==0) {\n");
00251 fprintf(file, " Error(\"%s streamer\",\"Missing the TClass object for %s!\");\n",
00252 shortTypeName.c_str(), secondFullName.c_str());
00253 fprintf(file, " return;\n");
00254 fprintf(file, " }\n");
00255 }
00256 fprintf(file, " %s::iterator R__k;\n", shortTypeName.c_str());
00257 fprintf(file, " for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {\n");
00258
00259 if (stltype == kMap || stltype == kMultiMap) {
00260 ElementStreamer(firstType ,"((*R__k).first )",1,tclFirst);
00261 ElementStreamer(secondType,"((*R__k).second)",1,tclSecond);
00262 } else {
00263 ElementStreamer(firstType ,"(*R__k)" ,1,tclFirst);
00264 }
00265
00266 fprintf(file, " }\n");
00267 fprintf(file, " }\n");
00268
00269 fprintf(file, " }\n");
00270 fprintf(file, " } // end of %s streamer\n",stlcl.Fullname());
00271 fprintf(file, "} // close namespace ROOT\n\n");
00272
00273 fprintf(file, "// Register the streamer (a typedef is used to avoid problem with macro parameters\n");
00274
00275
00276
00277
00278 fprintf(file, "RootStlStreamer(%s,%s)\n", typedefName.c_str(), streamerName.c_str());
00279 fprintf(file, "\n");
00280
00281 }
00282
00283 void ROOT::RStl::WriteStreamer(FILE *file)
00284 {
00285
00286
00287
00288 set<string>::iterator iter;
00289 G__ClassInfo cl;
00290 for(iter = fList.begin(); iter != fList.end(); ++iter) {
00291 cl.Init( (*iter).c_str() );
00292 WriteStreamer(file,cl);
00293 }
00294 }