/********************************************************************* * typeinfo.h * * Run time type identification * * Memo: * typeid(typename) , typeid(expression) is implemented as special * function in the cint body src/G__func.c. * * As an extention, G__typeid(char *name) is defined in src/G__func.c * too for more dynamic use of the typeid. * * type_info is extended to support non-polymorphic type objects. * * In src/G__sizeof.c , G__typeid() is implemented. It relies on * specific binary layout of type_info object. If order of type_info * member declaration is modified, src/G__sizeof.c must be modified * too. * *********************************************************************/ #ifdef __CINT__ #ifndef G__TYPEINFO_H #define G__TYPEINFO_H #include /********************************************************************* * Functions embedded in cint core * Most of those functions are defined in src/sizeof.c * *********************************************************************/ // type_info typeid(expression); // type_info typeid(char *typename); // type_info G__typeid(char *expression); // long G__get_classinfo(char *item,int tagnum); // long G__get_variableinfo(char *item,long *handle,long *index,long tagnum); // long G__get_functioninfo(char *item,long *handle,long &index,long tagnum); /********************************************************************* * type_info * * Included in ANSI/ISO resolution proposal 1995 spring * *********************************************************************/ class type_info { public: virtual ~type_info() { } // type_info is polymorphic bool operator==(const type_info&) const; bool operator!=(const type_info&) const; bool before(const type_info&) const; const char* name() const; private: type_info(const type_info&); protected: // original enhancement type_info& operator=(const type_info&); // implementation dependent representation protected: long type; // intrinsic types long tagnum; // class/struct/union long typenum; // typedefs long reftype; // pointing level and reference types long size; // size of the object public: // original enhancement type_info() { } }; bool type_info::operator==(const type_info& a) const { if(reftype == a.reftype && tagnum == a.tagnum && type == a.type) return(true); else return(false); } bool type_info::operator!=(const type_info& a) const { if( *this == a ) return(false); else return(true); } bool type_info::before(const type_info& a) const { if(-1!=tagnum) return( tagnum < a.tagnum ); else if(-1!=a.tagnum) return( -1 < a.tagnum ); else return( type < a.type ); } const char* type_info::name() const { static char namestring[100]; //printf("%d %d %d %d\n",type,tagnum,typenum,reftype); strcpy(namestring,G__type2string(type,tagnum,typenum,reftype)); return(namestring); } type_info::type_info(const type_info& a) { type = a.type; tagnum = a.tagnum; typenum = a.typenum; reftype = a.reftype; size = a.size; } type_info& type_info::operator=(const type_info& a) { type = a.type; tagnum = a.tagnum; typenum = a.typenum; reftype = a.reftype; size = a.size; return(*this); } /************************************************************************** * original enhancment **************************************************************************/ type_info::type_info() { type = 0; tagnum = typenum = -1; reftype = 0; } /************************************************************************** * Further runtime type checking requirement from Fons Rademaker **************************************************************************/ /********************************************************************* * G__class_info * *********************************************************************/ class G__class_info : public type_info { public: G__class_info() { init(); } G__class_info(type_info& a) { init(a); } G__class_info(char *classname) { init(G__typeid(classname)); } void init() { typenum = -1; reftype = 0; tagnum = G__get_classinfo("next",-1); size = G__get_classinfo("size",tagnum); type = G__get_classinfo("type",tagnum); } void init(type_info& a) { type_info *p=this; *p = a; } G__class_info& operator=(G__class_info& a) { type = a.type; tagnum = a.tagnum; typenum = a.typenum; reftype = a.reftype; size = a.size; } G__class_info& operator=(type_info& a) { init(a); } G__class_info* next() { tagnum=G__get_classinfo("next",tagnum); if(-1!=tagnum) return(this); else { size = type = 0; return((G__class_info*)NULL); } } char *title() { return((char*)G__get_classinfo("title",tagnum)); } // char *name() is inherited from type_info char *baseclass() { return((char*)G__get_classinfo("baseclass",tagnum)); } int isabstract() { return((int)G__get_classinfo("isabstract",tagnum)); } // can be implemented // int iscompiled(); int Tagnum() { return(tagnum); } }; /********************************************************************* * G__variable_info * *********************************************************************/ class G__variable_info { public: G__variable_info() { init(); } G__variable_info(G__class_info& a) { init(a); } G__variable_info(char *classname) { init(G__class_info(classname)); } void init() { G__get_variableinfo("new",&handle,&index,tagnum=-1); } void init(G__class_info& a) { G__get_variableinfo("new",&handle,&index,tagnum=a.Tagnum()); } G__variable_info* next() { if(G__get_variableinfo("next",&handle,&index,tagnum)) return(this); else return((G__variable_info*)NULL); } char *title() { return((char*)G__get_variableinfo("title",&handle,&index,tagnum)); } char *name() { return((char*)G__get_variableinfo("name",&handle,&index,tagnum)); } char *type() { return((char*)G__get_variableinfo("type",&handle,&index,tagnum)); } int offset() { return((int)G__get_variableinfo("offset",&handle,&index,tagnum)); } // can be implemented // char *access(); // return public,protected,private // int isstatic(); // int iscompiled(); private: long handle; // pointer to variable table long index; long tagnum; // class/struct identity }; /********************************************************************* * G__function_info * *********************************************************************/ class G__function_info { public: G__function_info() { init(); } G__function_info(G__class_info& a) { init(a); } G__function_info(char *classname) { init(G__class_info(classname)); } void init() { G__get_functioninfo("new",&handle,&index,tagnum=-1); } // initialize for global function void init(G__class_info& a) { G__get_functioninfo("new",&handle,&index,tagnum=a.Tagnum()); } // initialize for member function G__function_info* next() { if(G__get_functioninfo("next",&handle,&index,tagnum)) return(this); else return((G__function_info*)NULL); } char *title() { return((char*)G__get_functioninfo("title",&handle,&index,tagnum)); } char *name() { return((char*)G__get_functioninfo("name",&handle,&index,tagnum)); } char *type() { return((char*)G__get_functioninfo("type",&handle,&index,tagnum)); } char *arglist() { return((char*)G__get_functioninfo("arglist",&handle,&index,tagnum)); } // can be implemented // char *access(); // return public,protected,private // int isstatic(); // int iscompiled(); // int isvirtual(); // int ispurevirtual(); private: long handle; // pointer to variable table long index; long tagnum; // class/struct identity }; /********************************************************************* * G__string_buf * * This struct is used as temporary object for returning title strings. * Size of buf[] limits maximum length of the title string you can * describe. You can increase size of it here to increase it. * *********************************************************************/ struct G__string_buf { char buf[256]; }; /********************************************************************* * Example code * * Following functions are the examples of how to use the type info * facilities. * *********************************************************************/ #ifdef __CINT__ void G__list_class(void) { G__class_info a; do { printf("%s:%s =%d '%s'\n",a.name(),a.baseclass(),a.isabstract(),a.title()); } while(a.next()); } void G__list_class(char *classname) { G__list_memvar(classname); G__list_memfunc(classname); } void G__list_memvar(char *classname) { G__variable_info a=G__variable_info(G__typeid(classname)); do { printf("%s %s; offset=%d '%s'\n",a.type(),a.name(),a.offset(),a.title()); } while(a.next()); } void G__list_memfunc(char *classname) { G__function_info a=G__function_info(G__typeid(classname)); do { printf("%s %s(%s) '%s'\n",a.type(),a.name(),a.arglist(),a.title()); } while(a.next()); } #endif #endif /* of G__TYPEINFO_H */ #endif /* __CINT__ */