13 #include "TClassTable.h" 14 #include "TDataType.h" 16 #include "TEnumConstant.h" 17 #include "TMethodArg.h" 18 #include "TRealData.h" 21 #include "tbb/concurrent_unordered_map.h" 36 using Map = tbb::concurrent_unordered_map<std::string, TypeWithDict>;
38 using FunctionMap = tbb::concurrent_unordered_map<std::string, FunctionWithDict>;
39 FunctionMap functionMap;
41 struct TypeIndexHash {
42 std::size_t operator()(std::type_index ti)
const {
return ti.hash_code(); }
45 using TypeIndexMap = tbb::concurrent_unordered_map<std::type_index, TypeWithDict, TypeIndexHash>;
46 TypeIndexMap typeIndexMap;
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.";
64 auto index = std::type_index(ti);
65 auto const& item = typeIndexMap.find(
index);
66 if (item != typeIndexMap.end()) {
70 typeIndexMap.insert(std::make_pair(
index, theType));
76 auto const& item = typeMap.find(name);
77 if (item != typeMap.end()) {
81 typeMap.insert(std::make_pair(name, theType));
90 static size_t const constPrefixSize(constPrefix.size());
91 static size_t const constSuffixSize(constSuffix.size());
94 if (name.back() ==
'&') {
95 assert(property == 0
L);
96 property |= kIsReference;
97 return byName(name.substr(0, name.size() - 1), property);
101 if (name.size() > constSuffixSize && name.back() !=
'*') {
102 if (name.substr(0, constPrefixSize) == constPrefix) {
103 property |= kIsConstant;
104 return byName(name.substr(constPrefixSize), property);
106 if (name.substr(name.size() - constSuffixSize) == constSuffix) {
107 property |= kIsConstant;
108 return byName(name.substr(0, name.size() - constSuffixSize), property);
113 if (name.back() ==
'*') {
115 assert(!(property & (
long)kIsPointer));
117 assert(!(property & (
long)kIsArray));
118 property |= kIsPointer;
119 if (property & (
long)kIsConstant) {
120 property &= ~((long)kIsConstant);
121 property |= kIsConstPointer;
123 return byName(name.substr(0, name.size() - 1), property);
127 if (name.back() ==
']') {
129 assert(!(property & (
long)kIsPointer));
131 size_t begin = name.find_last_of(
"<>:,()");
132 if (begin == std::string::npos) {
137 size_t first = name.find(
'[', begin);
138 assert(first != std::string::npos);
144 char const*
s = dimensions.c_str();
147 int count = sscanf(s,
"[%lu]", &x);
151 while (*s !=
'\0' && *s !=
'[') {
162 TClass* theClass = TClass::GetClass(name.c_str());
163 if (theClass !=
nullptr) {
168 TEnum* theEnum = TEnum::GetEnum(name.c_str(), TEnum::kAutoload);
174 TDataType* theDataType = gROOT->GetType(name.c_str());
176 switch (theDataType->GetType()) {
186 return TypeWithDict(
typeid(
unsigned long long), property);
209 case kDataTypeAliasSignedChar_t:
214 if (name ==
"void") {
221 if (name ==
"std::type_info") {
228 size_t begin = name.find(
'<');
229 size_t end = name.rfind(
'>');
230 if (begin != std::string::npos && end != std::string::npos && end > ++begin) {
256 property_ &= ~((long)kIsReference | (
long)kIsConstPointer);
258 property_ &= ~((long)kIsConstant | (
long)kIsReference);
279 class_(TClass::GetClass(ti)),
281 dataType_(TDataType::GetDataType(TDataType::GetType(ti))),
291 if (lastChar ==
'*' || lastChar ==
']') {
300 enum_ = TEnum::GetEnum(ti, TEnum::kAutoload);
301 if (
enum_ !=
nullptr) {
305 if (ti ==
typeid(
void)) {
319 :
ti_(cl->GetTypeInfo()),
325 if (
ti_ ==
nullptr) {
363 category =
"a pointer";
365 category =
"an array";
367 category =
"an enum";
372 <<
"Function TypeWithDict::typeInfo: Type\n" 373 <<
qualifiedName() <<
"\ndoes not have valid type_info information in ROOT\n" 374 <<
"because it is " << category <<
".\n";
444 qname =
"const " + qname;
445 }
else if (
property_ & kIsConstPointer) {
460 std::ostringstream
out;
464 if (
enum_ !=
nullptr) {
465 if (
enum_->GetClass()) {
469 out <<
enum_->GetName();
495 nBytes =
sizeof(
void*);
496 }
else if (
class_ !=
nullptr) {
497 nBytes =
class_->GetClassSize();
500 }
else if (
enum_ !=
nullptr) {
501 nBytes =
sizeof(
int);
511 size_t theLength = 1;
530 return class_->GetListOfDataMembers()->GetSize();
533 return enum_->GetConstants()->GetSize();
540 return class_->GetListOfMethods()->GetSize();
549 if (this->
ti_ == derivedType.
ti_ || *this->ti_ == *derivedType.
ti_) {
556 return static_cast<char const*
>(ptr) + offset;
574 TDataMember* dataMember =
class_->GetDataMember(member.c_str());
575 if (dataMember ==
nullptr) {
577 TRealData* realDataMember =
class_->GetRealData(member.c_str());
578 if (realDataMember !=
nullptr) {
579 dataMember = realDataMember->GetDataMember();
585 TClass*
cl =
enum_->GetClass();
595 TMethod*
meth =
reinterpret_cast<TMethod*
>(
class_->GetListOfMethods()->FindObject(member.c_str()));
596 if (meth ==
nullptr) {
609 auto const& item = functionMap.find(key);
610 if (item != functionMap.end()) {
613 TMethod*
meth =
class_->GetMethodWithPrototype(
614 functionName.c_str(), proto.c_str(),
isConst, ROOT::kConversionMatch);
615 if (meth ==
nullptr) {
619 functionMap.insert(std::make_pair(key, theFunction));
639 newType.
property_ &= ~((long)kIsReference);
644 newType.
property_ &= ~((long)kIsPointer | (
long)kIsConstPointer);
656 for (
size_t i = 0;
i !=
size; ++
i) {
657 dims[
i] = dims[
i + 1];
670 if (
name() ==
"std::string") {
674 auto begin = templateName.find(
'<');
675 assert(
begin != std::string::npos);
676 auto end = templateName.rfind(
'<');
677 assert(
end != std::string::npos);
682 char c = templateName[
idx];
688 }
else if (c ==
'>') {
694 return templateName.substr(0,
begin);
702 auto begin = className.find(
'<');
703 if (
begin == std::string::npos) {
707 auto end = className.rfind(
'>');
708 assert(
end != std::string::npos);
713 char c = className[
idx];
716 }
else if (c ==
'>') {
719 }
else if ((depth == 0) && (c ==
',')) {
720 if (argCount < index) {
730 if (argCount < index) {
740 TClass*
cl =
class_->GetBaseClass(basename.c_str());
751 if (basety.
class_ ==
nullptr) {
754 TClass*
cl =
class_->GetBaseClass(basety.
name().c_str());
764 <<
name() <<
"\nis not a class\n";
766 if (baseClass.
class_ ==
nullptr) {
768 <<
name() <<
"\nis not a class\n";
777 << name <<
"\nis not an enum\n";
779 TEnumConstant
const*
ec =
enum_->GetConstant(name.c_str());
782 << name <<
"\nis not an enum constant\n";
784 return static_cast<int>(ec->GetValue());
800 class_->Destructor(address, !dealloc);
804 delete[]
reinterpret_cast<char*
>(address);
810 if (ti.name()[1] ==
'\0') {
814 return (TClassTable::GetDict(ti) !=
nullptr);
851 return class_->GetListOfBases()->GetSize();
873 return class_->GetListOfDataMembers()->GetSize();
895 return class_->GetListOfMethods(kFALSE)->GetSize();
size_t functionMemberSize() const
static void throwTypeException(std::string const &function, std::string const &typeName)
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
void const * pointerToBaseType(void const *ptr, TypeWithDict const &derivedType) const
TypeWithDict & operator=(TypeWithDict 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
bool hasBase(std::string const &) const
TypeWithDict toType() const
static TypeWithDict byName(std::string const &name)
bool invalidTypeInfo() const
std::string unscopedName() const
TypeWithDict templateArgumentAt(size_t index) const
MemberWithDict dataMemberByName(std::string const &) const
size_t arrayDimension() const
std::string templateName() const
bool isTemplateInstance() const
size_t dataMemberSize() const
TClass * getClass() const
std::type_info const * ti_
std::string friendlyName(std::string const &iFullName)
std::string cppName() const
void const * pointerToContainedType(void const *ptr, TypeWithDict const &derivedType) const
friend bool operator==(TypeWithDict const &, std::type_info const &)
bool isFundamental() const
std::type_info const & typeInfo() const
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)
TypeWithDict & stripConstRef()
value_ptr< std::vector< size_t > > arrayDimensions_
void destruct(void *address, bool dealloc=true) const
std::string userClassName() const
int getBaseClassOffset(TypeWithDict const &baseClass) const
std::string stripNamespace(std::string const &theName)
TypeBases(TypeWithDict const &)
std::string const & className() const
bool hasDictionary(std::type_info const &)
ObjectWithDict construct() 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.
std::string className(const T &t)
IterWithDict< TDataMember > end() const