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