TVirtualCollectionIterators.h

Go to the documentation of this file.
00001 // @(#)root/cont:$Id: TVirtualCollectionIterators.h 36338 2010-10-13 14:06:27Z pcanal $
00002 // Author: Philippe Canal 20/08/2010
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2003, Rene Brun, Fons Rademakers and al.           *
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 #ifndef ROOT_TVirtualCollectionIterators
00013 #define ROOT_TVirtualCollectionIterators
00014 
00015 //////////////////////////////////////////////////////////////////////////
00016 //                                                                      //
00017 // TVirtualCollectionIterators                                          //
00018 //                                                                      //
00019 // Small helper class to generically acquire and release iterators      //
00020 //                                                                      //
00021 //////////////////////////////////////////////////////////////////////////
00022 
00023 #ifndef ROOT_TVirtualCollectionProxy
00024 #include "TVirtualCollectionProxy.h"
00025 #endif
00026 #ifndef ROOT_TError
00027 #include "TError.h"
00028 #endif
00029 
00030 class TVirtualCollectionIterators
00031 {
00032 private:
00033    TVirtualCollectionIterators(); // Intentionally unimplemented.
00034    TVirtualCollectionIterators(const TVirtualCollectionIterators&); // Intentionally unimplemented.
00035    
00036 public:
00037    // Note when the collection is a vector, fBegin and fEnd points to
00038    // the start and end of the memory content rather than to the address
00039    // of iterators (saving one dereference when being used).
00040    
00041    typedef TVirtualCollectionProxy::CreateIterators_t CreateIterators_t;
00042    typedef TVirtualCollectionProxy::DeleteTwoIterators_t DeleteTwoIterators_t;
00043    
00044    char  fBeginBuffer[TVirtualCollectionProxy::fgIteratorArenaSize];
00045    char  fEndBuffer[TVirtualCollectionProxy::fgIteratorArenaSize];
00046    void *fBegin; // Pointer to the starting iterator (collection->begin())
00047    void *fEnd;   // Pointer to the ending iterator (collection->end())
00048    CreateIterators_t    fCreateIterators;
00049    DeleteTwoIterators_t fDeleteTwoIterators;
00050    
00051    TVirtualCollectionIterators(TVirtualCollectionProxy *proxy) : fBegin( &(fBeginBuffer[0]) ), fEnd(&(fEndBuffer[0])), fCreateIterators(0), fDeleteTwoIterators(0) 
00052    {
00053       //         memset(fBeginBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
00054       //         memset(fEndBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
00055       if (proxy) {
00056          fCreateIterators = proxy->GetFunctionCreateIterators();
00057          fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators();
00058       } else {
00059          ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
00060       }
00061    }
00062    TVirtualCollectionIterators(CreateIterators_t creator, DeleteTwoIterators_t destruct) : fBegin( &(fBeginBuffer[0]) ), fEnd(&(fEndBuffer[0])), fCreateIterators(creator), fDeleteTwoIterators(destruct) 
00063    {
00064    }
00065    
00066    inline void CreateIterators(void *collection)
00067    {
00068       // Initialize the fBegin and fEnd iterators.
00069       
00070       fCreateIterators(collection, &fBegin, &fEnd);
00071    }
00072    
00073    inline ~TVirtualCollectionIterators() 
00074    {
00075       if (fBegin != &(fBeginBuffer[0])) {
00076          // assert(end != endbuf);
00077          fDeleteTwoIterators(fBegin,fEnd);
00078       }      
00079    }
00080 };
00081 
00082 class TVirtualCollectionPtrIterators
00083 {
00084 public:
00085    typedef TVirtualCollectionProxy::Next_t Next_t;
00086    typedef TVirtualCollectionProxy::CopyIterator_t Copy_t;
00087    typedef TVirtualCollectionProxy::CreateIterators_t CreateIterators_t;
00088    typedef TVirtualCollectionProxy::DeleteIterator_t Delete_t;
00089    typedef TVirtualCollectionProxy::DeleteTwoIterators_t DeleteTwoIterators_t;
00090    
00091 private:
00092    TVirtualCollectionPtrIterators(); // Intentionally unimplemented.
00093    TVirtualCollectionPtrIterators(const TVirtualCollectionPtrIterators&); // Intentionally unimplemented.
00094    
00095    CreateIterators_t    fCreateIterators;
00096    DeleteTwoIterators_t fDeleteTwoIterators;
00097    
00098    Bool_t fAllocated;
00099 
00100    char  fRawBeginBuffer[TVirtualCollectionProxy::fgIteratorArenaSize];
00101    char  fRawEndBuffer[TVirtualCollectionProxy::fgIteratorArenaSize];
00102 
00103    struct TInternalIterator {
00104       TInternalIterator() : fCopy(0),fDelete(0),fNext(0),fIter(0) {}
00105       TInternalIterator(const TInternalIterator &source) : fCopy(source.fCopy),fDelete(source.fDelete),fNext(source.fNext),fIter(0) {}
00106 
00107       Copy_t    fCopy;
00108       Delete_t  fDelete;
00109       Next_t    fNext;
00110 
00111       void     *fIter;
00112    };
00113    
00114    TInternalIterator fBeginBuffer;
00115    TInternalIterator fEndBuffer;
00116 
00117 public:
00118    // Note when the collection is a vector, fBegin and fEnd points to
00119    // the start and end of the memory content rather than to the address
00120    // of iterators (saving one dereference when being used).
00121    
00122    void *fBegin; // Pointer to the starting iterator (collection->begin())
00123    void *fEnd;   // Pointer to the ending iterator (collection->end())
00124    
00125    TVirtualCollectionPtrIterators(TVirtualCollectionProxy *proxy) : fCreateIterators(0), fDeleteTwoIterators(0), fAllocated(kFALSE),
00126                                                                     fBegin( &(fRawBeginBuffer[0]) ),
00127                                                                     fEnd( &(fRawEndBuffer[0]) )
00128    {
00129       //         memset(fBeginBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
00130       //         memset(fEndBuffer,0,TVirtualCollectionProxy::fgIteratorArenaSize);
00131       if (proxy) {
00132          fCreateIterators = proxy->GetFunctionCreateIterators();
00133          fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators();
00134          
00135          fEndBuffer.fCopy = fBeginBuffer.fCopy = proxy->GetFunctionCopyIterator();
00136          fEndBuffer.fNext = fBeginBuffer.fNext = proxy->GetFunctionNext();
00137          fEndBuffer.fDelete = fBeginBuffer.fDelete = proxy->GetFunctionDeleteIterator();
00138       } else {
00139          ::Fatal("TIterators::TIterators","Created with out a collection proxy!\n");
00140       }
00141    }
00142    
00143    inline void CreateIterators(void *collection)
00144    {
00145       // Initialize the fBegin and fEnd iterators.
00146       
00147       fBegin = &(fRawBeginBuffer[0]);
00148       fEnd = &(fRawEndBuffer[0]);
00149       fCreateIterators(collection, &fBegin, &fEnd);
00150       if (fBegin != &(fRawBeginBuffer[0])) {
00151          // The iterator where too large to buffer in the  buffer
00152          fAllocated = kTRUE;
00153       }
00154       fBeginBuffer.fIter = fBegin;
00155       fEndBuffer.fIter = fEnd;
00156       fBegin = &fBeginBuffer;
00157       fEnd = &fEndBuffer;
00158    }
00159    
00160    inline ~TVirtualCollectionPtrIterators() 
00161    {
00162       if (fAllocated) {
00163          // assert(end != endbuf);
00164          fDeleteTwoIterators(fBeginBuffer.fIter,fEndBuffer.fIter);
00165       }
00166    }
00167    
00168    static void *Next(void *iter, const void *end) 
00169    {
00170       TInternalIterator *internal_iter = (TInternalIterator*) iter;
00171       TInternalIterator *internal_end = (TInternalIterator*) end;
00172       
00173       void **ptr = (void**)internal_iter->fNext(internal_iter->fIter,internal_end->fIter);
00174       if(ptr) return *ptr;
00175       else return 0;
00176    }
00177    
00178    static void DeleteIterator(void *iter)
00179    {
00180       TInternalIterator *internal_iter = (TInternalIterator*) iter;
00181       if (internal_iter->fDelete) {
00182          internal_iter->fDelete(internal_iter->fIter);
00183       }
00184    }
00185    
00186    static void *CopyIterator(void *dest, const void *source)
00187    {
00188       TInternalIterator *internal_source = (TInternalIterator*)source;
00189       TInternalIterator *internal_dest = new TInternalIterator(*internal_source);
00190       
00191       void *newiter = internal_source->fCopy(dest,internal_source->fIter);
00192       if (newiter == dest) {
00193          internal_dest->fDelete = 0;
00194       }
00195       internal_dest->fIter = newiter;
00196       return internal_dest;
00197    }
00198 };
00199 
00200 // Specialization of TVirtualCollectionIterators when we know the collection
00201 // to be a vector (hence there is nothing to delete at the end).
00202 struct TVirtualVectorIterators
00203 {
00204 private:
00205    TVirtualVectorIterators(const TVirtualVectorIterators&); // Intentionally unimplemented.
00206    
00207 public:
00208    // Note when the collection is a vector, fBegin and fEnd points to
00209    // the start and end of the memory content rather than to the address
00210    // of iterators (saving one dereference when being used).
00211    
00212    typedef TVirtualCollectionProxy::CreateIterators_t CreateIterators_t;
00213 
00214    void *fBegin; // Pointer to the starting iterator (collection->begin())
00215    void *fEnd;   // Pointer to the ending iterator (collection->end())
00216    
00217    TVirtualVectorIterators(TVirtualCollectionProxy * /* proxy */) : fBegin(0), fEnd(0)
00218    {
00219       // fCreateIterators = proxy->GetFunctionCreateIterators();
00220    }
00221    
00222    TVirtualVectorIterators(CreateIterators_t /* creator */) : fBegin(0), fEnd(0)
00223    {
00224       // fCreateIterators = creator;
00225    }
00226    
00227    TVirtualVectorIterators() : fBegin(0), fEnd(0) 
00228    {
00229       // Default constructor.
00230    }
00231    
00232    inline void CreateIterators(void *collection)
00233    {
00234       // Initialize the fBegin and fEnd iterators.
00235       
00236       // We can safely assume that the std::vector layout does not really depend on
00237       // the content!
00238       std::vector<char> *vec = (std::vector<char>*)collection;
00239       if (vec->empty()) {
00240          fBegin = 0;
00241          fEnd = 0;
00242          return;
00243       }
00244       fBegin= &(*vec->begin());
00245 #ifdef R__VISUAL_CPLUSPLUS
00246       fEnd = &(*(vec->end()-1)) + 1; // On windows we can not dererence the end iterator at all.
00247 #else
00248       // coverity[past_the_end] Safe on other platforms
00249       fEnd = &(*vec->end());
00250 #endif
00251       //fCreateIterators(collection, &fBegin, &fEnd);
00252    }
00253 };
00254 
00255 #endif // ROOT_TVirtualCollectionIterators
00256 

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