19 #include "boost/regex.hpp"
30 #include "Reflex/Type.h"
31 #include "Cintex/Cintex.h"
44 class RootLoadFileSentry {
46 RootLoadFileSentry() {
47 G__setfilecontext(
"{CMS auto library loader}", &oldIFile_);
50 ~RootLoadFileSentry() {
51 G__input_file*
ifile = G__get_ifile();
58 G__input_file oldIFile_;
77 std::map<std::string, std::string>&
78 cintToReflexSpecialCasesMap() {
79 static std::map<std::string, std::string> s_map;
84 addWrapperOfVectorOfBuiltin(std::map<std::string, std::string>& iMap,
char const* iBuiltin) {
85 static std::string sReflexPrefix(
"edm::Wrapper<std::vector<");
86 static std::string sReflexPostfix(
"> >");
89 static std::string sCintPrefix(
"Wrapper<vector<");
90 static std::string sCintMiddle(
",allocator<");
91 static std::string sCintPostfix(
"> > >");
93 std::string
type(iBuiltin);
94 iMap.insert(make_pair(sCintPrefix + type + sCintMiddle + type + sCintPostfix,
95 sReflexPrefix + type + sReflexPostfix));
98 bool loadLibraryForClass(
char const* classname) {
104 static std::string
const cPrefix(
"LCGReflex/");
108 RootLoadFileSentry sentry;
115 if(!t.IsComplete()) {
131 t = Reflex::Type::ByName(classname);
148 int ALL_AutoLoadCallback(
char*
c,
char*
l) {
151 if(0 == c || 0 == l || l[0] == 0) {
154 ULong_t varp = G__getgvp();
155 G__setgvp((
long)G__PVOID);
156 int result = loadLibraryForClass(c) ? 1:0;
167 if(!result && 0 != strcmp(l, kDummyLibName) && gPrevious) {
174 classNameForRoot(std::string
const& iCapName) {
176 static boost::regex
const ex(
"std::");
177 std::string
const to(
"");
179 return regex_replace(iCapName, ex, to, boost::match_default | boost::format_sed);
184 struct CompareFirst {
185 bool operator()(std::pair<std::string, std::string>
const& iLHS,
186 std::pair<std::string, std::string>
const& iRHS)
const{
187 return iLHS.first > iRHS.first;
191 void registerTypes() {
196 CatToInfos::const_iterator itFound = db->
categoryToInfos().find(
"Capability");
206 typedef std::vector<std::pair<std::string, std::string> > ClassAndLibraries;
207 ClassAndLibraries classes;
208 classes.reserve(1000);
209 std::string lastClass;
212 std::map<std::string, std::string> specialsToLib;
213 std::map<std::string, std::string>
const& specials = cintToReflexSpecialCasesMap();
214 for(std::map<std::string, std::string>::const_iterator itSpecial = specials.begin();
215 itSpecial != specials.end();
217 specialsToLib[classNameForRoot(itSpecial->second)];
219 static std::string
const cPrefix(
"LCGReflex/");
220 for (edmplugin::PluginManager::Infos::const_iterator itInfo = itFound->second.begin(),
221 itInfoEnd = itFound->second.end();
222 itInfo != itInfoEnd; ++itInfo) {
223 if (lastClass == itInfo->name_) {
226 lastClass = itInfo->name_;
227 if(cPrefix == lastClass.substr(0, cPrefix.size())) {
228 std::string
className = classNameForRoot(lastClass.c_str() + cPrefix.size());
229 classes.push_back(std::pair<std::string, std::string>(className, itInfo->loadable_.native_file_string()));
230 std::map<std::string, std::string>::iterator itFound = specialsToLib.find(className);
231 if(itFound != specialsToLib.end()) {
233 itFound->second = itInfo->loadable_.native_file_string();
240 for(ClassAndLibraries::reverse_iterator itClass = classes.rbegin(), itClassEnd = classes.rend();
241 itClass != itClassEnd;
244 std::string
const&
className = itClass->first;
245 std::string
const& libraryName = itClass->second;
247 static std::string
const toFind(
":<");
249 while(std::string::npos != (pos = className.find_first_of(toFind, pos))) {
250 if (className[pos] ==
'<') {
break;}
251 if (className.size() <= pos + 1 || className[pos + 1] !=
':') {
break;}
253 G__set_class_autoloading_table(const_cast<char*>(className.substr(0, pos).c_str()), const_cast<char*>(
""));
257 G__set_class_autoloading_table(const_cast<char*>(className.c_str()), const_cast<char*>(libraryName.c_str()));
262 for(std::map<std::string, std::string>::const_iterator itSpecial = specials.begin();
263 itSpecial != specials.end();
267 if(specialsToLib[classNameForRoot(itSpecial->second)].size()) {
269 std::string
name = itSpecial->second;
274 std::cout <<
"failed to load plugin for " << cPrefix + name << std::endl;
280 std::cout <<
"reflex did not build " << name << std::endl;
283 TClass* reflexNamedClass = TClass::GetClass(t.TypeInfo());
284 if(0 == reflexNamedClass) {
285 std::cout <<
"failed to get TClass by typeid for " << name << std::endl;
288 reflexNamedClass->Clone(itSpecial->first.c_str());
289 std::string magictypedef(
"namespace edm { typedef ");
290 magictypedef += classNameForRoot(name) +
" " + itSpecial->first +
"; }";
292 gROOT->ProcessLine(magictypedef.c_str());
303 #
if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,6)
304 classNameAttemptingToLoad_(0),
305 isInitializingCintex_(
true) {
310 gROOT->AddClassGenerator(
this);
311 ROOT::Cintex::Cintex::Enable();
312 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,6)
316 std::map<std::string, std::string>& specials = cintToReflexSpecialCasesMap();
317 if(specials.empty()) {
318 addWrapperOfVectorOfBuiltin(specials,
"bool");
320 addWrapperOfVectorOfBuiltin(specials,
"char");
321 addWrapperOfVectorOfBuiltin(specials,
"unsigned char");
322 addWrapperOfVectorOfBuiltin(specials,
"signed char");
323 addWrapperOfVectorOfBuiltin(specials,
"short");
324 addWrapperOfVectorOfBuiltin(specials,
"unsigned short");
325 addWrapperOfVectorOfBuiltin(specials,
"int");
326 addWrapperOfVectorOfBuiltin(specials,
"unsigned int");
327 addWrapperOfVectorOfBuiltin(specials,
"long");
328 addWrapperOfVectorOfBuiltin(specials,
"unsigned long");
329 addWrapperOfVectorOfBuiltin(specials,
"long long");
330 addWrapperOfVectorOfBuiltin(specials,
"unsigned long long");
332 addWrapperOfVectorOfBuiltin(specials,
"float");
333 addWrapperOfVectorOfBuiltin(specials,
"double");
338 G__set_class_autoloading_callback(&ALL_AutoLoadCallback);
348 TClass* returnValue = 0;
354 if (idx != std::string::npos) {
355 className.replace(idx, 18, std::string(
"string"));
358 if(className.size() > idx + 6 && className[idx + 6] ==
' ') {
359 className.replace(idx + 6, 1,
"");
362 returnValue = gROOT->GetClass(className.c_str(), kTRUE);
377 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,6)
380 if (loadLibraryForClass(classname)) {
388 returnValue = gROOT->GetClass(classname, kTRUE);
398 TClass* returnValue = 0;
421 CatToInfos::const_iterator itFound = db->
categoryToInfos().find(
"Capability");
426 std::string lastClass;
427 std::string
const cPrefix(
"LCGReflex/");
430 RootLoadFileSentry sentry;
432 for (edmplugin::PluginManager::Infos::const_iterator itInfo = itFound->second.begin(),
433 itInfoEnd = itFound->second.end();
434 itInfo != itInfoEnd; ++itInfo) {
435 if (lastClass == itInfo->name_) {
439 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_
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
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
static PluginManager * get()
static char const * kDummyLibName
std::string className(const T &t)