CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ClassUtils.cc
Go to the documentation of this file.
5 #include "ClassUtils.h"
6 //
7 #include <typeinfo>
8 #include <cxxabi.h>
9 // externals
12 #include "TROOT.h"
13 #include "TDictAttributeMap.h"
14 
16  m_type( type ){
17 }
18 
20  m_type( rhs.m_type ){
21 }
22 
24 }
25 
26 void ora::RflxDeleter::operator()( void* ptr ){
27  m_type.destruct( ptr );
28 }
29 
31  static std::string const prefix("LCGReflex/");
32  edmplugin::PluginCapabilities::get()->load(prefix + className);
33 }
34 
36  void* ptr,
37  const edm::TypeWithDict& castType ){
38  void* ret = 0;
39  if( type == castType ){
40  ret = ptr;
41  } else if( type.hasBase( castType )){
42  ret = reinterpret_cast<void*>(reinterpret_cast<size_t>(ptr) + type.getBaseClassOffset(castType));
43  }
44  return ret;
45 }
46 
48  const edm::TypeWithDict& baseType ){
49  bool ret = false;
50  if( type == baseType || type.hasBase( baseType )){
51  ret = true;
52  }
53  return ret;
54 }
55 
56 static
57 void
59  // from must not be a substring of to.
60  std::string::size_type length = from.size();
61  std::string::size_type pos = 0;
62  while((pos = name.find(from, pos)) != std::string::npos) {
63  name.replace(pos, length, to);
64  }
65 }
66 
67 static
68 bool
70  size_t pos = name.find('<');
71  if(pos == std::string::npos) {
72  // Not a template instance
73  return false;
74  }
75  size_t nameSize = name.size();
76  if(other.size() >= nameSize) {
77  // Can't be a case with ull qualifiers no name.
78  return false;
79  }
80  if(name.substr(0, pos) != other.substr(0, pos)) {
81  return false;
82  }
83  int nesting = 0;
84  size_t j = pos;
85  for(size_t i = pos; i < nameSize; ++i) {
86  char c = name[i];
87  if (c == '<') ++nesting;
88  if(c != other[j]) {
89  if(c != 'u' && c != 'l') return false;
90  if(nesting == 0) return false;
91  if(!isdigit(name[i-1])) return false;
92  for(size_t n = i-2; n >= pos; --n) {
93  char q = name[n];
94  if(q == '<' || q == ',') break;
95  if(!isdigit(q)) return false;
96  }
97  for(size_t n = i+1; n < nameSize; ++n) {
98  char q = name[n];
99  if(q == '>' || q == ',') break;
100  if(q != 'l') return false;
101  ++i;
102  }
103  continue;
104  }
105  if (c == '>') --nesting;
106  ++j;
107  }
108  return true;
109 }
110 
112  const std::string& mappedTypeName ){
113  if( isTypeString( type ) ){
114  return (mappedTypeName=="std::basic_string<char>" || mappedTypeName=="basic_string<char>" || mappedTypeName=="std::string" || mappedTypeName=="string");
115  } else if ( type.isEnum() ){
116  return mappedTypeName=="int";
117  } else if ( isTypeOraVector( type ) ){
118  return isTypeNameOraVector( mappedTypeName );
119  } else if ( type.cppName() == mappedTypeName ) {
120  return true;
121  }
122  // ROOT 6 uses these typedefs in names.
123  std::string typeName(mappedTypeName);
124  replaceString(typeName, "std::basic_string<char> ", "std::string");
125  replaceString(typeName, "std::basic_string<char>", "std::string");
126  if ( type.cppName() == typeName ) {
127  return true;
128  }
129  // Ignore u and l qualifiers off of integer template parameters for comparison
130  return ( compareWithSuffixes( type.cppName(), typeName ) );
131 }
132 
134  bool found = false;
135  if ( ! type.hasBase(baseType) ) {
136  return found; // no inheritance, nothing to do
137  } else {
138  func = type.getBaseClassOffset(baseType);
139  found = true;
140  }
141 /*-ap old code
142  for ( unsigned int i=0;i<type.BaseSize() && !found; i++){
143  edm::BaseWithDict base = type.BaseAt(i);
144  edm::TypeWithDict bt = resolvedType( base.ToType() );
145  if( bt == baseType ){
146  func = base.OffsetFP();
147  found = true;
148  } else {
149  found = findBaseType( bt, baseType, func );
150  }
151  }
152 */
153  return found;
154 }
155 
156 std::string ora::ClassUtils::demangledName( const std::type_info& typeInfo ){
157  int status = 0;
158  std::string ret("");
159  char* realname = abi::__cxa_demangle( typeInfo.name(), 0, 0, &status);
160  if( status == 0 && realname ){
161  ret = realname;
162  free(realname);
163  }
164  return ret;
165 }
166 
167 edm::TypeWithDict ora::ClassUtils::lookupDictionary( const std::type_info& typeInfo, bool throwFlag ){
168  edm::TypeWithDict type ( typeInfo );
169  if( typeInfo == typeid(std::string) ){
170  // ugly, but no other way with Reflex...
171  type = edm::TypeWithDict::byName("std::string");
172  }
173  if( !type ){
174  loadDictionary( demangledName(typeInfo) );
175  edm::TypeWithDict type1 ( typeInfo );
176  type = type1;
177  }
178  if( !type && throwFlag ){
179  throwException( "Class \""+demangledName(typeInfo)+"\" has not been found in the dictionary.",
180  "ClassUtils::lookupDictionary" );
181  }
182  return type;
183 }
184 
187  if( className == "std::basic_string<char>" ){
188  // ugly, but no other way with Reflex...
189  type = edm::TypeWithDict::byName("std::string");
190  }
191  if( !type ){
192  loadDictionary( className );
193  type = edm::TypeWithDict::byName( className );
194  }
195  if( !type && throwFlag ){
196  throwException( "Class \""+className+"\" has not been found in the dictionary.",
197  "ClassUtils::lookupDictionary" );
198  }
199  return type;
200 }
201 
203  void* ptr = 0;
204  if( typ.cppName()=="std::string"){
205  ptr = new std::string("");
206  } else {
207  ptr = typ.construct().address();
208  }
209  return ptr;
210 }
211 
213  std::string name = typ.cppName();
214  return ( name == "std::string" ||
215  name == "std::basic_string<char>" );
216 }
217 
219  return ( typ.isFundamental() || typ.isEnum() || isTypeString( typ ) );
220 }
221 
223  if ( ! typ.isTemplateInstance() ) {
224  return false;
225  } else {
226  std::string contName = typ.templateName();
227  if( contName == "std::vector" ||
228  contName == "std::list" ||
229  contName == "std::deque" ||
230  contName == "std::stack" ||
231  contName == "std::set" ||
232  contName == "std::multiset" ||
233  contName == "__gnu_cxx::hash_set" ||
234  contName == "__gnu_cxx::hash_multiset" ||
235  contName == "std::map" ||
236  contName == "std::multimap" ||
237  contName == "__gnu_cxx::hash_map" ||
238  contName == "__gnu_cxx::hash_multimap" ||
239  contName == "ora::PVector" ||
240  contName == "ora::QueryableVector" ){
241  return true;
242  }
243  }
244  return false;
245 }
246 
248  if ( ! typ.isTemplateInstance() ) {
249  return false;
250  } else {
251  std::string contName = typ.templateName();
252  if( contName == "std::map" ||
253  contName == "std::multimap" ||
254  contName == "std::set" ||
255  contName == "std::multiset" ||
256  contName == "__gnu_cxx::hash_set" ||
257  contName == "__gnu_cxx::hash_multiset" ||
258  contName == "__gnu_cxx::hash_map" ||
259  contName == "__gnu_cxx::hash_multimap" ){
260  return true;
261  }
262  }
263  return false;
264 }
265 
267  if ( ! typ.isTemplateInstance() ) {
268  return false;
269  } else {
270  std::string contName = typ.templateName();
271  if( contName == "std::vector" ||
272  contName == "std::list" ||
273  contName == "std::deque" ||
274  contName == "std::stack" ||
275  contName == "ora::PVector" ||
276  contName == "ora::QueryableVector" ){
277  return true;
278  }
279  }
280  return false;
281 }
282 
284  if ( ! typ.isTemplateInstance() ) {
285  return false;
286  } else {
287  std::string contName = typ.templateName();
288  if( contName == "std::map" ||
289  contName == "std::multimap" ||
290  contName == "__gnu_cxx::hash_map" ||
291  contName == "__gnu_cxx::hash_multimap" ){
292  return true;
293  }
294  }
295  return false;
296 }
297 
299  if ( ! typ.isTemplateInstance() ) {
300  return false;
301  } else {
302  std::string contName = typ.templateName();
303  if( contName == "std::vector" ||
304  contName == "std::list" ||
305  contName == "std::deque" ||
306  contName == "std::stack" ||
307  contName == "std::set" ||
308  contName == "std::multiset" ||
309  contName == "__gnu_cxx::hash_set" ||
310  contName == "__gnu_cxx::hash_multiset" ||
311  contName == "ora::PVector" ||
312  contName == "ora::QueryableVector"){
313  return true;
314  }
315  }
316  return false;
317 }
318 
319 
321  if ( ! typ.isTemplateInstance() ) {
322  return false;
323  } else {
324  std::string contName = typ.templateName();
325  if( contName == "ora::Ptr" ){
326  return true;
327  }
328  }
329  return false;
330 }
331 
333  return typ.hasBase( edm::TypeWithDict(typeid(ora::Reference)) );
334 }
335 
337  return typ.hasBase( edm::TypeWithDict(typeid(ora::NamedReference)) );
338 }
339 
341  if ( ! typ.isTemplateInstance() ) {
342  return false;
343  } else {
344  std::string contName = typ.templateName();
345  if( contName == "ora::UniqueRef" ){
346  return true;
347  }
348  }
349  return false;
350 }
351 
353  if ( ! typ.isTemplateInstance() ) {
354  return false;
355  } else {
356  std::string contName = typ.templateName();
357  if( contName == "ora::PVector" ){
358  return true;
359  }
360  }
361  return false;
362 }
363 
365  if ( ! typ.isTemplateInstance() ) {
366  return false;
367  } else {
368  std::string contName = typ.templateName();
369  if( contName == "ora::QueryableVector" ){
370  return true;
371  }
372  }
373  return false;
374 }
375 
377  if( isTypePVector( typ ) || isTypeQueryableVector( typ ) ){
378  return true;
379  }
380  return false;
381 }
382 
384  size_t idx = typeName.find('<');
385  if( idx != std::string::npos ){
386  std::string tname = typeName.substr( 0, idx );
387  return (tname == "ora::PVector" || tname == "ora::QueryableVector" || tname == "pool::PVector" );
388  }
389  return false;
390 }
391 
394  if( isTypePrimitive( resType ) ) {
395  //if ( resType.IsFundamental() || resType.IsEnum() || isTypeString(resType) ) {
396  return false;
397  } else {
398  if( resType.isArray( ) ) return false;
399  if( isTypeContainer( resType ) ) return false;
400  if( isTypeOraPointer( resType ) ) return false;
401  if( isTypeUniqueReference( resType ) ) return false;
402  if( isTypeOraVector( resType ) ) return false;
403  }
404  return true;
405 }
406 
408  /*-ap old code
409  edm::TypeWithDict valueType;
410  // find the iterator return type as the member value_type of the containers
411  size_t subTypeSize = typ.SubTypeSize();
412  size_t i=0;
413  while(i<subTypeSize){
414  edm::TypeWithDict sti = typ.SubTypeAt(i);
415  if(sti.Name()=="value_type") {
416  valueType = sti;
417  break;
418  }
419  i++;
420  }
421  return valueType;
422  */
423  return typ.nestedType("value_type");
424 }
425 
427  /*-ap old code
428  edm::TypeWithDict keyType;
429  // find the iterator return type as the member value_type of the containers
430  size_t subTypeSize = typ.SubTypeSize();
431  size_t i=0;
432  while(i<subTypeSize){
433  edm::TypeWithDict sti = typ.SubTypeAt(i);
434  if(sti.Name()=="key_type") {
435  keyType = sti;
436  break;
437  }
438  i++;
439  }
440  return keyType;
441  */
442  return typ.nestedType("key_type");
443 
444 }
445 
447  /*-ap old code
448  edm::TypeWithDict dataType;
449  // find the iterator return type as the member value_type of the containers
450  size_t subTypeSize = typ.SubTypeSize();
451  size_t i=0;
452  while(i<subTypeSize){
453  edm::TypeWithDict sti = typ.SubTypeAt(i);
454  if(sti.Name()=="mapped_type") {
455  dataType = sti;
456  break;
457  }
458  i++;
459  }
460  return dataType;
461  */
462  return typ.nestedType("mapped_type");
463 }
464 
466  /*-ap old code
467  edm::TypeWithDict subType;
468  size_t subTypeSize = typ.SubTypeSize();
469  size_t i=0;
470  while(i<subTypeSize){
471  edm::TypeWithDict sti = typ.SubTypeAt(i);
472  if(sti.Name()==subTypeName) {
473  subType = sti;
474  break;
475  }
476  i++;
477  }
478  return resolvedType(subType);
479  */
480  return typ.nestedType(subTypeName);
481 }
482 
484  if (typ.isTypedef()){
485  return typ.finalType().toType();
486  }
487  return typ;
488 }
489 
491  size_t arraySize = typ.arrayLength();
492  edm::TypeWithDict arrayType = typ.toType();
493  if( arrayType.isArray() ) arraySize /= arrayType.arrayLength();
494  return arraySize;
495 }
496 
498  const edm::TypeWithDict& type ){
499  std::string ret("");
500  TClass* rclass = type.getClass();
501  if( rclass ){
502  TDictAttributeMap* classProps = rclass->GetAttributeMap();
503  if( classProps && classProps->HasKey( propertyName.c_str() ) ){
504  ret = classProps->GetPropertyAsString( propertyName.c_str() );
505  }
506  }
507  return ret;
508 }
509 
511  const edm::MemberWithDict& dataMember ){
512  std::string ret("");
513  TClass* declaringClass = dataMember.declaringType().getClass();
514  if( declaringClass ){
515  auto dm = declaringClass->GetDataMember( dataMember.name().c_str() );
516  if( dm ) {
517  TDictAttributeMap* memberProps = dm->GetAttributeMap();
518  if( memberProps && memberProps->HasKey( propertyName.c_str() ) ){
519  ret = memberProps->GetPropertyAsString( propertyName.c_str() );
520  }
521  }
522  }
523  return ret;
524 }
bool isTypeObject(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:392
type
Definition: HCALResponse.h:21
bool isEnum() const
int i
Definition: DBlmapReader.cc:9
edm::TypeWithDict resolvedType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:483
bool isTypeKeyedContainer(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:247
TypeWithDict finalType() const
void * address() const
bool isTypeNamedReference(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:336
bool isTypedef() const
static char const * tname
Definition: GTSchema.h:13
static bool compareWithSuffixes(std::string const &name, std::string const &other)
Definition: ClassUtils.cc:69
bool isTypeString(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:212
void * upCast(const edm::TypeWithDict &type, void *ptr, const edm::TypeWithDict &asType)
Definition: ClassUtils.cc:35
void operator()(void *ptr)
Definition: ClassUtils.cc:26
TypeWithDict nestedType(char const *) const
uint16_t size_type
RflxDeleter(const edm::TypeWithDict &type)
Definition: ClassUtils.cc:15
bool hasBase(std::string const &) const
bool isTypePrimitive(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:218
TypeWithDict toType() const
bool isTypeOraPointer(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:320
bool isType(const edm::TypeWithDict &type, const edm::TypeWithDict &baseType)
Definition: ClassUtils.cc:47
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:60
std::string demangledName(const std::type_info &typeInfo)
Definition: ClassUtils.cc:156
TypeWithDict declaringType() const
bool isArray() const
bool isTypeNonAssociativeContainer(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:298
std::string templateName() const
bool isTemplateInstance() const
TClass * getClass() const
bool isTypeNameOraVector(const std::string &typeName)
Definition: ClassUtils.cc:383
void loadDictionary(const std::string &className)
Definition: ClassUtils.cc:30
std::string cppName() const
bool isTypePVector(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:352
edm::TypeWithDict containerSubType(const edm::TypeWithDict &typ, const std::string &subTypeName)
Definition: ClassUtils.cc:465
bool isTypeUniqueReference(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:340
int j
Definition: DBlmapReader.cc:9
std::string name() const
static PluginCapabilities * get()
bool isTypeOraVector(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:376
bool checkMappedType(const edm::TypeWithDict &type, const std::string &mappedTypeName)
Definition: ClassUtils.cc:111
bool isFundamental() const
bool isTypeOraReference(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:332
static void replaceString(std::string &name, std::string const &from, std::string const &to)
Definition: ClassUtils.cc:58
edm::TypeWithDict lookupDictionary(const std::type_info &typeInfo, bool throwFlag=true)
Definition: ClassUtils.cc:167
bool findBaseType(edm::TypeWithDict &type, edm::TypeWithDict &baseType, size_t &func)
Definition: ClassUtils.cc:133
bool isTypeAssociativeContainer(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:283
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
bool isTypeNonKeyedContainer(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:266
size_t arrayLength(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:490
bool isTypeQueryableVector(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:364
edm::TypeWithDict containerKeyType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:426
edm::TypeWithDict containerDataType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:446
void throwException(const std::string &message, const std::string &methodName) __attribute__((noreturn))
Definition: Exception.cc:10
int getBaseClassOffset(TypeWithDict const &baseClass) const
void * constructObject(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:202
std::string getClassProperty(const std::string &propertyName, const edm::TypeWithDict &type)
Definition: ClassUtils.cc:497
edm::TypeWithDict containerValueType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:407
ObjectWithDict construct() const
void load(const std::string &iName)
std::string getDataMemberProperty(const std::string &propertyName, const edm::MemberWithDict &dataMember)
Definition: ClassUtils.cc:510
tuple status
Definition: ntuplemaker.py:245
bool isTypeContainer(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:222
size_t arrayLength() const
std::string className(const T &t)
Definition: ClassName.h:30