Typename of basic types

Hi,

I’m trying to implement a generic tree reader. To do this I need to be able to retrieve the complete type name of a variable. This is easy for objects that derive from TObject but I have no idea how to get the full typename of an Int_t for example. I tried with typeid(dummy_int).name(), but that returns only “i”.

Does someone have an idea how to accomplish this?

Thanks,
Johannes Asal

[quote]Does someone have an idea how to accomplish this? [/quote]Did you try to use the TClass object representing your classes to loop through the data member?

Also the TTree itself knows its content and you should be able to ask it about the real typename.

Philippe

Hi Philippe,

yeah i tried that. Retrieving the types from the tree works fine. The problem is, I need to get the typename of a dummy variable in the template function to do a type check:

[code]template
type Get(TString name)
{
//Here is my problem…
//type dummy;

std::map<TString, void*>::iterator it = dataMap.find(name);
if(it == dataMap.end())
{
	E_MESSAGE("Data object not found (" << name << ")");
	throw bad_varname();
}

//How to do the type check here?
/*if(typeid(dataMap[name]).name() != typeid(dummy).name())
{
	E_MESSAGE("Wrong object type (requested " << typeClass->GetName()
	<< ", is " << dataMap[name].second << ")");
	throw bad_vartype();
}*/

return *(static_cast<type*>(dataMap[name]));

}
[/code]

The typeid on dataMap[name] always returns Pv (pointer to void). So I thought maybe I could use the type info from the tree. But that would be “Int_t” for example. My question is now, is there some easy way to retrieve the type of the dummy variable in a common way for the basic types like Int_t, Double_t? Maybe there is something built in into ROOT or CINT that I haven’t found yet. If not, I would need to make a switch on the typeid names like “i”, “d”, “Pv”, etc. and generate the matching ROOT type name from that to compare them.

Thanks,
Johannes

Hi,

we have that switch statement already :slight_smile: If you have access to the TTree’s TLeaf, say in leafMap[name], you can use TLeaf* leaf = leafMap[name]; TDataType * leafType = gROOT->GetListOfTypes()->FindObject(leaf->GetDataType()); if(!leafType || leafType->GetTypeName() != TDataType::GetType(typeid(type))) throw bad_vartype();This will probably fail with pointers, though; you’ll have to do some string manipulation for that.

Axel.

Hi,

That’s what I suspected. Thanks for your answers.

Cheers,
Johannes

Hi,
What about something like:[code]
void *Get(TString name, typeinfo &info, Bool_t ispointer) {
// Get ROOT type name of simple types:
const char *type_name TDataType::GetTypeName(TDataType::GetType(info));

std::map<TString, pair<TString,void*> >::iterator it = dataMap.find(name);
if(it == dataMap.end())
{
E_MESSAGE(“Data object not found (” << name << “)”);
throw bad_varname();
}

//How to do the type check here?
if( (*it).first != type_name) {
{
E_MESSAGE("Wrong object type (requested " << typeClass->GetName()
<< ", is " << dataMap[name].second << “)”);
throw bad_vartype();
}
return (*it).second;
}

template<class type*> type* Get(TString name)
{
return (static_cast<type*>(Get(name,typeid(type), true)));
}
template type Get(TString name)
{
return (static_cast<type>(Get(name,typeid(type), true)));
}[/code]

Cheers,
Philippe

Hi Philippe,

that works fine! But only in compiled programs. The interpreter crashes with a segfault when I try to do the TDataType::GetType():

#10 <signal handler called> #11 0x41993904 in strcmp () from /lib/libc.so.6 #12 0x4023c8e0 in TDataType::GetType () from /afs/physik.uni-freiburg.de/opt/root_v5.14/lib/libCore.so

In v5.14 btw. I don’t need it interpreted, but maybe someone wants to fix that.

Cheers,
Johannes

[quote]The interpreter crashes …[/quote]Yes the interpreter’s typeinfo and the compiler’s are incompatible. We are planning on adding protection for this type of cases (same class name in interpreter and compiler but incompatible) once we are finished upgrading CINT to use reflex.

Cheers,
Philippe.

Hi there,
How far are we today?
How could one check basic types (Int_t, …) within CINT?
I made several unsuccessful attempts with TDataType.
Does CINTex need to be enabled?
Cheers,
Z

Hi,

For various reasons we decided to no longer pursue updating Cint to use Reflex (and are prototype alternatives) and so enabling Cintex is only useful if you explicitly generate Reflex dictionary. If you really need to check for basic types in a consistent way, we recommend you compile your script via ACLiC.

Philippe.

Thanks Philippe.
Will CLING be able to deal with this easily?
Cheers, Z

Hi,

In the cling context there would be very little difference between ‘interpreted’ and ‘compiled’ code so apriori yes.

Philippe.

:smiley:
So cling on jup-pu’ ! :wink:
Qa tlho’
Z