CMS 3D CMS Logo

TypeWithDict.cc
Go to the documentation of this file.
2 
11 
12 #include "TClass.h"
13 #include "TClassTable.h"
14 #include "TDataType.h"
15 #include "TEnum.h"
16 #include "TEnumConstant.h"
17 #include "TMethodArg.h"
18 #include "TRealData.h"
19 #include "TROOT.h"
20 
21 #include "tbb/concurrent_unordered_map.h"
22 
23 #include <cassert>
24 #include <cstdio>
25 #include <cstdlib>
26 #include <ostream>
27 #include <typeinfo>
28 #include <typeindex>
29 
30 #include <cxxabi.h>
31 
32 //#include <iostream>
33 namespace edm {
34 
35  namespace {
36  using Map = tbb::concurrent_unordered_map<std::string, TypeWithDict>;
37  Map typeMap;
38  using FunctionMap = tbb::concurrent_unordered_map<std::string, FunctionWithDict>;
39  FunctionMap functionMap;
40 
41  struct TypeIndexHash {
42  std::size_t operator()(std::type_index ti) const { return ti.hash_code(); }
43  };
44 
45  using TypeIndexMap = tbb::concurrent_unordered_map<std::type_index, TypeWithDict, TypeIndexHash>;
46  TypeIndexMap typeIndexMap;
47  } // namespace
48  static void throwTypeException(std::string const& function, std::string const& typeName) {
49  throw Exception(errors::DictionaryNotFound) << "Function " << function << ",\n"
50  << "no data dictionary found for type:\n\n"
51  << typeName << "\nMost likely the dictionary was never generated,\n"
52  << "but it may be that it was generated in the wrong package.\n"
53  << "Please add (or move) the specification\n"
54  << "<class name=\"whatever\"/>\n"
55  << "to the appropriate classes_def.xml file.\n"
56  << "If the class is a template instance, you may need\n"
57  << "to define a dummy variable of this type in classes.h.\n"
58  << "Also, if this class has any transient members,\n"
59  << "you need to specify them in classes_def.xml.";
60  }
61 
62  TypeWithDict TypeWithDict::byTypeInfo(std::type_info const& ti) {
63  // This is a public static function.
64  auto index = std::type_index(ti);
65  auto const& item = typeIndexMap.find(index);
66  if (item != typeIndexMap.end()) {
67  return item->second;
68  }
69  TypeWithDict theType(ti, 0L);
70  typeIndexMap.insert(std::make_pair(index, theType));
71  return theType;
72  }
73 
75  // This is a public static function.
76  auto const& item = typeMap.find(name);
77  if (item != typeMap.end()) {
78  return item->second;
79  }
80  TypeWithDict theType = TypeWithDict::byName(name, 0L);
81  typeMap.insert(std::make_pair(name, theType));
82  return theType;
83  }
84 
86  // This is a private static function.
87 
88  static std::string const constPrefix("const ");
89  static std::string const constSuffix(" const");
90  static size_t const constPrefixSize(constPrefix.size());
91  static size_t const constSuffixSize(constSuffix.size());
92 
93  // Handle references
94  if (name.back() == '&') {
95  assert(property == 0L);
96  property |= kIsReference;
97  return byName(name.substr(0, name.size() - 1), property);
98  }
99 
100  // Handle const qualifier
101  if (name.size() > constSuffixSize && name.back() != '*') {
102  if (name.substr(0, constPrefixSize) == constPrefix) {
103  property |= kIsConstant;
104  return byName(name.substr(constPrefixSize), property);
105  }
106  if (name.substr(name.size() - constSuffixSize) == constSuffix) {
107  property |= kIsConstant;
108  return byName(name.substr(0, name.size() - constSuffixSize), property);
109  }
110  }
111 
112  // Handle pointers
113  if (name.back() == '*') {
114  // pointer to pointer not supported
115  assert(!(property & (long)kIsPointer));
116  // C-style array of pointers is not supported
117  assert(!(property & (long)kIsArray));
118  property |= kIsPointer;
119  if (property & (long)kIsConstant) {
120  property &= ~((long)kIsConstant);
121  property |= kIsConstPointer;
122  }
123  return byName(name.substr(0, name.size() - 1), property);
124  }
125 
126  // Handle C-style arrays
127  if (name.back() == ']') {
128  // pointer to array not supported
129  assert(!(property & (long)kIsPointer));
130  // Protect against the remote possibility of '[' nested in a class type
131  size_t begin = name.find_last_of("<>:,()");
132  if (begin == std::string::npos) {
133  begin = 0;
134  } else {
135  ++begin;
136  }
137  size_t first = name.find('[', begin);
138  assert(first != std::string::npos);
139  assert(first != 0);
140  TypeWithDict ret = TypeWithDict::byName(name.substr(0, first), property);
141  ret.property_ |= kIsArray;
142  ret.arrayDimensions_ = value_ptr<std::vector<size_t> >(new std::vector<size_t>);
143  std::string const dimensions = name.substr(first);
144  char const* s = dimensions.c_str();
145  while (true) {
146  size_t x = 0;
147  int count = sscanf(s, "[%lu]", &x);
148  assert(count == 1);
149  ret.arrayDimensions_->push_back(x);
150  ++s;
151  while (*s != '\0' && *s != '[') {
152  ++s;
153  }
154  if (*s == '\0') {
155  break;
156  }
157  }
158  return ret;
159  }
160 
161  // Handle classes
162  TClass* theClass = TClass::GetClass(name.c_str());
163  if (theClass != nullptr) {
164  return TypeWithDict(theClass, property);
165  }
166 
167  // Handle enums
168  TEnum* theEnum = TEnum::GetEnum(name.c_str(), TEnum::kAutoload);
169  if (theEnum) {
170  return TypeWithDict(theEnum, property);
171  }
172 
173  // Handle built-ins
174  TDataType* theDataType = gROOT->GetType(name.c_str());
175  if (theDataType) {
176  switch (theDataType->GetType()) {
177  case kUInt_t:
178  return TypeWithDict(typeid(unsigned int), property);
179  case kInt_t:
180  return TypeWithDict(typeid(int), property);
181  case kULong_t:
182  return TypeWithDict(typeid(unsigned long), property);
183  case kLong_t:
184  return TypeWithDict(typeid(long), property);
185  case kULong64_t:
186  return TypeWithDict(typeid(unsigned long long), property);
187  case kLong64_t:
188  return TypeWithDict(typeid(long long), property);
189  case kUShort_t:
190  return TypeWithDict(typeid(unsigned short), property);
191  case kShort_t:
192  return TypeWithDict(typeid(short), property);
193  case kUChar_t:
194  return TypeWithDict(typeid(unsigned char), property);
195  case kChar_t:
196  return TypeWithDict(typeid(char), property);
197  case kBool_t:
198  return TypeWithDict(typeid(bool), property);
199  case kFloat_t:
200  return TypeWithDict(typeid(float), property);
201  case kFloat16_t:
202  return TypeWithDict(typeid(Float16_t), property);
203  case kDouble_t:
204  return TypeWithDict(typeid(double), property);
205  case kDouble32_t:
206  return TypeWithDict(typeid(Double32_t), property);
207  case kCharStar:
208  return TypeWithDict(typeid(char*), property);
209  case kDataTypeAliasSignedChar_t:
210  return TypeWithDict(typeid(signed char), property);
211  }
212  }
213 
214  if (name == "void") {
215  return TypeWithDict(typeid(void), property);
216  }
217 
218  // For a reason not understood, TClass::GetClass sometimes cannot find std::type_info
219  // by name. This simple workaround bypasses the problem.
220  // The problem really should be debugged. (testORA12)
221  if (name == "std::type_info") {
222  return TypeWithDict(typeid(std::type_info), property);
223  }
224 
225  // For a reason not understood, TClass::GetClass sometimes cannot find std::vector<T>::value_type
226  // when T is a nested class.
227  if (stripNamespace(name) == "value_type") {
228  size_t begin = name.find('<');
229  size_t end = name.rfind('>');
230  if (begin != std::string::npos && end != std::string::npos && end > ++begin) {
231  return TypeWithDict::byName(name.substr(begin, end - begin), property);
232  }
233  }
234  //std::cerr << "DEBUG BY NAME: " << name << std::endl;
235  return TypeWithDict();
236  }
237 
239  : ti_(&typeid(TypeWithDict::invalidType)),
240  class_(nullptr),
241  enum_(nullptr),
242  dataType_(nullptr),
243  arrayDimensions_(nullptr),
244  property_(0L) {}
245 
247  : ti_(rhs.ti_),
248  class_(rhs.class_),
249  enum_(rhs.enum_),
250  dataType_(rhs.dataType_),
252  property_(rhs.property_) {}
253 
255  if (isPointer()) {
256  property_ &= ~((long)kIsReference | (long)kIsConstPointer);
257  } else {
258  property_ &= ~((long)kIsConstant | (long)kIsReference);
259  }
260  return *this;
261  }
262 
264  if (this != &rhs) {
265  ti_ = rhs.ti_;
266  class_ = rhs.class_;
267  enum_ = rhs.enum_;
268  dataType_ = rhs.dataType_;
270  property_ = rhs.property_;
271  }
272  return *this;
273  }
274 
275  TypeWithDict::TypeWithDict(std::type_info const& ti) : TypeWithDict(ti, 0L) {}
276 
277  TypeWithDict::TypeWithDict(std::type_info const& ti, long property /*= 0L*/)
278  : ti_(&ti),
279  class_(TClass::GetClass(ti)),
280  enum_(nullptr),
281  dataType_(TDataType::GetDataType(TDataType::GetType(ti))),
283  property_(property) {
284  if (class_ != nullptr) {
285  return;
286  }
287 
288  // Handle pointers and arrays
289  // Must be done before dataType_ is checked, because dataType_ will be filled for char*
290  char lastChar = TypeID(*ti_).className().back();
291  if (lastChar == '*' || lastChar == ']') {
292  *this = TypeWithDict::byName(TypeID(*ti_).className());
293  return;
294  }
295 
296  if (dataType_ != nullptr) {
297  return;
298  }
299 
300  enum_ = TEnum::GetEnum(ti, TEnum::kAutoload);
301  if (enum_ != nullptr) {
302  return;
303  }
304 
305  if (ti == typeid(void)) {
306  // For some reason, "void" has a data type if accessed by name, but not by type_info.
307  dataType_ = gROOT->GetType("void");
308  return;
309  }
310 
311  // std::cerr << "DEBUG BY TI: " << name() << std::endl;
312 
313  throwTypeException("TypeWithDict): ", name());
314  }
315 
317 
318  TypeWithDict::TypeWithDict(TClass* cl, long property)
319  : ti_(cl->GetTypeInfo()),
320  class_(cl),
321  enum_(nullptr),
324  property_(property) {
325  if (ti_ == nullptr) {
326  ti_ = &typeid(TypeWithDict::dummyType);
327  }
328  }
329 
330  TypeWithDict::TypeWithDict(TEnum* enm) : TypeWithDict(enm, 0L) {}
331 
332  TypeWithDict::TypeWithDict(TEnum* enm, long property)
333  : ti_(&typeid(TypeWithDict::dummyType)),
334  class_(nullptr),
335  enum_(enm),
338  property_(property) {}
339 
340  TypeWithDict::TypeWithDict(TMethodArg* arg) : TypeWithDict(arg, 0L) {}
341 
342  TypeWithDict::TypeWithDict(TMethodArg* arg, long property)
343  : TypeWithDict(byName(arg->GetTypeName(), arg->Property() | property)) {}
344 
346  if (*ti_ == typeid(invalidType)) {
347  return false;
348  }
349  if (class_ != nullptr || dataType_ != nullptr || enum_ != nullptr) {
350  return true;
351  }
352  return false;
353  }
354 
355  bool TypeWithDict::invalidTypeInfo() const { return *ti_ == typeid(dummyType) || isPointer() || isArray(); }
356 
357  std::type_info const& TypeWithDict::typeInfo() const {
358  if (*ti_ == typeid(dummyType) || isPointer() || isArray()) {
359  // No accurate type_info
360  if (qualifiedName().c_str() != nullptr) {
361  std::string category("unknown");
362  if (isPointer()) {
363  category = "a pointer";
364  } else if (isArray()) {
365  category = "an array";
366  } else if (isEnum()) {
367  category = "an enum";
368  } else if (isClass()) {
369  throw Exception(errors::DictionaryNotFound) << "No Dictionary for class: '" << name() << "'" << std::endl;
370  }
372  << "Function TypeWithDict::typeInfo: Type\n"
373  << qualifiedName() << "\ndoes not have valid type_info information in ROOT\n"
374  << "because it is " << category << ".\n";
375  }
376  }
377  return *ti_;
378  }
379 
380  TClass* TypeWithDict::getClass() const {
381  if (isPointer() || isArray()) {
382  return nullptr;
383  }
384  return class_;
385  }
386 
387  TEnum* TypeWithDict::getEnum() const {
388  if (isPointer() || isArray()) {
389  return nullptr;
390  }
391  return enum_;
392  }
393 
394  TDataType* TypeWithDict::getDataType() const {
395  if (isPointer() || isArray()) {
396  return nullptr;
397  }
398  return dataType_;
399  }
400 
401  long TypeWithDict::getProperty() const { return property_; }
402 
403  bool TypeWithDict::isClass() const {
404  // Note: This really means is class, struct, or union.
405  return class_ != nullptr && !isPointer() && !isArray();
406  }
407 
408  bool TypeWithDict::isConst() const { return (property_ & (long)kIsConstant); }
409 
410  bool TypeWithDict::isArray() const { return (property_ & (long)kIsArray); }
411 
412  bool TypeWithDict::isEnum() const { return enum_ != nullptr && !isPointer() && !isArray(); }
413 
414  bool TypeWithDict::isFundamental() const { return dataType_ != nullptr && !isPointer() && !isArray(); }
415 
416  bool TypeWithDict::isPointer() const { return (property_ & (long)kIsPointer); }
417 
418  bool TypeWithDict::isReference() const { return (property_ & (long)kIsReference); }
419 
420  bool TypeWithDict::isTemplateInstance() const { return (isClass() && name().back() == '>'); }
421 
422  bool TypeWithDict::isTypedef() const {
423  if (class_ != nullptr || dataType_ != nullptr || enum_ != nullptr || *ti_ == typeid(invalidType)) {
424  return false;
425  }
426  return true;
427  }
428 
429  bool TypeWithDict::isVirtual() const { return isClass() && (class_->ClassProperty() & (long)kClassHasVirtual); }
430 
431  void TypeWithDict::print(std::ostream& os) const { os << name(); }
432 
434  std::string cName = qualifiedName();
435  // Get rid of silly ROOT typedefs
436  replaceString(cName, "ULong64_t", "unsigned long long");
437  replaceString(cName, "Long64_t", "long long");
438  return cName;
439  }
440 
442  std::string qname(name());
443  if (isConst() && !isPointer()) {
444  qname = "const " + qname;
445  } else if (property_ & kIsConstPointer) {
446  qname += " const";
447  }
448  if (isReference()) {
449  qname += '&';
450  }
451  return qname;
452  }
453 
455 
457  if (*ti_ == typeid(invalidType)) {
458  return std::string();
459  }
460  std::ostringstream out;
461  if (isPointer() && isConst()) {
462  out << "const ";
463  }
464  if (enum_ != nullptr) {
465  if (enum_->GetClass()) {
466  out << std::string(enum_->GetClass()->GetName());
467  out << "::";
468  }
469  out << enum_->GetName();
470  } else if (*ti_ == typeid(dummyType) && isClass()) {
471  out << class_->GetName();
472  } else {
473  out << TypeID(*ti_).className();
474  }
475  if (isPointer()) {
476  out << '*';
477  }
478  if (isArray()) {
479  for (size_t i = 0; i < arrayDimension(); ++i) {
480  out << '[';
481  out << std::dec << maximumIndex(i);
482  out << ']';
483  }
484  }
485  return out.str();
486  }
487 
489 
491 
492  size_t TypeWithDict::size() const {
493  size_t nBytes = 0;
494  if (isPointer()) {
495  nBytes = sizeof(void*);
496  } else if (class_ != nullptr) {
497  nBytes = class_->GetClassSize();
498  } else if (dataType_ != nullptr) {
499  nBytes = dataType_->Size();
500  } else if (enum_ != nullptr) {
501  nBytes = sizeof(int);
502  }
503  if (isArray()) {
504  nBytes *= arrayLength();
505  }
506  return nBytes;
507  }
508 
509  size_t TypeWithDict::arrayLength() const {
510  assert(isArray());
511  size_t theLength = 1;
512  for (size_t i = 0; i < arrayDimension(); ++i) {
513  theLength *= maximumIndex(i);
514  }
515  return theLength;
516  }
517 
519  assert(isArray());
520  return arrayDimensions_->size();
521  }
522 
523  size_t TypeWithDict::maximumIndex(size_t dim) const {
524  assert(isArray());
525  return (*arrayDimensions_)[dim];
526  }
527 
529  if (isClass()) {
530  return class_->GetListOfDataMembers()->GetSize();
531  }
532  if (isEnum()) {
533  return enum_->GetConstants()->GetSize();
534  }
535  return 0;
536  }
537 
539  if (isClass()) {
540  return class_->GetListOfMethods()->GetSize();
541  }
542  return 0;
543  }
544 
545  void const* TypeWithDict::pointerToBaseType(void const* ptr, TypeWithDict const& derivedType) const {
546  if (!isClass()) {
547  return ptr;
548  }
549  if (this->ti_ == derivedType.ti_ || *this->ti_ == *derivedType.ti_) {
550  return ptr;
551  }
552  int offset = derivedType.getBaseClassOffset(*this);
553  if (offset < 0) {
554  return nullptr;
555  }
556  return static_cast<char const*>(ptr) + offset;
557  }
558 
559  void const* TypeWithDict::pointerToContainedType(void const* ptr, TypeWithDict const& derivedType) const {
560  if (!isClass()) {
561  return ptr;
562  }
563  return pointerToBaseType(ptr, derivedType);
564  }
565 
566  TypeWithDict TypeWithDict::nestedType(char const* nestedName) const { return byName(name() + "::" + nestedName); }
567 
569  return byName(name() + "::" + nestedName);
570  }
571 
573  if (isClass()) {
574  TDataMember* dataMember = class_->GetDataMember(member.c_str());
575  if (dataMember == nullptr) {
576  // Look for indirect data members
577  TRealData* realDataMember = class_->GetRealData(member.c_str());
578  if (realDataMember != nullptr) {
579  dataMember = realDataMember->GetDataMember();
580  }
581  }
582  return MemberWithDict(dataMember);
583  }
584  if (isEnum()) {
585  TClass* cl = enum_->GetClass();
586  return MemberWithDict(cl->GetDataMember(member.c_str()));
587  }
588  return MemberWithDict();
589  }
590 
592  if (!isClass()) {
593  return FunctionWithDict();
594  }
595  TMethod* meth = reinterpret_cast<TMethod*>(class_->GetListOfMethods()->FindObject(member.c_str()));
596  if (meth == nullptr) {
597  return FunctionWithDict();
598  }
599  return FunctionWithDict(meth);
600  }
601 
603  std::string const& proto,
604  bool isConst) const {
605  if (!isClass()) {
606  return FunctionWithDict();
607  }
608  std::string const& key = name() + '#' + functionName + '#' + proto;
609  auto const& item = functionMap.find(key);
610  if (item != functionMap.end()) {
611  return item->second;
612  }
613  TMethod* meth = class_->GetMethodWithPrototype(
614  functionName.c_str(), proto.c_str(), /*objectIsConst=*/isConst, /*mode=*/ROOT::kConversionMatch);
615  if (meth == nullptr) {
616  return FunctionWithDict();
617  }
618  FunctionWithDict theFunction = FunctionWithDict(meth);
619  functionMap.insert(std::make_pair(key, theFunction));
620  return theFunction;
621  }
622 
624  if (*ti_ == typeid(invalidType)) {
625  return TypeWithDict();
626  }
627  if (!isClass() && !isFundamental()) {
628  return *this;
629  }
630  return TypeWithDict(*ti_);
631  }
632 
634  if (*ti_ == typeid(invalidType)) {
635  return TypeWithDict();
636  }
637  if (isReference()) {
638  TypeWithDict newType = *this;
639  newType.property_ &= ~((long)kIsReference);
640  return newType;
641  }
642  if (isPointer()) {
643  TypeWithDict newType = *this;
644  newType.property_ &= ~((long)kIsPointer | (long)kIsConstPointer);
645  return newType;
646  }
647  if (isArray()) {
648  TypeWithDict newType = *this;
649  size_t size = newType.arrayDimensions_->size();
650  if (size == 1) {
651  newType.property_ &= ~((long)kIsArray);
653  newType.arrayDimensions_ = emptyVec;
654  } else {
655  std::vector<size_t>& dims = *newType.arrayDimensions_;
656  for (size_t i = 0; i != size; ++i) {
657  dims[i] = dims[i + 1];
658  }
659  newType.arrayDimensions_->resize(size - 1);
660  }
661  return newType;
662  }
663  return *this;
664  }
665 
667  if (!isTemplateInstance()) {
668  return "";
669  }
670  if (name() == "std::string") {
671  return std::string("std::basic_string");
672  }
674  auto begin = templateName.find('<');
675  assert(begin != std::string::npos);
676  auto end = templateName.rfind('<');
677  assert(end != std::string::npos);
678  assert(begin <= end);
679  if (begin < end) {
680  int depth = 1;
681  for (auto idx = begin + 1; idx <= end; ++idx) {
682  char c = templateName[idx];
683  if (c == '<') {
684  if (depth == 0) {
685  begin = idx;
686  }
687  ++depth;
688  } else if (c == '>') {
689  --depth;
690  assert(depth >= 0);
691  }
692  }
693  }
694  return templateName.substr(0, begin);
695  }
696 
698  if (!isClass()) {
699  return TypeWithDict();
700  }
702  auto begin = className.find('<');
703  if (begin == std::string::npos) {
704  return TypeWithDict();
705  }
706  ++begin;
707  auto end = className.rfind('>');
708  assert(end != std::string::npos);
709  assert(begin < end);
710  int depth = 0;
711  size_t argCount = 0;
712  for (auto idx = begin; idx < end; ++idx) {
713  char c = className[idx];
714  if (c == '<') {
715  ++depth;
716  } else if (c == '>') {
717  --depth;
718  assert(depth >= 0);
719  } else if ((depth == 0) && (c == ',')) {
720  if (argCount < index) {
721  begin = idx + 1;
722  ++argCount;
723  } else {
724  end = idx;
725  break;
726  }
727  }
728  }
729  assert(depth == 0);
730  if (argCount < index) {
731  return TypeWithDict();
732  }
733  return byName(className.substr(begin, end - begin));
734  }
735 
737  if (!isClass()) {
738  return false;
739  }
740  TClass* cl = class_->GetBaseClass(basename.c_str());
741  if (cl != nullptr) {
742  return true;
743  }
744  return false;
745  }
746 
747  bool TypeWithDict::hasBase(TypeWithDict const& basety) const {
748  if (!isClass()) {
749  return false;
750  }
751  if (basety.class_ == nullptr) {
752  return false;
753  }
754  TClass* cl = class_->GetBaseClass(basety.name().c_str());
755  if (cl != nullptr) {
756  return true;
757  }
758  return false;
759  }
760 
761  int TypeWithDict::getBaseClassOffset(TypeWithDict const& baseClass) const {
762  if (!isClass()) {
763  throw Exception(errors::LogicError) << "Function TypeWithDict::getBaseClassOffset(), type\n"
764  << name() << "\nis not a class\n";
765  }
766  if (baseClass.class_ == nullptr) {
767  throw Exception(errors::LogicError) << "Function TypeWithDict::getBaseClassOffset(), base type\n"
768  << name() << "\nis not a class\n";
769  }
770  int offset = class_->GetBaseClassOffset(baseClass.class_);
771  return offset;
772  }
773 
775  if (!isEnum()) {
776  throw Exception(errors::LogicError) << "Function TypeWithDict::stringToEnumValue(), type\n"
777  << name << "\nis not an enum\n";
778  }
779  TEnumConstant const* ec = enum_->GetConstant(name.c_str());
780  if (!ec) {
781  throw Exception(errors::LogicError) << "Function TypeWithDict::stringToEnumValue(), type\n"
782  << name << "\nis not an enum constant\n";
783  }
784  return static_cast<int>(ec->GetValue());
785  }
786 
787  void* TypeWithDict::allocate() const { return new char[size()]; }
788 
789  void TypeWithDict::deallocate(void* address) const { delete[] reinterpret_cast<char*>(address); }
790 
792  if (isClass()) {
793  return ObjectWithDict(*this, class_->New());
794  }
795  return ObjectWithDict(*this, new char[size()]);
796  }
797 
798  void TypeWithDict::destruct(void* address, bool dealloc) const {
799  if (isClass()) {
800  class_->Destructor(address, !dealloc);
801  return;
802  }
803  if (dealloc) {
804  delete[] reinterpret_cast<char*>(address);
805  }
806  }
807 
808  // A related free function
809  bool hasDictionary(std::type_info const& ti) {
810  if (ti.name()[1] == '\0') {
811  // returns true for built in types (single character mangled names)
812  return true;
813  }
814  return (TClassTable::GetDict(ti) != nullptr);
815  }
816 
817  bool operator==(TypeWithDict const& a, TypeWithDict const& b) { return a.name() == b.name(); }
818 
819  bool operator==(TypeWithDict const& a, std::type_info const& b) {
820  if (*a.ti_ == typeid(TypeWithDict::dummyType) || a.isPointer() || a.isArray()) {
821  // No accurate type_info
822  return a.name() == TypeID(b).className();
823  }
824  return *a.ti_ == b;
825  }
826 
827  std::ostream& operator<<(std::ostream& os, TypeWithDict const& ty) {
828  ty.print(os);
829  return os;
830  }
831 
832  //-------------------------------------------------------------
833  //
834  //
835 
837 
839  if (class_ == nullptr) {
840  return IterWithDict<TBaseClass>();
841  }
842  return IterWithDict<TBaseClass>(class_->GetListOfBases());
843  }
844 
846 
847  size_t TypeBases::size() const {
848  if (class_ == nullptr) {
849  return 0;
850  }
851  return class_->GetListOfBases()->GetSize();
852  }
853 
854  //-------------------------------------------------------------
855  //
856  //
857 
859 
861  if (class_ == nullptr) {
862  return IterWithDict<TDataMember>();
863  }
864  return IterWithDict<TDataMember>(class_->GetListOfDataMembers());
865  }
866 
868 
869  size_t TypeDataMembers::size() const {
870  if (class_ == nullptr) {
871  return 0;
872  }
873  return class_->GetListOfDataMembers()->GetSize();
874  }
875 
876  //-------------------------------------------------------------
877  //
878  //
879 
881 
883  if (class_ == nullptr) {
884  return IterWithDict<TMethod>();
885  }
886  return IterWithDict<TMethod>(class_->GetListOfMethods());
887  }
888 
890 
891  size_t TypeFunctionMembers::size() const {
892  if (class_ == nullptr) {
893  return 0;
894  }
895  return class_->GetListOfMethods(kFALSE)->GetSize();
896  }
897 
898 } // namespace edm
bool isConst() const
size_t functionMemberSize() const
type
Definition: HCALResponse.h:21
bool isEnum() const
static void throwTypeException(std::string const &function, std::string const &typeName)
Definition: TypeWithDict.cc:48
void print(std::ostream &os) const
TypeFunctionMembers(TypeWithDict const &)
size_t maximumIndex(size_t dim) const
IterWithDict< TDataMember > begin() const
IterWithDict< TBaseClass > begin() const
TypeDataMembers(TypeWithDict const &)
TypeWithDict finalType() const
IterWithDict< TBaseClass > end() const
bool isTypedef() const
long getProperty() const
void const * pointerToBaseType(void const *ptr, TypeWithDict const &derivedType) const
#define nullptr
TypeWithDict & operator=(TypeWithDict const &)
TDataType * dataType_
Definition: TypeWithDict.h:49
size_t size() const
void replaceString(std::string &demangledName, std::string const &from, std::string const &to)
std::string qualifiedName() const
IterWithDict< TMethod > begin() const
TypeWithDict nestedType(char const *) const
A arg
Definition: Factorize.h:38
bool hasBase(std::string const &) const
TypeWithDict toType() const
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:74
bool invalidTypeInfo() const
std::string unscopedName() const
TypeWithDict templateArgumentAt(size_t index) const
size_t size() const
MemberWithDict dataMemberByName(std::string const &) const
size_t arrayDimension() const
bool isArray() const
std::string templateName() const
bool isTemplateInstance() const
size_t dataMemberSize() const
TClass * getClass() const
std::string name() const
std::type_info const * ti_
Definition: TypeWithDict.h:46
std::string friendlyName(std::string const &iFullName)
std::string cppName() const
bool isVirtual() const
void const * pointerToContainedType(void const *ptr, TypeWithDict const &derivedType) const
bool isClass() const
friend bool operator==(TypeWithDict const &, std::type_info const &)
bool isFundamental() const
std::type_info const & typeInfo() const
#define end
Definition: vmac.h:39
int stringToEnumValue(std::string const &) const
FunctionWithDict functionMemberByName(std::string const &) const
std::string friendlyClassName() const
void deallocate(void *address) const
TDataType * getDataType() const
IterWithDict< TMethod > end() const
static TypeWithDict byTypeInfo(std::type_info const &ti)
Definition: TypeWithDict.cc:62
bool isReference() const
TypeWithDict & stripConstRef()
value_ptr< std::vector< size_t > > arrayDimensions_
Definition: TypeWithDict.h:50
void destruct(void *address, bool dealloc=true) const
double b
Definition: hdecay.h:120
std::string userClassName() const
TEnum * getEnum() const
size_t size() const
int getBaseClassOffset(TypeWithDict const &baseClass) const
std::string stripNamespace(std::string const &theName)
Definition: TypeID.cc:90
TypeBases(TypeWithDict const &)
#define begin
Definition: vmac.h:32
HLT enums.
double a
Definition: hdecay.h:121
std::string const & className() const
Definition: TypeID.cc:43
bool hasDictionary(std::type_info const &)
ObjectWithDict construct() const
bool isPointer() const
size_t arrayLength() const
T first(std::pair< T, U > const &p)
std::ostream & operator<<(std::ostream &ost, const HLTGlobalStatus &hlt)
Formatted printout of trigger tbale.
void * allocate() const
std::string className(const T &t)
Definition: ClassName.h:30
IterWithDict< TDataMember > end() const
TClass * class_
Definition: TypeWithDict.h:155