00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TClass.h"
00013 #include "TError.h"
00014 #include "TInterpreter.h"
00015 #include "TIsAProxy.h"
00016
00017 #include <map>
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 namespace {
00029 struct DynamicType {
00030
00031
00032
00033 virtual ~DynamicType() {}
00034 };
00035 }
00036
00037 typedef std::map<long, TClass*> ClassMap_t;
00038 inline ClassMap_t *GetMap(void* p)
00039 {
00040 return (ClassMap_t*)p;
00041 }
00042
00043
00044 TIsAProxy::TIsAProxy(const std::type_info& typ, void* ctxt)
00045 : fType(&typ), fLastType(&typ), fClass(0), fLastClass(0),
00046 fVirtual(false), fContext(ctxt), fInit(false)
00047 {
00048
00049
00050 ::new(fSubTypes) ClassMap_t();
00051 if ( sizeof(ClassMap_t) > sizeof(fSubTypes) ) {
00052 Fatal("TIsAProxy::TIsAProxy",
00053 "Classmap size is badly adjusted: it needs %u instead of %u bytes.",
00054 (UInt_t)sizeof(ClassMap_t), (UInt_t)sizeof(fSubTypes));
00055 }
00056 }
00057
00058
00059 TIsAProxy::TIsAProxy(const TIsAProxy& iap) :
00060 TVirtualIsAProxy(iap),
00061 fType(iap.fType),
00062 fLastType(iap.fLastType),
00063 fClass(iap.fClass),
00064 fLastClass(iap.fLastClass),
00065 fVirtual(iap.fVirtual),
00066 fContext(iap.fContext),
00067 fInit(iap.fInit)
00068 {
00069
00070 for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
00071 }
00072
00073
00074 TIsAProxy& TIsAProxy::operator=(const TIsAProxy& iap)
00075 {
00076
00077 if(this!=&iap) {
00078 TVirtualIsAProxy::operator=(iap);
00079 fType=iap.fType;
00080 fLastType=iap.fLastType;
00081 fClass=iap.fClass;
00082 fLastClass=iap.fLastClass;
00083 for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
00084 fVirtual=iap.fVirtual;
00085 fContext=iap.fContext;
00086 fInit=iap.fInit;
00087 }
00088 return *this;
00089 }
00090
00091
00092 TIsAProxy::~TIsAProxy()
00093 {
00094
00095
00096 ClassMap_t* m = GetMap(fSubTypes);
00097 m->clear();
00098 m->~ClassMap_t();
00099 }
00100
00101
00102 void TIsAProxy::SetClass(TClass *cl)
00103 {
00104
00105 GetMap(fSubTypes)->clear();
00106 fClass = fLastClass = cl;
00107 }
00108
00109
00110 TClass* TIsAProxy::operator()(const void *obj)
00111 {
00112
00113
00114 if ( !fInit ) {
00115 fInit = kTRUE;
00116 if ( !fClass && fType ) fClass = TClass::GetClass(*fType);
00117 if ( !fClass) return 0;
00118 fClass->Property();
00119 if ( fClass->GetClassInfo() ) {
00120 fVirtual = (gCint->ClassInfo_ClassProperty(fClass->GetClassInfo())&G__CLS_HASVIRTUAL) == G__CLS_HASVIRTUAL;
00121 }
00122 }
00123 if ( !obj || !fVirtual ) {
00124 return fClass;
00125 } else {
00126
00127
00128 Long_t offset = **(Long_t**)obj;
00129 if ( offset == 0 ) return fClass;
00130
00131 DynamicType* ptr = (DynamicType*)obj;
00132 const std::type_info* typ = &typeid(*ptr);
00133
00134 if ( typ == fType ) {
00135 return fClass;
00136 }
00137 else if ( typ == fLastType ) {
00138 return fLastClass;
00139 }
00140
00141 else if ( 0 != (fLastClass=(*GetMap(fSubTypes))[long(typ)]) ) {
00142 fLastType = typ;
00143 }
00144
00145 else {
00146 fLastClass = TClass::GetClass(*typ);
00147 fLastType = typ;
00148 (*GetMap(fSubTypes))[long(fLastType)] = fLastClass;
00149 }
00150 }
00151 return fLastClass;
00152 }