TIsAProxy.cxx

Go to the documentation of this file.
00001 // @(#)root/meta:$Id: TIsAProxy.cxx 35067 2010-08-30 12:19:01Z pcanal $
00002 // Author: Markus Frank 20/05/2005
00003 
00004 /*************************************************************************
00005 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006 * All rights reserved.                                                  *
00007 *                                                                       *
00008 * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
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 // TClass                                                               //
00023 //                                                                      //
00024 // TIsAProxy implementation class.                                      //
00025 //                                                                      //
00026 //////////////////////////////////////////////////////////////////////////
00027 
00028 namespace {
00029    struct DynamicType {
00030       // Helper class to enable typeid on any address
00031       // Used in code similar to:
00032       //    typeid( * (DynamicType*) void_ptr );
00033       virtual ~DynamicType() {}
00034    };
00035 }
00036 
00037 typedef std::map<long, TClass*> ClassMap_t; // Internal type map
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    // Standard initializing constructor
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    //copy constructor
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    //assignement operator
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    // Standard destructor
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    // Set class pointer
00105    GetMap(fSubTypes)->clear();
00106    fClass = fLastClass = cl;
00107 }
00108 
00109 //______________________________________________________________________________
00110 TClass* TIsAProxy::operator()(const void *obj)
00111 {
00112    // IsA callback
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       // Avoid the case that the first word is a virtual_base_offset_table instead of
00127       // a virtual_function_table
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       // Check if type is already in sub-class cache
00141       else if ( 0 != (fLastClass=(*GetMap(fSubTypes))[long(typ)]) )  {
00142          fLastType = typ;
00143       }
00144       // Last resort: lookup root class
00145       else   {
00146          fLastClass = TClass::GetClass(*typ);
00147          fLastType = typ;
00148          (*GetMap(fSubTypes))[long(fLastType)] = fLastClass;
00149       }
00150    }
00151    return fLastClass;
00152 }

Generated on Tue Jul 5 14:11:55 2011 for ROOT_528-00b_version by  doxygen 1.5.1