ROOT logo
// @(#)root/meta:$Id: TIsAProxy.cxx 24077 2008-05-31 19:39:09Z brun $
// Author: Markus Frank 20/05/2005

/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/

#include "TClass.h"
#include "TError.h"
#include "TInterpreter.h"
#include "TIsAProxy.h"

#include <map>


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TClass                                                               //
//                                                                      //
// TIsAProxy implementation class.                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

namespace {
   struct DynamicType {
      // Helper class to enable typeid on any address
      // Used in code similar to:
      //    typeid( * (DynamicType*) void_ptr );
      virtual ~DynamicType() {}
   };
}

typedef std::map<long, TClass*> ClassMap_t; // Internal type map
inline ClassMap_t *GetMap(void* p)
{
   return (ClassMap_t*)p;
}

//______________________________________________________________________________
TIsAProxy::TIsAProxy(const std::type_info& typ, void* ctxt)
   : fType(&typ), fLastType(&typ), fClass(0), fLastClass(0),
     fVirtual(false), fContext(ctxt), fInit(false)
{
   // Standard initializing constructor

   ::new(fSubTypes) ClassMap_t();
   if ( sizeof(ClassMap_t) > sizeof(fSubTypes) ) {
      Fatal("TIsAProxy::TIsAProxy",
         "Classmap size is badly adjusted: it needs %d instead of %d bytes.",
         sizeof(ClassMap_t), sizeof(fSubTypes));
   }
}

//______________________________________________________________________________
TIsAProxy::TIsAProxy(const TIsAProxy& iap) :
  TVirtualIsAProxy(iap),
  fType(iap.fType),
  fLastType(iap.fLastType),
  fClass(iap.fClass),
  fLastClass(iap.fLastClass),
  fVirtual(iap.fVirtual),
  fContext(iap.fContext),
  fInit(iap.fInit)
{
   //copy constructor
   for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
}

//______________________________________________________________________________
TIsAProxy& TIsAProxy::operator=(const TIsAProxy& iap)
{
   //assignement operator
   if(this!=&iap) {
      TVirtualIsAProxy::operator=(iap);
      fType=iap.fType;
      fLastType=iap.fLastType;
      fClass=iap.fClass;
      fLastClass=iap.fLastClass;
      for(Int_t i=0; i<72; i++) fSubTypes[i]=iap.fSubTypes[i];
      fVirtual=iap.fVirtual;
      fContext=iap.fContext;
      fInit=iap.fInit;
   } 
   return *this;
}

//______________________________________________________________________________
TIsAProxy::~TIsAProxy()
{
   // Standard destructor

   ClassMap_t* m = GetMap(fSubTypes);
   m->clear();
   m->~ClassMap_t();
}

//______________________________________________________________________________
void TIsAProxy::SetClass(TClass *cl)
{
   // Set class pointer
   GetMap(fSubTypes)->clear();
   fClass = fLastClass = cl;
}

//______________________________________________________________________________
TClass* TIsAProxy::operator()(const void *obj)
{
   // IsA callback

   if ( !fInit )  {
      fInit = kTRUE;
      if ( !fClass && fType ) fClass = TClass::GetClass(*fType);
      fClass->Property();
      if ( fClass->GetClassInfo() )  {
         fVirtual = (gCint->ClassInfo_ClassProperty(fClass->GetClassInfo())&G__CLS_HASVIRTUAL) == G__CLS_HASVIRTUAL;
      }
   }
   if ( !obj || !fVirtual )  {
      return fClass;
   } else  {
      // Avoid the case that the first word is a virtual_base_offset_table instead of
      // a virtual_function_table
      Long_t offset = **(Long_t**)obj;
      if ( offset == 0 ) return fClass;

      DynamicType* ptr = (DynamicType*)obj;
      const std::type_info* typ = &typeid(*ptr);

      if ( typ == fType )  {
         return fClass;
      }
      else if ( typ == fLastType )  {
         return fLastClass;
      }
      // Check if type is already in sub-class cache
      else if ( 0 != (fLastClass=(*GetMap(fSubTypes))[long(typ)]) )  {
         fLastType = typ;
      }
      // Last resort: lookup root class
      else   {
         fLastClass = TClass::GetClass(*typ);
         fLastType = typ;
         (*GetMap(fSubTypes))[long(fLastType)] = fLastClass;
      }
   }
   return fLastClass;
}
 TIsAProxy.cxx:1
 TIsAProxy.cxx:2
 TIsAProxy.cxx:3
 TIsAProxy.cxx:4
 TIsAProxy.cxx:5
 TIsAProxy.cxx:6
 TIsAProxy.cxx:7
 TIsAProxy.cxx:8
 TIsAProxy.cxx:9
 TIsAProxy.cxx:10
 TIsAProxy.cxx:11
 TIsAProxy.cxx:12
 TIsAProxy.cxx:13
 TIsAProxy.cxx:14
 TIsAProxy.cxx:15
 TIsAProxy.cxx:16
 TIsAProxy.cxx:17
 TIsAProxy.cxx:18
 TIsAProxy.cxx:19
 TIsAProxy.cxx:20
 TIsAProxy.cxx:21
 TIsAProxy.cxx:22
 TIsAProxy.cxx:23
 TIsAProxy.cxx:24
 TIsAProxy.cxx:25
 TIsAProxy.cxx:26
 TIsAProxy.cxx:27
 TIsAProxy.cxx:28
 TIsAProxy.cxx:29
 TIsAProxy.cxx:30
 TIsAProxy.cxx:31
 TIsAProxy.cxx:32
 TIsAProxy.cxx:33
 TIsAProxy.cxx:34
 TIsAProxy.cxx:35
 TIsAProxy.cxx:36
 TIsAProxy.cxx:37
 TIsAProxy.cxx:38
 TIsAProxy.cxx:39
 TIsAProxy.cxx:40
 TIsAProxy.cxx:41
 TIsAProxy.cxx:42
 TIsAProxy.cxx:43
 TIsAProxy.cxx:44
 TIsAProxy.cxx:45
 TIsAProxy.cxx:46
 TIsAProxy.cxx:47
 TIsAProxy.cxx:48
 TIsAProxy.cxx:49
 TIsAProxy.cxx:50
 TIsAProxy.cxx:51
 TIsAProxy.cxx:52
 TIsAProxy.cxx:53
 TIsAProxy.cxx:54
 TIsAProxy.cxx:55
 TIsAProxy.cxx:56
 TIsAProxy.cxx:57
 TIsAProxy.cxx:58
 TIsAProxy.cxx:59
 TIsAProxy.cxx:60
 TIsAProxy.cxx:61
 TIsAProxy.cxx:62
 TIsAProxy.cxx:63
 TIsAProxy.cxx:64
 TIsAProxy.cxx:65
 TIsAProxy.cxx:66
 TIsAProxy.cxx:67
 TIsAProxy.cxx:68
 TIsAProxy.cxx:69
 TIsAProxy.cxx:70
 TIsAProxy.cxx:71
 TIsAProxy.cxx:72
 TIsAProxy.cxx:73
 TIsAProxy.cxx:74
 TIsAProxy.cxx:75
 TIsAProxy.cxx:76
 TIsAProxy.cxx:77
 TIsAProxy.cxx:78
 TIsAProxy.cxx:79
 TIsAProxy.cxx:80
 TIsAProxy.cxx:81
 TIsAProxy.cxx:82
 TIsAProxy.cxx:83
 TIsAProxy.cxx:84
 TIsAProxy.cxx:85
 TIsAProxy.cxx:86
 TIsAProxy.cxx:87
 TIsAProxy.cxx:88
 TIsAProxy.cxx:89
 TIsAProxy.cxx:90
 TIsAProxy.cxx:91
 TIsAProxy.cxx:92
 TIsAProxy.cxx:93
 TIsAProxy.cxx:94
 TIsAProxy.cxx:95
 TIsAProxy.cxx:96
 TIsAProxy.cxx:97
 TIsAProxy.cxx:98
 TIsAProxy.cxx:99
 TIsAProxy.cxx:100
 TIsAProxy.cxx:101
 TIsAProxy.cxx:102
 TIsAProxy.cxx:103
 TIsAProxy.cxx:104
 TIsAProxy.cxx:105
 TIsAProxy.cxx:106
 TIsAProxy.cxx:107
 TIsAProxy.cxx:108
 TIsAProxy.cxx:109
 TIsAProxy.cxx:110
 TIsAProxy.cxx:111
 TIsAProxy.cxx:112
 TIsAProxy.cxx:113
 TIsAProxy.cxx:114
 TIsAProxy.cxx:115
 TIsAProxy.cxx:116
 TIsAProxy.cxx:117
 TIsAProxy.cxx:118
 TIsAProxy.cxx:119
 TIsAProxy.cxx:120
 TIsAProxy.cxx:121
 TIsAProxy.cxx:122
 TIsAProxy.cxx:123
 TIsAProxy.cxx:124
 TIsAProxy.cxx:125
 TIsAProxy.cxx:126
 TIsAProxy.cxx:127
 TIsAProxy.cxx:128
 TIsAProxy.cxx:129
 TIsAProxy.cxx:130
 TIsAProxy.cxx:131
 TIsAProxy.cxx:132
 TIsAProxy.cxx:133
 TIsAProxy.cxx:134
 TIsAProxy.cxx:135
 TIsAProxy.cxx:136
 TIsAProxy.cxx:137
 TIsAProxy.cxx:138
 TIsAProxy.cxx:139
 TIsAProxy.cxx:140
 TIsAProxy.cxx:141
 TIsAProxy.cxx:142
 TIsAProxy.cxx:143
 TIsAProxy.cxx:144
 TIsAProxy.cxx:145
 TIsAProxy.cxx:146
 TIsAProxy.cxx:147
 TIsAProxy.cxx:148
 TIsAProxy.cxx:149
 TIsAProxy.cxx:150
 TIsAProxy.cxx:151