19 #include "boost/regex.hpp"
30 #include "Reflex/Type.h"
31 #include "Cintex/Cintex.h"
43 class RootLoadFileSentry {
45 RootLoadFileSentry() {
46 G__setfilecontext(
"{CMS auto library loader}", &oldIFile_);
49 ~RootLoadFileSentry() {
50 G__input_file*
ifile = G__get_ifile();
57 G__input_file oldIFile_;
76 std::map<std::string, std::string>&
77 cintToReflexSpecialCasesMap() {
78 static std::map<std::string, std::string> s_map;
83 addWrapperOfVectorOfBuiltin(std::map<std::string, std::string>& iMap,
char const* iBuiltin) {
84 static std::string sReflexPrefix(
"edm::Wrapper<std::vector<");
85 static std::string sReflexPostfix(
"> >");
88 static std::string sCintPrefix(
"Wrapper<vector<");
89 static std::string sCintMiddle(
",allocator<");
90 static std::string sCintPostfix(
"> > >");
92 std::string
type(iBuiltin);
93 iMap.insert(make_pair(sCintPrefix + type + sCintMiddle + type + sCintPostfix,
94 sReflexPrefix + type + sReflexPostfix));
97 bool loadLibraryForClass(
char const* classname) {
103 static std::string
const cPrefix(
"LCGReflex/");
107 RootLoadFileSentry sentry;
114 if(!t.IsComplete()) {
130 t = Reflex::Type::ByName(classname);
147 int ALL_AutoLoadCallback(
char*
c,
char*
l) {
150 if(0 == c || 0 == l || l[0] == 0) {
153 ULong_t varp = G__getgvp();
154 G__setgvp((
long)G__PVOID);
155 int result = loadLibraryForClass(c) ? 1:0;
166 if(!result && 0 != strcmp(l, kDummyLibName) && gPrevious) {
173 classNameForRoot(std::string
const& iCapName) {
175 static boost::regex
const ex(
"std::");
176 std::string
const to(
"");
178 return regex_replace(iCapName, ex, to, boost::match_default | boost::format_sed);
183 struct CompareFirst {
184 bool operator()(std::pair<std::string, std::string>
const& iLHS,
185 std::pair<std::string, std::string>
const& iRHS)
const{
186 return iLHS.first > iRHS.first;
190 void registerTypes() {
195 CatToInfos::const_iterator itFound = db->
categoryToInfos().find(
"Capability");
205 typedef std::vector<std::pair<std::string, std::string> > ClassAndLibraries;
206 ClassAndLibraries classes;
207 classes.reserve(1000);
208 std::string lastClass;
211 std::map<std::string, std::string> specialsToLib;
212 std::map<std::string, std::string>
const& specials = cintToReflexSpecialCasesMap();
213 for(std::map<std::string, std::string>::const_iterator itSpecial = specials.begin();
214 itSpecial != specials.end();
216 specialsToLib[classNameForRoot(itSpecial->second)];
218 static std::string
const cPrefix(
"LCGReflex/");
219 for (edmplugin::PluginManager::Infos::const_iterator itInfo = itFound->second.begin(),
220 itInfoEnd = itFound->second.end();
221 itInfo != itInfoEnd; ++itInfo) {
222 if (lastClass == itInfo->name_) {
225 lastClass = itInfo->name_;
226 if(cPrefix == lastClass.substr(0, cPrefix.size())) {
227 std::string
className = classNameForRoot(lastClass.c_str() + cPrefix.size());
228 classes.push_back(std::pair<std::string, std::string>(className, itInfo->loadable_.string()));
229 std::map<std::string, std::string>::iterator itFound = specialsToLib.find(className);
230 if(itFound != specialsToLib.end()) {
232 itFound->second = itInfo->loadable_.string();
239 for(ClassAndLibraries::reverse_iterator itClass = classes.rbegin(), itClassEnd = classes.rend();
240 itClass != itClassEnd;
243 std::string
const&
className = itClass->first;
244 std::string
const& libraryName = itClass->second;
246 static std::string
const toFind(
":<");
248 while(std::string::npos != (pos = className.find_first_of(toFind, pos))) {
249 if (className[pos] ==
'<') {
break;}
250 if (className.size() <= pos + 1 || className[pos + 1] !=
':') {
break;}
252 G__set_class_autoloading_table(const_cast<char*>(className.substr(0, pos).c_str()), const_cast<char*>(
""));
256 G__set_class_autoloading_table(const_cast<char*>(className.c_str()), const_cast<char*>(libraryName.c_str()));
261 for(std::map<std::string, std::string>::const_iterator itSpecial = specials.begin();
262 itSpecial != specials.end();
266 if(specialsToLib[classNameForRoot(itSpecial->second)].size()) {
268 std::string
name = itSpecial->second;
273 std::cout <<
"failed to load plugin for " << cPrefix + name << std::endl;
279 std::cout <<
"reflex did not build " << name << std::endl;
282 TClass* reflexNamedClass = TClass::GetClass(t.TypeInfo());
283 if(0 == reflexNamedClass) {
284 std::cout <<
"failed to get TClass by typeid for " << name << std::endl;
287 reflexNamedClass->Clone(itSpecial->first.c_str());
288 std::string magictypedef(
"namespace edm { typedef ");
289 magictypedef += classNameForRoot(name) +
" " + itSpecial->first +
"; }";
291 gROOT->ProcessLine(magictypedef.c_str());
302 #
if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,6)
303 classNameAttemptingToLoad_(0),
304 isInitializingCintex_(
true) {
309 gROOT->AddClassGenerator(
this);
310 ROOT::Cintex::Cintex::Enable();
311 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,6)
315 std::map<std::string, std::string>& specials = cintToReflexSpecialCasesMap();
316 if(specials.empty()) {
317 addWrapperOfVectorOfBuiltin(specials,
"bool");
319 addWrapperOfVectorOfBuiltin(specials,
"char");
320 addWrapperOfVectorOfBuiltin(specials,
"unsigned char");
321 addWrapperOfVectorOfBuiltin(specials,
"signed char");
322 addWrapperOfVectorOfBuiltin(specials,
"short");
323 addWrapperOfVectorOfBuiltin(specials,
"unsigned short");
324 addWrapperOfVectorOfBuiltin(specials,
"int");
325 addWrapperOfVectorOfBuiltin(specials,
"unsigned int");
326 addWrapperOfVectorOfBuiltin(specials,
"long");
327 addWrapperOfVectorOfBuiltin(specials,
"unsigned long");
328 addWrapperOfVectorOfBuiltin(specials,
"long long");
329 addWrapperOfVectorOfBuiltin(specials,
"unsigned long long");
331 addWrapperOfVectorOfBuiltin(specials,
"float");
332 addWrapperOfVectorOfBuiltin(specials,
"double");
337 G__set_class_autoloading_callback(&ALL_AutoLoadCallback);
347 TClass* returnValue = 0;
353 if (idx != std::string::npos) {
354 className.replace(idx, 18, std::string(
"string"));
357 if(className.size() > idx + 6 && className[idx + 6] ==
' ') {
358 className.replace(idx + 6, 1,
"");
361 returnValue = gROOT->GetClass(className.c_str(), kTRUE);
376 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,6)
379 if (loadLibraryForClass(classname)) {
387 returnValue = gROOT->GetClass(classname, kTRUE);
397 TClass* returnValue = 0;
420 CatToInfos::const_iterator itFound = db->
categoryToInfos().find(
"Capability");
425 std::string lastClass;
426 std::string
const cPrefix(
"LCGReflex/");
429 RootLoadFileSentry sentry;
431 for (edmplugin::PluginManager::Infos::const_iterator itInfo = itFound->second.begin(),
432 itInfoEnd = itFound->second.end();
433 itInfo != itInfoEnd; ++itInfo) {
434 if (lastClass == itInfo->name_) {
438 lastClass = itInfo->name_;
const CategoryToInfos & categoryToInfos() const
virtual TClass * GetClass(char const *classname, Bool_t load)
return class type
int(* CallbackPtr)(char *, char *)
std::string stdNamespaceAdder(const std::string &iClassName)
std::map< std::string, Infos > CategoryToInfos
static PluginCapabilities * get()
CallbackPtr G__p_class_autoloading
bool isInitializingCintex_
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
static void loadAll()
load all known libraries holding dictionaries
char const * classNameAttemptingToLoad_
static CallbackPtr gPrevious
perl if(1 lt scalar(@::datatypes))
void load(const std::string &iName)
static void enable()
interface for TClass generators
static PluginManager * get()
static char const * kDummyLibName
std::string className(const T &t)