TGenCollectionProxy.cxx

Go to the documentation of this file.
00001 // @(#)root/io:$Id: TGenCollectionProxy.cxx 38237 2011-02-27 19:19:48Z pcanal $
00002 // Author: Markus Frank 28/10/04
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, 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 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TGenCollectionProxy
00015 //
00016 // Proxy around an arbitrary container, which implements basic
00017 // functionality and iteration.
00018 //
00019 // In particular this is used to implement splitting and abstract
00020 // element access of any container. Access to compiled code is necessary
00021 // to implement the abstract iteration sequence and functionality like
00022 // size(), clear(), resize(). resize() may be a void operation.
00023 //
00024 //////////////////////////////////////////////////////////////////////////
00025 
00026 #include "TGenCollectionProxy.h"
00027 #include "TVirtualStreamerInfo.h"
00028 #include "TStreamerElement.h"
00029 #include "TClassEdit.h"
00030 #include "TClass.h"
00031 #include "TError.h"
00032 #include "TROOT.h"
00033 #include "TInterpreter.h"
00034 #include "Riostream.h"
00035 #include "TVirtualMutex.h"
00036 #include "TStreamerInfoActions.h"
00037 #include <stdlib.h>
00038 
00039 #define MESSAGE(which,text)
00040 
00041 std::vector<TVirtualCollectionProxy*> gSlowIterator__Proxy;
00042 
00043 //////////////////////////////////////////////////////////////////////////
00044 //                                                                      //
00045 //  class TGenVectorProxy
00046 //
00047 //   Local optimization class.
00048 //
00049 //   Collection proxies get copied. On copy we switch the type of the
00050 //   proxy to the concrete STL type. The concrete types are optimized
00051 //   for element access.
00052 //
00053 //////////////////////////////////////////////////////////////////////////
00054 class TGenVectorProxy : public TGenCollectionProxy {
00055 public:
00056    // Standard Destructor
00057    TGenVectorProxy(const TGenCollectionProxy& c) : TGenCollectionProxy(c)
00058    {
00059    }
00060    // Standard Destructor
00061    virtual ~TGenVectorProxy()
00062 {
00063    }
00064    // Return the address of the value at index 'idx'
00065    virtual void* At(UInt_t idx)
00066 {
00067       if ( fEnv && fEnv->fObject ) {
00068          fEnv->fIdx = idx;
00069          switch( idx ) {
00070          case 0:
00071             return fEnv->fStart = fFirst.invoke(fEnv);
00072          default:
00073             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00074             return ((char*)fEnv->fStart) + fValDiff*idx;
00075          }
00076       }
00077       Fatal("TGenVectorProxy","At> Logic error - no proxy object set.");
00078       return 0;
00079    }
00080    // Call to delete/destruct individual item
00081    virtual void DeleteItem(bool force, void* ptr) const
00082    {
00083       if ( force && ptr ) {
00084          fVal->DeleteItem(ptr);
00085       }
00086    }
00087 };
00088 
00089 //////////////////////////////////////////////////////////////////////////
00090 //                                                                      //
00091 //  class TGenVectorBoolProxy
00092 //
00093 //   Local optimization class.
00094 //
00095 //   Collection proxies get copied. On copy we switch the type of the
00096 //   proxy to the concrete STL type. The concrete types are optimized
00097 //   for element access.
00098 //
00099 //////////////////////////////////////////////////////////////////////////
00100 class TGenVectorBoolProxy : public TGenCollectionProxy {
00101    bool fLastValue;
00102    
00103 public:
00104    TGenVectorBoolProxy(const TGenCollectionProxy& c) : TGenCollectionProxy(c), fLastValue(false)
00105    {
00106       // Standard Constructor.
00107    }
00108    virtual ~TGenVectorBoolProxy()
00109    {
00110       // Standard Destructor.
00111    }
00112    virtual void* At(UInt_t idx)
00113    {
00114       // Return the address of the value at index 'idx'
00115       
00116       // However we can 'take' the address of the content of vector<bool>.
00117       if ( fEnv && fEnv->fObject ) {
00118          switch( idx ) {
00119             case 0:
00120                fEnv->fStart = fFirst.invoke(fEnv);
00121                fEnv->fIdx = idx;
00122                break;
00123             default:
00124                fEnv->fIdx = idx - fEnv->fIdx;
00125                if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00126                fNext.invoke(fEnv);
00127                fEnv->fIdx = idx;
00128                break;
00129          }
00130          typedef ROOT::TCollectionProxyInfo::Type<std::vector<bool> >::Env_t EnvType_t;
00131          EnvType_t *e = (EnvType_t*)fEnv;
00132          fLastValue = *(e->iter());
00133          return &fLastValue;
00134       }
00135       Fatal("TGenVectorProxy","At> Logic error - no proxy object set.");
00136       return 0;
00137    }
00138    
00139    virtual void DeleteItem(bool force, void* ptr) const
00140    {
00141       // Call to delete/destruct individual item
00142       if ( force && ptr ) {
00143          fVal->DeleteItem(ptr);
00144       }
00145    }
00146 };
00147 
00148 //////////////////////////////////////////////////////////////////////////
00149 //                                                                      //
00150 //  class TGenBitsetProxy
00151 //
00152 //   Local optimization class.
00153 //
00154 //   Collection proxies get copied. On copy we switch the type of the
00155 //   proxy to the concrete STL type. The concrete types are optimized
00156 //   for element access.
00157 //
00158 //////////////////////////////////////////////////////////////////////////
00159 class TGenBitsetProxy : public TGenCollectionProxy {
00160    
00161 public:
00162    TGenBitsetProxy(const TGenCollectionProxy& c) : TGenCollectionProxy(c)
00163    {
00164       // Standard Constructor.
00165    }
00166    virtual ~TGenBitsetProxy()
00167    {
00168       // Standard Destructor.
00169    }
00170    virtual void* At(UInt_t idx)
00171    {
00172       // Return the address of the value at index 'idx'
00173       
00174       // However we can 'take' the address of the content of vector<bool>.
00175       if ( fEnv && fEnv->fObject ) {
00176          switch( idx ) {
00177             case 0:
00178                fEnv->fStart = fFirst.invoke(fEnv);
00179                fEnv->fIdx = idx;
00180                break;
00181             default:
00182                fEnv->fIdx = idx - fEnv->fIdx;
00183                if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00184                fNext.invoke(fEnv);
00185                fEnv->fIdx = idx;
00186                break;
00187          }
00188          typedef ROOT::TCollectionProxyInfo::Environ<std::pair<size_t,bool> > EnvType_t;
00189          EnvType_t *e = (EnvType_t*)fEnv;
00190          return &(e->fIterator.second);
00191       }
00192       Fatal("TGenVectorProxy","At> Logic error - no proxy object set.");
00193       return 0;
00194    }
00195    
00196    virtual void DeleteItem(bool force, void* ptr) const
00197    {
00198       // Call to delete/destruct individual item
00199       if ( force && ptr ) {
00200          fVal->DeleteItem(ptr);
00201       }
00202    }
00203 };
00204 
00205 //////////////////////////////////////////////////////////////////////////
00206 //                                                                      //
00207 //  class TGenListProxy
00208 //
00209 //   Localoptimization class.
00210 //
00211 //   Collection proxies get copied. On copy we switch the type of the
00212 //   proxy to the concrete STL type. The concrete types are optimized
00213 //   for element access.
00214 //
00215 //////////////////////////////////////////////////////////////////////////
00216 class TGenListProxy : public TGenVectorProxy {
00217 public:
00218    // Standard Destructor
00219    TGenListProxy(const TGenCollectionProxy& c) : TGenVectorProxy(c)
00220 {
00221    }
00222    // Standard Destructor
00223    virtual ~TGenListProxy()
00224 {
00225    }
00226    // Return the address of the value at index 'idx'
00227    void* At(UInt_t idx)
00228 {
00229       if ( fEnv && fEnv->fObject ) {
00230          switch( idx ) {
00231          case 0:
00232             fEnv->fIdx = idx;
00233             return fEnv->fStart = fFirst.invoke(fEnv);
00234          default:  {
00235             fEnv->fIdx = idx - fEnv->fIdx;
00236             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00237             void* result = fNext.invoke(fEnv);
00238             fEnv->fIdx = idx;
00239             return result;
00240          }
00241          }
00242       }
00243       Fatal("TGenListProxy","At> Logic error - no proxy object set.");
00244       return 0;
00245    }
00246 };
00247 
00248 //////////////////////////////////////////////////////////////////////////
00249 //                                                                      //
00250 // class TGenSetProxy
00251 //
00252 //   Localoptimization class.
00253 //
00254 //   Collection proxies get copied. On copy we switch the type of the
00255 //   proxy to the concrete STL type. The concrete types are optimized
00256 //   for element access.
00257 //
00258 //////////////////////////////////////////////////////////////////////////
00259 class TGenSetProxy : public TGenVectorProxy {
00260 public:
00261    // Standard Destructor
00262    TGenSetProxy(const TGenCollectionProxy& c) : TGenVectorProxy(c)
00263 {
00264    }
00265    // Standard Destructor
00266    virtual ~TGenSetProxy()
00267 {
00268    }
00269    // Return the address of the value at index 'idx'
00270    void* At(UInt_t idx)
00271 {
00272       if ( fEnv && fEnv->fObject ) {
00273          if ( fEnv->fUseTemp ) {
00274             return (((char*)fEnv->fTemp)+idx*fValDiff);
00275          }
00276          switch( idx ) {
00277          case 0:
00278             fEnv->fIdx = idx;
00279             return fEnv->fStart = fFirst.invoke(fEnv);
00280          default:  {
00281             fEnv->fIdx = idx - fEnv->fIdx;
00282             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00283             void* result = fNext.invoke(fEnv);
00284             fEnv->fIdx = idx;
00285             return result;
00286          }
00287          }
00288       }
00289       Fatal("TGenSetProxy","At> Logic error - no proxy object set.");
00290       return 0;
00291    }
00292 };
00293 
00294 //////////////////////////////////////////////////////////////////////////
00295 //                                                                      //
00296 //  class TGenMapProxy
00297 //
00298 //   Localoptimization class.
00299 //
00300 //   Collection proxies get copied. On copy we switch the type of the
00301 //   proxy to the concrete STL type. The concrete types are optimized
00302 //   for element access.
00303 //
00304 //////////////////////////////////////////////////////////////////////////
00305 class TGenMapProxy : public TGenSetProxy {
00306 public:
00307    // Standard Destructor
00308    TGenMapProxy(const TGenCollectionProxy& c) : TGenSetProxy(c)
00309 {
00310    }
00311    // Standard Destructor
00312    virtual ~TGenMapProxy()
00313 {
00314    }
00315    // Call to delete/destruct individual item
00316    virtual void DeleteItem(Bool_t /* force */, void* ptr) const
00317    {
00318       if ( fKey->fCase&G__BIT_ISPOINTER ) {
00319          fKey->DeleteItem(*(void**)ptr);
00320       }
00321       if ( fVal->fCase&G__BIT_ISPOINTER ) {
00322          char *addr = ((char*)ptr)+fValOffset;
00323          fVal->DeleteItem(*(void**)addr);
00324       }
00325    }
00326 };
00327 
00328 
00329 //______________________________________________________________________________
00330 TGenCollectionProxy::Value::Value(const Value& copy)
00331 {
00332    // Constructor.
00333 
00334    fType   = copy.fType;
00335    fCase   = copy.fCase;
00336    fKind   = copy.fKind;
00337    fSize   = copy.fSize;
00338    fCtor   = copy.fCtor;
00339    fDtor   = copy.fDtor;
00340    fDelete = copy.fDelete;
00341 }
00342 
00343 //______________________________________________________________________________
00344 TGenCollectionProxy::Value::Value(const std::string& inside_type)
00345 {
00346    // Constructor.
00347 
00348    std::string inside = (inside_type.find("const ")==0) ? inside_type.substr(6) : inside_type;
00349    fCase = 0;
00350    fCtor = 0;
00351    fDtor = 0;
00352    fDelete = 0;
00353    fSize = std::string::npos;
00354    fKind = kNoType_t;
00355    std::string intype = TClassEdit::ShortType(inside.c_str(),TClassEdit::kDropTrailStar );
00356    if ( inside.substr(0,6) == "string" || inside.substr(0,11) == "std::string" ) {
00357       fCase = kBIT_ISSTRING;
00358       fType = TClass::GetClass("string");
00359       fCtor = fType->GetNew();
00360       fDtor = fType->GetDestructor();
00361       fDelete = fType->GetDelete();
00362       switch(inside[inside.length()-1]) {
00363       case '*':
00364          fCase |= G__BIT_ISPOINTER;
00365          fSize = sizeof(void*);
00366          break;
00367       default:
00368          fSize = sizeof(std::string);
00369          break;
00370       }
00371    }
00372    else {
00373       // In the case where we have an emulated class,
00374       // if the class is nested (in a class or a namespace),
00375       // calling G__TypeInfo ti(inside.c_str());
00376       // might fail because CINT does not known the nesting
00377       // scope, so let's first look for an emulated class:
00378       fType = TClass::GetClass(intype.c_str());
00379       if (fType && !fType->IsLoaded()) {
00380          if (intype != inside) {
00381             fCase |= G__BIT_ISPOINTER;
00382             fSize = sizeof(void*);
00383          }
00384          fCase  |= G__BIT_ISCLASS;
00385          fCtor   = fType->GetNew();
00386          fDtor   = fType->GetDestructor();
00387          fDelete = fType->GetDelete();
00388       } else {
00389 #if defined(NOT_YET)
00390          // Because the TStreamerInfo of the contained classes
00391          // is stored only when tbere at least one element in
00392          // the collection, we might not even have an emulated
00393          // class.  So go the long route to avoid errors
00394          // issued by CINT ....
00395          G__value gval = G__string2type_body(inside.c_str(),2);
00396          G__TypeInfo ti(gval);
00397 #else
00398          //G__TypeInfo ti(inside.c_str());
00399          TypeInfo_t *ti = gCint->TypeInfo_Factory();
00400          gCint->TypeInfo_Init(ti,inside.c_str());
00401 #endif   
00402          if ( !gCint->TypeInfo_IsValid(ti) ) {
00403             if (intype != inside) {
00404                fCase |= G__BIT_ISPOINTER;
00405                fSize = sizeof(void*);
00406             }
00407             fType = TClass::GetClass(intype.c_str());
00408             if (fType) {
00409                fCase  |= G__BIT_ISCLASS;
00410                fCtor   = fType->GetNew();
00411                fDtor   = fType->GetDestructor();
00412                fDelete = fType->GetDelete();
00413             }
00414             else {
00415                // either we have an Emulated enum or a really unknown class!
00416                // let's just claim its an enum :(
00417                fCase = G__BIT_ISENUM;
00418                fSize = sizeof(Int_t);
00419                fKind = kInt_t;
00420             }
00421          }
00422          else {
00423             Long_t prop = gCint->TypeInfo_Property(ti);
00424             if ( prop&G__BIT_ISPOINTER ) {
00425                fSize = sizeof(void*);
00426             }
00427             if ( prop&G__BIT_ISSTRUCT ) {
00428                prop |= G__BIT_ISCLASS;
00429             }
00430             if ( prop&G__BIT_ISCLASS ) {
00431                fType = TClass::GetClass(intype.c_str());
00432                R__ASSERT(fType);
00433                fCtor   = fType->GetNew();
00434                fDtor   = fType->GetDestructor();
00435                fDelete = fType->GetDelete();
00436             }
00437             else if ( prop&G__BIT_ISFUNDAMENTAL ) {
00438                TDataType *fundType = gROOT->GetType( intype.c_str() );
00439                if (fundType==0) {
00440                   if (intype != "long double") {
00441                      Error("TGenCollectionProxy","Unknown fundamental type %s",intype.c_str());
00442                   }
00443                   fSize = sizeof(int);
00444                   fKind = kInt_t;
00445                } else {
00446                   fKind = (EDataType)fundType->GetType();
00447                   if ( 0 == strcmp("bool",fundType->GetFullTypeName()) ) {
00448                      fKind = (EDataType)kBOOL_t;
00449                   }
00450                   fSize = gCint->TypeInfo_Size(ti);
00451                   R__ASSERT((fKind>0 && fKind<0x16) || (fKind==-1&&(prop&G__BIT_ISPOINTER)) );
00452                }
00453             }
00454             else if ( prop&G__BIT_ISENUM ) {
00455                fSize = sizeof(int);
00456                fKind = kInt_t;
00457             }
00458             fCase = prop & (G__BIT_ISPOINTER|G__BIT_ISFUNDAMENTAL|G__BIT_ISENUM|G__BIT_ISCLASS);
00459             if (fType == TString::Class() && (fCase&G__BIT_ISPOINTER)) {
00460                fCase |= kBIT_ISTSTRING;
00461             }
00462          }
00463          gCint->TypeInfo_Delete(ti);
00464       }
00465    }
00466    if ( fSize == std::string::npos ) {
00467       if ( fType == 0 ) {
00468          // The caller should check the validity by calling IsValid()
00469       } else {
00470          fSize = fType->Size();
00471       }
00472    }
00473 }
00474 
00475 Bool_t TGenCollectionProxy::Value::IsValid()
00476 {
00477    // Return true if the Value has been properly initialized.
00478    
00479    return fSize != std::string::npos;
00480 }
00481 
00482 void TGenCollectionProxy::Value::DeleteItem(void* ptr)
00483 {
00484    // Delete an item.
00485 
00486    if ( ptr && fCase&G__BIT_ISPOINTER ) {
00487       if ( fDelete ) {
00488          (*fDelete)(ptr);
00489       }
00490       else if ( fType ) {
00491          fType->Destructor(ptr);
00492       }
00493       else {
00494          ::operator delete(ptr);
00495       }
00496    }
00497 }
00498 
00499 //______________________________________________________________________________
00500 TGenCollectionProxy::TGenCollectionProxy(const TGenCollectionProxy& copy)
00501    : TVirtualCollectionProxy(copy.fClass),
00502      fTypeinfo(copy.fTypeinfo)
00503 {
00504    // Build a proxy for an emulated container.
00505    fEnv            = 0;
00506    fName           = copy.fName;
00507    fPointers       = copy.fPointers;
00508    fSTL_type       = copy.fSTL_type;
00509    fSize.call      = copy.fSize.call;
00510    fNext.call      = copy.fNext.call;
00511    fFirst.call     = copy.fFirst.call;
00512    fClear.call     = copy.fClear.call;
00513    fResize         = copy.fResize;
00514    fDestruct       = copy.fDestruct;
00515    fConstruct      = copy.fConstruct;
00516    fFeed           = copy.fFeed;
00517    fCollect.call   = copy.fCollect.call;
00518    fCreateEnv.call = copy.fCreateEnv.call;
00519    fValOffset      = copy.fValOffset;
00520    fValDiff        = copy.fValDiff;
00521    fValue          = copy.fValue ? new Value(*copy.fValue) : 0;
00522    fVal            = copy.fVal   ? new Value(*copy.fVal)   : 0;
00523    fKey            = copy.fKey   ? new Value(*copy.fKey)   : 0;
00524    fOnFileClass    = copy.fOnFileClass;
00525    fReadMemberWise = new TObjArray(TCollection::kInitCapacity,-1);
00526    fConversionReadMemberWise = 0;
00527    fProperties     = copy.fProperties;
00528    fFunctionCreateIterators    = copy.fFunctionCreateIterators;
00529    fFunctionDeleteTwoIterators = copy.fFunctionDeleteTwoIterators;
00530 }
00531 
00532 //______________________________________________________________________________
00533 TGenCollectionProxy::TGenCollectionProxy(Info_t info, size_t iter_size)
00534    : TVirtualCollectionProxy(0),
00535      fTypeinfo(info)
00536 {
00537    // Build a proxy for a collection whose type is described by 'collectionClass'.
00538    fEnv             = 0;
00539    fSize.call       = 0;
00540    fFirst.call      = 0;
00541    fNext.call       = 0;
00542    fClear.call      = 0;
00543    fResize          = 0;
00544    fDestruct        = 0;
00545    fConstruct       = 0;
00546    fCollect.call    = 0;
00547    fCreateEnv.call  = 0;
00548    fFeed            = 0;
00549    fValue           = 0;
00550    fKey             = 0;
00551    fVal             = 0;
00552    fValOffset       = 0;
00553    fValDiff         = 0;
00554    fPointers        = false;
00555    fOnFileClass     = 0;
00556    fSTL_type        = TClassEdit::kNotSTL;
00557    Env_t e;
00558    if ( iter_size > sizeof(e.fIterator) ) {
00559       Fatal("TGenCollectionProxy",
00560             "%s %s are too large:%ld bytes. Maximum is:%ld bytes",
00561             "Iterators for collection",
00562             fClass->GetName(),
00563             (Long_t)iter_size,
00564             (Long_t)sizeof(e.fIterator));
00565    }
00566    fReadMemberWise = new TObjArray(TCollection::kInitCapacity,-1);
00567    fConversionReadMemberWise   = 0;
00568    fFunctionCreateIterators    = 0;
00569    fFunctionDeleteTwoIterators = 0;
00570 }
00571 
00572 //______________________________________________________________________________
00573 TGenCollectionProxy::TGenCollectionProxy(const ROOT::TCollectionProxyInfo &info, TClass *cl)
00574    : TVirtualCollectionProxy(cl),
00575      fTypeinfo(info.fInfo), fOnFileClass(0)
00576 {
00577    // Build a proxy for a collection whose type is described by 'collectionClass'.
00578    fEnv            = 0;
00579    fValDiff        = info.fValueDiff;
00580    fValOffset      = info.fValueOffset;
00581    fSize.call      = info.fSizeFunc;
00582    fResize         = info.fResizeFunc;
00583    fNext.call      = info.fNextFunc;
00584    fFirst.call     = info.fFirstFunc;
00585    fClear.call     = info.fClearFunc;
00586    fConstruct      = info.fConstructFunc;
00587    fDestruct       = info.fDestructFunc;
00588    fFeed           = info.fFeedFunc;
00589    fCollect.call   = info.fCollectFunc;
00590    fCreateEnv.call = info.fCreateEnv;
00591    
00592    if (cl) {
00593       fName = cl->GetName();
00594    }
00595    CheckFunctions();
00596 
00597    fValue           = 0;
00598    fKey             = 0;
00599    fVal             = 0;
00600    fPointers        = false;
00601    fSTL_type        = TClassEdit::kNotSTL;
00602 
00603    Env_t e;
00604    if ( info.fIterSize > sizeof(e.fIterator) ) {
00605       Fatal("TGenCollectionProxy",
00606             "%s %s are too large:%ld bytes. Maximum is:%ld bytes",
00607             "Iterators for collection",
00608             fClass->GetName(),
00609             (Long_t)info.fIterSize,
00610             (Long_t)sizeof(e.fIterator));
00611    }
00612    fReadMemberWise = new TObjArray(TCollection::kInitCapacity,-1);
00613    fConversionReadMemberWise   = 0;
00614    fFunctionCreateIterators    = 0;
00615    fFunctionDeleteTwoIterators = 0;
00616 }
00617 
00618 namespace {
00619    template <class vec> 
00620    void clearVector(vec& v)
00621    {
00622       // Clear out the proxies.
00623 
00624       for(typename vec::iterator i=v.begin(); i != v.end(); ++i) {
00625          typename vec::value_type e = *i;
00626          if ( e ) {
00627             delete e;
00628          }
00629       }
00630       v.clear();
00631    }
00632 }
00633 //______________________________________________________________________________
00634 TGenCollectionProxy::~TGenCollectionProxy()
00635 {
00636    // Standard destructor
00637    clearVector(fProxyList);
00638    clearVector(fProxyKept);
00639    clearVector(fStaged);
00640 
00641    if ( fValue ) delete fValue;
00642    if ( fVal   ) delete fVal;
00643    if ( fKey   ) delete fKey;
00644    
00645    delete fReadMemberWise;
00646    if (fConversionReadMemberWise) {
00647       std::map<std::string, TObjArray*>::iterator it;
00648       std::map<std::string, TObjArray*>::iterator end = fConversionReadMemberWise->end();
00649       for( it = fConversionReadMemberWise->begin(); it != end; ++it ) {
00650          delete it->second;
00651       }
00652       delete fConversionReadMemberWise;
00653       fConversionReadMemberWise = 0;
00654    }
00655 }
00656 
00657 //______________________________________________________________________________
00658 TVirtualCollectionProxy* TGenCollectionProxy::Generate() const
00659 {
00660    // Virtual copy constructor
00661    if ( !fValue ) Initialize();
00662 
00663    if( fPointers )
00664       return new TGenCollectionProxy(*this);
00665 
00666    switch(fSTL_type) {
00667    case TClassEdit::kBitSet: {
00668       return new TGenBitsetProxy(*this);
00669    }
00670    case TClassEdit::kVector: {
00671       if (fValue->fKind == (EDataType)kBOOL_t) {
00672          return new TGenVectorBoolProxy(*this);
00673       } else {
00674          return new TGenVectorProxy(*this);
00675       }         
00676    }
00677    case TClassEdit::kList:
00678       return new TGenListProxy(*this);
00679    case TClassEdit::kMap:
00680    case TClassEdit::kMultiMap:
00681       return new TGenMapProxy(*this);
00682    case TClassEdit::kSet:
00683    case TClassEdit::kMultiSet:
00684       return new TGenSetProxy(*this);
00685    default:
00686       return new TGenCollectionProxy(*this);
00687    }
00688 }
00689 
00690 //______________________________________________________________________________
00691 TGenCollectionProxy *TGenCollectionProxy::Initialize() const
00692 {
00693    // Proxy initializer
00694    TGenCollectionProxy* p = const_cast<TGenCollectionProxy*>(this);
00695    if ( fValue ) return p;
00696    const_cast<TGenCollectionProxy*>(this)->fProperties |= kIsInitialized;
00697    return p->InitializeEx();
00698 }
00699 
00700 //______________________________________________________________________________
00701 void TGenCollectionProxy::CheckFunctions() const
00702 {
00703    // Check existence of function pointers
00704    if ( 0 == fSize.call ) {
00705       Fatal("TGenCollectionProxy","No 'size' function pointer for class %s present.",fName.c_str());
00706    }
00707    if ( 0 == fResize ) {
00708       Fatal("TGenCollectionProxy","No 'resize' function for class %s present.",fName.c_str());
00709    }
00710    if ( 0 == fNext.call  ) {
00711       Fatal("TGenCollectionProxy","No 'next' function for class %s present.",fName.c_str());
00712    }
00713    if ( 0 == fFirst.call ) {
00714       Fatal("TGenCollectionProxy","No 'begin' function for class %s present.",fName.c_str());
00715    }
00716    if ( 0 == fClear.call ) {
00717       Fatal("TGenCollectionProxy","No 'clear' function for class %s present.",fName.c_str());
00718    }
00719    if ( 0 == fConstruct ) {
00720       Fatal("TGenCollectionProxy","No 'block constructor' function for class %s present.",fName.c_str());
00721    }
00722    if ( 0 == fDestruct ) {
00723       Fatal("TGenCollectionProxy","No 'block destructor' function for class %s present.",fName.c_str());
00724    }
00725    if ( 0 == fFeed ) {
00726       Fatal("TGenCollectionProxy","No 'data feed' function for class %s present.",fName.c_str());
00727    }
00728    if ( 0 == fCollect.call ) {
00729       Fatal("TGenCollectionProxy","No 'data collect' function for class %s present.",fName.c_str());
00730    }
00731    if (0 == fCreateEnv.call ) {
00732       Fatal("TGenCollectionProxy","No 'environment creation' function for class %s present.",fName.c_str());
00733    }
00734 }
00735 
00736 //______________________________________________________________________________
00737 static TGenCollectionProxy::Value *R__CreateValue(const std::string &name)
00738 {
00739    // Utility routine to issue a Fatal error is the Value object is not valid
00740    TGenCollectionProxy::Value *val = new TGenCollectionProxy::Value( name );
00741    if ( !val->IsValid() ) {
00742       Fatal("TGenCollectionProxy","Could not find %s!",name.c_str());
00743    }
00744    return val;
00745 }
00746       
00747 //______________________________________________________________________________
00748 TGenCollectionProxy *TGenCollectionProxy::InitializeEx()
00749 {
00750    // Proxy initializer
00751    R__LOCKGUARD2(gCollectionMutex);
00752    if (fValue) return this;
00753 
00754    TClass *cl = fClass ? fClass.GetClass() : TClass::GetClass(fTypeinfo);
00755    if ( cl ) {
00756       fEnv    = 0;
00757       fName   = cl->GetName();
00758       fPointers  = false;
00759       int nested = 0;
00760       std::vector<std::string> inside;
00761       int num = TClassEdit::GetSplit(cl->GetName(),inside,nested);
00762       if ( num > 1 ) {
00763          std::string nam;
00764          if ( inside[0].find("stdext::hash_") != std::string::npos )
00765             inside[0].replace(3,10,"::");
00766          if ( inside[0].find("__gnu_cxx::hash_") != std::string::npos )
00767             inside[0].replace(0,16,"std::");
00768          fSTL_type = TClassEdit::STLKind(inside[0].c_str());
00769          switch ( fSTL_type ) {
00770             case TClassEdit::kMap:
00771             case TClassEdit::kMultiMap:
00772             case TClassEdit::kSet:
00773             case TClassEdit::kMultiSet:
00774                fProperties |= kIsAssociative;
00775                break;
00776          };
00777                
00778          int slong = sizeof(void*);
00779          switch ( fSTL_type ) {
00780             case TClassEdit::kMap:
00781             case TClassEdit::kMultiMap:
00782                nam = "pair<"+inside[1]+","+inside[2];
00783                nam += (nam[nam.length()-1]=='>') ? " >" : ">";
00784                fValue = R__CreateValue(nam);
00785                
00786                fVal   = R__CreateValue(inside[2]);
00787                fKey   = R__CreateValue(inside[1]);
00788                fPointers = fPointers || (0 != (fKey->fCase&G__BIT_ISPOINTER));
00789                if ( 0 == fValDiff ) {
00790                   fValDiff = fKey->fSize + fVal->fSize;
00791                   fValDiff += (slong - fKey->fSize%slong)%slong;
00792                   fValDiff += (slong - fValDiff%slong)%slong;
00793                }
00794                if ( 0 == fValOffset ) {
00795                   fValOffset = fKey->fSize;
00796                   fValOffset += (slong - fKey->fSize%slong)%slong;
00797                }
00798                break;
00799             case TClassEdit::kBitSet:
00800                inside[1] = "bool";
00801                // Intentional fall through
00802             default:
00803                fValue = R__CreateValue(inside[1]);
00804                
00805                fVal   = new Value(*fValue);
00806                if ( 0 == fValDiff ) {
00807                   fValDiff = fVal->fSize;
00808                   fValDiff += (slong - fValDiff%slong)%slong;
00809                }
00810                break;
00811          }
00812 
00813          fPointers = fPointers || (0 != (fVal->fCase&G__BIT_ISPOINTER));
00814          fClass = cl;
00815          return this;
00816       }
00817       Fatal("TGenCollectionProxy","Components of %s not analysed!",cl->GetName());
00818    }
00819    Fatal("TGenCollectionProxy","Collection class %s not found!",fTypeinfo.name());
00820    return 0;
00821 }
00822 
00823 //______________________________________________________________________________
00824 TClass *TGenCollectionProxy::GetCollectionClass()
00825 {
00826    // Return a pointer to the TClass representing the container
00827    return fClass ? fClass : Initialize()->fClass;
00828 }
00829 
00830 //______________________________________________________________________________
00831 Int_t TGenCollectionProxy::GetCollectionType()
00832 {
00833    // Return the type of collection see TClassEdit::ESTLType
00834 
00835    if (!fClass) {
00836       Initialize();
00837    }
00838    return fSTL_type;
00839 }
00840 
00841 //______________________________________________________________________________
00842 ULong_t TGenCollectionProxy::GetIncrement() {
00843    // Return the offset between two consecutive value_types (memory layout).
00844 
00845    if (!fValue) {
00846       Initialize();
00847    }
00848    return fValDiff;
00849 }
00850 
00851 //______________________________________________________________________________
00852 UInt_t TGenCollectionProxy::Sizeof() const
00853 {
00854    // Return the sizeof the collection object.
00855    return fClass->Size();
00856 }
00857 
00858 //______________________________________________________________________________
00859 Bool_t TGenCollectionProxy::HasPointers() const
00860 {
00861    // Return true if the content is of type 'pointer to'
00862 
00863    // Initialize proxy in case it hasn't been initialized yet
00864    if( !fValue )
00865       Initialize();
00866 
00867    // The content of a map and multimap is always a 'pair' and hence
00868    // fPointers means "Flag to indicate if containee has pointers (key or value)"
00869    // so we need to ignore its value for map and multimap;
00870    return fPointers && !(fSTL_type == TClassEdit::kMap || fSTL_type == TClassEdit::kMultiMap);
00871 }
00872 
00873 //______________________________________________________________________________
00874 TClass *TGenCollectionProxy::GetValueClass()
00875 {
00876    // Return a pointer to the TClass representing the content.
00877 
00878    if (!fValue) Initialize();
00879    return fValue ? fValue->fType.GetClass() : 0;
00880 }
00881 
00882 //______________________________________________________________________________
00883 void TGenCollectionProxy::SetValueClass(TClass *new_Value_type)
00884 {
00885    // Set pointer to the TClass representing the content.
00886 
00887    if (!fValue) Initialize();
00888    fValue->fType = new_Value_type;
00889 }
00890 
00891 //______________________________________________________________________________
00892 EDataType TGenCollectionProxy::GetType()
00893 {
00894    // If the content is a simple numerical value, return its type (see TDataType)
00895 
00896    if ( !fValue ) Initialize();
00897    return fValue->fKind;
00898 }
00899 
00900 //______________________________________________________________________________
00901 void* TGenCollectionProxy::At(UInt_t idx)
00902 {
00903    // Return the address of the value at index 'idx'
00904    if ( fEnv && fEnv->fObject ) {
00905       switch (fSTL_type) {
00906       case TClassEdit::kVector:
00907          fEnv->fIdx = idx;
00908          switch( idx ) {
00909          case 0:
00910             return fEnv->fStart = fFirst.invoke(fEnv);
00911          default:
00912             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00913             return ((char*)fEnv->fStart) + fValDiff*idx;
00914          }
00915       case TClassEdit::kSet:
00916       case TClassEdit::kMultiSet:
00917       case TClassEdit::kMap:
00918       case TClassEdit::kMultiMap:
00919          if ( fEnv->fUseTemp ) {
00920             return (((char*)fEnv->fTemp)+idx*fValDiff);
00921          }
00922          // Intentional fall through.
00923       default:
00924          switch( idx ) {
00925          case 0:
00926             fEnv->fIdx = idx;
00927             return fEnv->fStart = fFirst.invoke(fEnv);
00928          default:  {
00929             fEnv->fIdx = idx - fEnv->fIdx;
00930             if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00931             void* result = fNext.invoke(fEnv);
00932             fEnv->fIdx = idx;
00933             return result;
00934          }
00935          }
00936       }
00937    }
00938    Fatal("TGenCollectionProxy","At> Logic error - no proxy object set.");
00939    return 0;
00940 }
00941 
00942 //______________________________________________________________________________
00943 void TGenCollectionProxy::Clear(const char* opt)
00944 {
00945    // Clear the emulated collection.
00946    if ( fEnv && fEnv->fObject ) {
00947       if ( fPointers && opt && *opt=='f' ) {
00948          size_t i, n = *(size_t*)fSize.invoke(fEnv);
00949          if ( n > 0 ) {
00950             for (i=0; i<n; ++i)
00951                DeleteItem(true, TGenCollectionProxy::At(i));
00952          }
00953       }
00954       fClear.invoke(fEnv);
00955    }
00956 }
00957 
00958 //______________________________________________________________________________
00959 UInt_t TGenCollectionProxy::Size() const
00960 {
00961    // Return the current size of the container
00962    if ( fEnv && fEnv->fObject ) {
00963       if (fEnv->fUseTemp) {
00964          return fEnv->fSize;
00965       } else {
00966          return *(size_t*)fSize.invoke(fEnv);
00967       }
00968    }
00969    Fatal("TGenCollectionProxy","Size> Logic error - no proxy object set.");
00970    return 0;
00971 }
00972 
00973 //______________________________________________________________________________
00974 void TGenCollectionProxy::Resize(UInt_t n, Bool_t force)
00975 {
00976    // Resize the container
00977    if ( fEnv && fEnv->fObject ) {
00978       if ( force && fPointers ) {
00979          size_t i, nold = *(size_t*)fSize.invoke(fEnv);
00980          if ( n != nold ) {
00981             for (i=n; i<nold; ++i)
00982                DeleteItem(true, *(void**)TGenCollectionProxy::At(i));
00983          }
00984       }
00985       MESSAGE(3, "Resize(n)" );
00986       fEnv->fSize = n;
00987       fResize(fEnv->fObject,fEnv->fSize);
00988       return;
00989    }
00990    Fatal("TGenCollectionProxy","Resize> Logic error - no proxy object set.");
00991 }
00992 
00993 //______________________________________________________________________________
00994 void* TGenCollectionProxy::Allocate(UInt_t n, Bool_t /* forceDelete */ )
00995 {
00996    // Allocate the needed space.
00997    // For associative collection, this returns a TStaging object that
00998    // need to be deleted manually __or__ returned by calling Commit(TStaging*)
00999 
01000    if ( fEnv && fEnv->fObject ) {
01001       switch ( fSTL_type ) {
01002          case TClassEdit::kSet:
01003          case TClassEdit::kMultiSet:
01004          case TClassEdit::kMap:
01005          case TClassEdit::kMultiMap:
01006             if ( fPointers )
01007                Clear("force");
01008             else
01009                fClear.invoke(fEnv);
01010             ++fEnv->fRefCount;
01011             fEnv->fSize  = n;
01012 
01013             TStaging *s;
01014             if (fStaged.empty()) {
01015                s = new TStaging(n,fValDiff);
01016             } else {
01017                s = fStaged.back();
01018                fStaged.pop_back();
01019                s->Resize(n);
01020             }
01021             fConstruct(s->GetContent(),s->GetSize());
01022             
01023             s->SetTarget(fEnv->fObject);
01024 
01025             fEnv->fTemp = s->GetContent();
01026             fEnv->fUseTemp = kTRUE;
01027             fEnv->fStart = fEnv->fTemp;
01028 
01029             return s;
01030          case TClassEdit::kVector:
01031          case TClassEdit::kList:
01032          case TClassEdit::kDeque:
01033             if( fPointers ) {
01034                Clear("force");
01035             }
01036             fEnv->fSize = n;
01037             fResize(fEnv->fObject,n);
01038             return fEnv->fObject;
01039             
01040          case TClassEdit::kBitSet:
01041             // Nothing to do.
01042             return fEnv->fObject;
01043       }
01044    }
01045    return 0;
01046 }
01047 
01048 //______________________________________________________________________________
01049 void TGenCollectionProxy::Commit(void* from)
01050 {
01051    // Commit the change.
01052 
01053    if (fProperties & kIsAssociative) {
01054 //      case TClassEdit::kMap:
01055 //      case TClassEdit::kMultiMap:
01056 //      case TClassEdit::kSet:
01057 //      case TClassEdit::kMultiSet:
01058       if ( from ) {
01059          TStaging *s = (TStaging*) from;
01060          if ( s->GetTarget() ) {
01061             fFeed(s->GetContent(),s->GetTarget(),s->GetSize());
01062          }
01063          fDestruct(s->GetContent(),s->GetSize());
01064          s->SetTarget(0);
01065          fStaged.push_back(s);
01066       }
01067    }
01068 }
01069 
01070 //______________________________________________________________________________
01071 void TGenCollectionProxy::PushProxy(void *objstart)
01072 {
01073    // Add an object.
01074 
01075    gSlowIterator__Proxy.push_back(this);
01076 
01077    if ( !fValue ) Initialize();
01078    if ( !fProxyList.empty() ) {
01079       EnvironBase_t* back = fProxyList.back();
01080       if ( back->fObject == objstart ) {
01081          ++back->fRefCount;
01082          fProxyList.push_back(back);
01083          fEnv = back;
01084          return;
01085       }
01086    }
01087    EnvironBase_t* e    = 0;
01088    if ( fProxyKept.empty() ) {
01089       e = (EnvironBase_t*)fCreateEnv.invoke();
01090       e->fTemp  = 0;
01091       e->fUseTemp = kFALSE;
01092    }
01093    else {
01094       e = fProxyKept.back();
01095       fProxyKept.pop_back();
01096    }
01097    e->fSize     = 0;
01098    e->fRefCount = 1;
01099    e->fObject   = objstart;
01100    e->fStart    = 0;
01101    e->fIdx      = 0;
01102    // ::memset(e->buff,0,sizeof(e->buff));
01103    fProxyList.push_back(e);
01104    fEnv = e;
01105 }
01106 
01107 //______________________________________________________________________________
01108 void TGenCollectionProxy::PopProxy()
01109 {
01110    // Remove the last object.
01111 
01112    gSlowIterator__Proxy.pop_back();
01113    
01114    if ( !fProxyList.empty() ) {
01115       EnvironBase_t* e = fProxyList.back();
01116       if ( --e->fRefCount <= 0 ) {
01117          fProxyKept.push_back(e);
01118          e->fUseTemp = kFALSE;
01119       }
01120       fProxyList.pop_back();
01121    }
01122    fEnv = fProxyList.empty() ? 0 : fProxyList.back();
01123 }
01124 
01125 //______________________________________________________________________________
01126 void TGenCollectionProxy::DeleteItem(Bool_t force, void* ptr) const
01127 {
01128    // Call to delete/destruct individual item.
01129    if ( force && ptr ) {
01130       switch (fSTL_type) {
01131       case TClassEdit::kMap:
01132       case TClassEdit::kMultiMap:
01133          if ( fKey->fCase&G__BIT_ISPOINTER ) {
01134             fKey->DeleteItem(*(void**)ptr);
01135          }
01136          if ( fVal->fCase&G__BIT_ISPOINTER ) {
01137             char *addr = ((char*)ptr)+fValOffset;
01138             fVal->DeleteItem(*(void**)addr);
01139          }
01140          break;
01141       default:
01142          if ( fVal->fCase&G__BIT_ISPOINTER ) {
01143             fVal->DeleteItem(*(void**)ptr);
01144          }
01145          break;
01146       }
01147    }
01148 }
01149 
01150 //______________________________________________________________________________
01151 void TGenCollectionProxy::ReadBuffer(TBuffer & /* b */, void * /* obj */, const TClass * /* onfileClass */)
01152 {
01153    MayNotUse("TGenCollectionProxy::ReadBuffer(TBuffer &, void *, const TClass *)");
01154 }
01155 
01156 //______________________________________________________________________________
01157 void TGenCollectionProxy::ReadBuffer(TBuffer & /* b */, void * /* obj */)
01158 {
01159    MayNotUse("TGenCollectionProxy::ReadBuffer(TBuffer &, void *)");
01160 }
01161 
01162 //______________________________________________________________________________
01163 void TGenCollectionProxy::Streamer(TBuffer &buff)
01164 {
01165    // Streamer Function.
01166    if ( fEnv ) {
01167       GetCollectionClass()->Streamer( fEnv->fObject, buff );
01168       return;
01169    }
01170    Fatal("TGenCollectionProxy","Streamer> Logic error - no proxy object set.");
01171 }
01172 
01173 //______________________________________________________________________________
01174 void TGenCollectionProxy::Streamer(TBuffer &buff, void *objp, int /* siz */ )
01175 {
01176    // Streamer I/O overload
01177    TPushPop env(this, objp);
01178    Streamer(buff);
01179 }
01180 
01181 //______________________________________________________________________________
01182 void TGenCollectionProxy::operator()(TBuffer &b, void *objp)
01183 {
01184    // TClassStreamer IO overload
01185    Streamer(b, objp, 0);
01186 }
01187 
01188 
01189 struct TGenCollectionProxy__SlowIterator {
01190    TVirtualCollectionProxy *fProxy;
01191    UInt_t fIndex;
01192    TGenCollectionProxy__SlowIterator(TVirtualCollectionProxy *proxy) : fProxy(proxy), fIndex(0) {}
01193 };
01194 
01195 //______________________________________________________________________________
01196 void TGenCollectionProxy__SlowCreateIterators(void * /* collection */, void **begin_arena, void **end_arena) 
01197 {
01198    new (*begin_arena) TGenCollectionProxy__SlowIterator(gSlowIterator__Proxy.back());
01199    *(UInt_t*)*end_arena = gSlowIterator__Proxy.back()->Size();
01200 }
01201 
01202 //______________________________________________________________________________
01203 void *TGenCollectionProxy__SlowNext(void *iter, const void *end) 
01204 {
01205    TGenCollectionProxy__SlowIterator *iterator = (TGenCollectionProxy__SlowIterator*)iter;
01206    if (iterator->fIndex != *(UInt_t*)end) {
01207       void *result = iterator->fProxy->At(iterator->fIndex);
01208       ++(iterator->fIndex);
01209       return result;
01210    } else {
01211       return 0;
01212    }
01213 }
01214 
01215 //______________________________________________________________________________
01216 void * TGenCollectionProxy__SlowCopyIterator(void *dest, const void *source) 
01217 {
01218    *(TGenCollectionProxy__SlowIterator*)dest = *(TGenCollectionProxy__SlowIterator*)source;
01219    return dest;
01220 }
01221 
01222 //______________________________________________________________________________
01223 void TGenCollectionProxy__SlowDeleteSingleIterators(void *) 
01224 {
01225    // Nothing to do
01226 }
01227 
01228 //______________________________________________________________________________
01229 void TGenCollectionProxy__SlowDeleteTwoIterators(void *, void *) 
01230 {
01231    // Nothing to do
01232 }
01233 
01234 
01235 //______________________________________________________________________________
01236 void TGenCollectionProxy__VectorCreateIterators(void *obj, void **begin_arena, void **end_arena) 
01237 {
01238    // We can safely assume that the std::vector layout does not really depend on
01239    // the content!
01240    std::vector<char> *vec = (std::vector<char>*)obj;
01241    if (vec->empty()) {
01242       *begin_arena = 0;
01243       *end_arena = 0;
01244       return;
01245    }
01246    *begin_arena = &(*vec->begin());
01247 #ifdef R__VISUAL_CPLUSPLUS
01248    *end_arena = &(*(vec->end()-1)) + 1; // On windows we can not dererence the end iterator at all.
01249 #else
01250    // coverity[past_the_end] Safe on other platforms
01251    *end_arena = &(*vec->end());
01252 #endif
01253    
01254    // The following is a safer way but require the caller to have called TPushPop
01255    //   TVirtualCollectionProxy *proxy = gSlowIterator__Proxy.back();
01256    //   void *good_begin_arena = proxy->At(0);
01257    //   void *good_end_arena = ((char*)proxy->At(0)) + proxy->Size() * proxy->GetIncrement();
01258 }
01259 
01260 //______________________________________________________________________________
01261 void *TGenCollectionProxy__VectorNext(void *, const void *) 
01262 {
01263    // Should not be used.
01264    R__ASSERT(0);
01265    return 0;
01266 }
01267 
01268 //______________________________________________________________________________
01269 void *TGenCollectionProxy__VectorCopyIterator(void *dest, const void *source) 
01270 {
01271    *(void**)dest = *(void**)source;
01272    return dest;
01273 }
01274 
01275 //______________________________________________________________________________
01276 void TGenCollectionProxy__VectorDeleteSingleIterators(void *) 
01277 {
01278    // Nothing to do
01279 }
01280 
01281 //______________________________________________________________________________
01282 void TGenCollectionProxy__VectorDeleteTwoIterators(void *, void *) 
01283 {
01284    // Nothing to do
01285 }
01286 
01287 
01288 
01289 //______________________________________________________________________________
01290 void TGenCollectionProxy__StagingCreateIterators(void *obj, void **begin_arena, void **end_arena) 
01291 {
01292    TGenCollectionProxy::TStaging * s = (TGenCollectionProxy::TStaging*)obj;
01293    *begin_arena = s->GetContent();
01294    *end_arena = s->GetEnd();
01295 }
01296 
01297 //______________________________________________________________________________
01298 void *TGenCollectionProxy__StagingNext(void *, const void *) 
01299 {
01300    // Should not be used.
01301    R__ASSERT(0);
01302    return 0;
01303 }
01304 
01305 //______________________________________________________________________________
01306 void *TGenCollectionProxy__StagingCopyIterator(void *dest, const void *source) 
01307 {
01308    *(void**)dest = *(void**)source;
01309    return dest;
01310 }
01311 
01312 //______________________________________________________________________________
01313 void TGenCollectionProxy__StagingDeleteSingleIterators(void *) 
01314 {
01315    // Nothing to do
01316 }
01317 
01318 //______________________________________________________________________________
01319 void TGenCollectionProxy__StagingDeleteTwoIterators(void *, void *) 
01320 {
01321    // Nothing to do
01322 }
01323 
01324 
01325 //______________________________________________________________________________
01326 TVirtualCollectionProxy::CreateIterators_t TGenCollectionProxy::GetFunctionCreateIterators(Bool_t read) 
01327 {
01328    // See typedef void (*CreateIterators_t)(void *collection, void *&begin_arena, void *&end_arena);
01329    // begin_arena and end_arena should contain the location of memory arena  of size fgIteratorSize. 
01330    // If the collection iterator are of that size or less, the iterators will be constructed in place in those location (new with placement)
01331    // Otherwise the iterators will be allocated via a regular new and their address returned by modifying the value of begin_arena and end_arena.
01332    
01333    if ( fFunctionCreateIterators ) return fFunctionCreateIterators;
01334    
01335    if ( !fValue ) InitializeEx();
01336 
01337 //   fprintf(stderr,"GetFunctinCreateIterator for %s will give: ",fClass.GetClassName());
01338 //   if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated)) 
01339 //      fprintf(stderr,"vector/emulated iterator\n");
01340 //   else if ( (fProperties & kIsAssociative) && read)
01341 //      fprintf(stderr,"an associative read iterator\n");
01342 //   else 
01343 //      fprintf(stderr,"a generic iterator\n");
01344       
01345    if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated)) 
01346       fFunctionCreateIterators = TGenCollectionProxy__VectorCreateIterators;
01347    else if ( (fProperties & kIsAssociative) && read)
01348       fFunctionCreateIterators = TGenCollectionProxy__StagingCreateIterators;
01349    else 
01350       fFunctionCreateIterators = TGenCollectionProxy__SlowCreateIterators;
01351    return fFunctionCreateIterators;
01352 }
01353 
01354 //______________________________________________________________________________
01355 TVirtualCollectionProxy::CopyIterator_t TGenCollectionProxy::GetFunctionCopyIterator(Bool_t read)
01356 {
01357    // See typedef void (*CopyIterator_t)(void *&dest, const void *source);
01358    // Copy the iterator source, into dest.   dest should contain should contain the location of memory arena  of size fgIteratorSize.
01359    // If the collection iterator are of that size or less, the iterator will be constructed in place in this location (new with placement)
01360    // Otherwise the iterator will be allocated via a regular new and its address returned by modifying the value of dest.
01361    
01362    if ( !fValue ) InitializeEx();
01363 
01364    if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated)) 
01365       return TGenCollectionProxy__VectorCopyIterator;
01366    else if ( (fProperties & kIsAssociative) && read)
01367       return TGenCollectionProxy__StagingCopyIterator;
01368    else 
01369       return TGenCollectionProxy__SlowCopyIterator;
01370 }
01371 
01372 //______________________________________________________________________________
01373 TVirtualCollectionProxy::Next_t TGenCollectionProxy::GetFunctionNext(Bool_t read)
01374 {
01375    // See typedef void* (*Next_t)(void *iter, void *end);
01376    // iter and end should be pointer to respectively an iterator to be incremented and the result of colleciton.end()
01377    // 'Next' will increment the iterator 'iter' and return 0 if the iterator reached the end.
01378    // If the end is not reached, 'Next' will return the address of the content unless the collection contains pointers in
01379    // which case 'Next' will return the value of the pointer.
01380    
01381    if ( !fValue ) InitializeEx();
01382 
01383    if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated)) 
01384       return TGenCollectionProxy__VectorNext;
01385    else if ( (fProperties & kIsAssociative) && read)
01386       return TGenCollectionProxy__StagingNext;
01387    else 
01388       return TGenCollectionProxy__SlowNext;
01389 }
01390 
01391 //______________________________________________________________________________
01392 TVirtualCollectionProxy::DeleteIterator_t TGenCollectionProxy::GetFunctionDeleteIterator(Bool_t read)
01393 {
01394    // See typedef void (*DeleteIterator_t)(void *iter);
01395    // If the sizeof iterator is greater than fgIteratorArenaSize, call delete on the addresses,
01396    // Otherwise just call the iterator's destructor.
01397 
01398    if ( !fValue ) InitializeEx();
01399 
01400    if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated)) 
01401       return TGenCollectionProxy__VectorDeleteSingleIterators;
01402    else if ( (fProperties & kIsAssociative) && read)
01403       return TGenCollectionProxy__StagingDeleteSingleIterators;
01404    else 
01405       return TGenCollectionProxy__SlowDeleteSingleIterators;
01406 }
01407 
01408 //______________________________________________________________________________
01409 TVirtualCollectionProxy::DeleteTwoIterators_t TGenCollectionProxy::GetFunctionDeleteTwoIterators(Bool_t read) 
01410 {
01411    // See typedef void (*DeleteTwoIterators_t)(void *begin, void *end);
01412    // If the sizeof iterator is greater than fgIteratorArenaSize, call delete on the addresses,
01413    // Otherwise just call the iterator's destructor.
01414 
01415    if ( fFunctionDeleteTwoIterators ) return fFunctionDeleteTwoIterators;
01416    
01417    if ( !fValue ) InitializeEx();
01418    
01419    if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated)) 
01420       fFunctionDeleteTwoIterators = TGenCollectionProxy__VectorDeleteTwoIterators;
01421    else if ( (fProperties & kIsAssociative) && read)
01422       fFunctionDeleteTwoIterators = TGenCollectionProxy__StagingDeleteTwoIterators;
01423    else 
01424       fFunctionDeleteTwoIterators = TGenCollectionProxy__SlowDeleteTwoIterators;
01425    return fFunctionDeleteTwoIterators;
01426 }
01427 
01428 //______________________________________________________________________________
01429 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version)
01430 {
01431    // Return the set of action necessary to stream in this collection member-wise coming from
01432    // the old value class layout refered to by 'version'.
01433    
01434    TObjArray* arr = 0;
01435    TStreamerInfoActions::TActionSequence *result = 0;
01436    if (fConversionReadMemberWise) {
01437       std::map<std::string, TObjArray*>::iterator it;
01438       
01439       it = fConversionReadMemberWise->find( oldClass->GetName() );
01440       
01441       if( it != fConversionReadMemberWise->end() ) {
01442          arr = it->second;
01443       }
01444       
01445       if (arr) {
01446          result = (TStreamerInfoActions::TActionSequence *)arr->At(version);
01447          if (result) {
01448             return result;
01449          }
01450       }
01451    }
01452    
01453    // Need to create it.
01454    TClass *valueClass = GetValueClass();
01455    if (valueClass == 0) {
01456       return 0;
01457    }
01458    TVirtualStreamerInfo *info = valueClass->GetConversionStreamerInfo(oldClass,version);
01459    if (info == 0) {
01460       return 0;
01461    }
01462    result = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*this);
01463 
01464    if (!arr) {
01465       arr = new TObjArray(version+10, -1);
01466       if (!fConversionReadMemberWise) {
01467          fConversionReadMemberWise = new std::map<std::string, TObjArray*>();
01468       }
01469       (*fConversionReadMemberWise)[oldClass->GetName()] = arr;
01470    }
01471    arr->AddAtAndExpand( result, version );
01472    
01473    return result;
01474 }
01475 
01476 //______________________________________________________________________________
01477 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetReadMemberWiseActions(Int_t version)
01478 {
01479    // Return the set of action necessary to stream in this collection member-wise coming from
01480    // the old value class layout refered to by 'version'.
01481    
01482    TStreamerInfoActions::TActionSequence *result = 0;
01483    if (version < (fReadMemberWise->GetSize()-1)) { // -1 because the 'index' starts at -1
01484       result = (TStreamerInfoActions::TActionSequence *)fReadMemberWise->At(version);
01485    }
01486    if (result == 0) {
01487       // Need to create it.
01488       TClass *valueClass = GetValueClass();
01489       TVirtualStreamerInfo *info = 0;
01490       if (valueClass) {
01491          info = valueClass->GetStreamerInfo(version);
01492       }
01493       result = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*this);
01494       fReadMemberWise->AddAtAndExpand(result,version);
01495    }
01496    return result;
01497 }
01498 
01499 //______________________________________________________________________________
01500 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetWriteMemberWiseActions()
01501 {
01502    // Return the set of action necessary to stream out this collection member-wise.
01503  
01504    R__ASSERT(0 /* Not Implemented yet */);
01505    return 0;
01506 }
01507 

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