Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

PHObjectHandleVectorv1.h

Go to the documentation of this file.
00001 #ifndef __PHOBJECTHANDLEVECTORV1_H__
00002 #define __PHOBJECTHANDLEVECTORV1_H__
00003 
00004 #include "PHObjectHandleVector.h"
00005 #include "TClonesArray.h"
00006 #include <iostream>
00007 #include <vector>
00008 
00017 template<typename BASE, typename DERIVED>
00018 class PHObjectHandleVectorv1 : public PHObjectHandleVector<BASE>
00019 {
00020 public:
00021 
00022   typedef PHObjectHandleVectorv1<BASE,DERIVED> self;
00023   typedef PHObjectHandle<BASE> value_type;
00024   typedef unsigned int size_type;
00025   typedef PHObjectHandleVectorIterator<BASE> iterator;
00026 
00027   PHObjectHandleVectorv1();
00028   PHObjectHandleVectorv1(const self& other);
00029   self& operator=(const self& other);
00030 
00031   virtual ~PHObjectHandleVectorv1();
00032 
00033   virtual value_type& add(const size_type& index);
00034 
00035   virtual value_type& add(const size_type& index, const value_type& value);
00036 
00037   virtual size_type capacity() const;
00038 
00039   virtual self* clone() const;
00040 
00041   virtual self* create() const;
00042 
00043   virtual bool empty() const { return fSize==0; }
00044 
00045   virtual iterator erase(iterator first, iterator last);
00046 
00047   virtual iterator erase(iterator pos) { return erase(pos,pos+1); }
00048 
00049   virtual const value_type& get(const size_type& index) const;
00050 
00051   virtual value_type& get(const size_type& index);
00052 
00053   virtual void identify(std::ostream& os = std::cout) const;
00054 
00055   virtual iterator insert(iterator pos, size_type n, const value_type& value);
00056 
00057   virtual iterator insert(iterator pos, const value_type& value)
00058   { return insert(pos,1,value); }
00059 
00060   virtual bool remove(const size_type& index);
00061 
00062   virtual void reserve(const size_type& thesize);
00063 
00064   virtual void Reset();
00065 
00066   virtual bool resize(const size_type& newsize, const value_type& value);
00067 
00068   virtual bool resize(const size_type& newsize)
00069   { return resize(newsize,value_type()); }
00070   
00071   virtual size_type size() const;
00072 
00073 private:
00074 
00075   void copyTo(self& other) const;
00076   void deallocate();
00077   void delete_last(size_type n);
00078   bool expand(const size_type& n);
00079   void init(size_type n);
00080   bool expand_for(const size_type& index);
00081   void isAliveCapacityok() const;
00082   static const unsigned int fgDefaultCapacity = 10;
00083   static const unsigned int fgMaxCapacity = 1000;
00084 
00085   size_type fSize;
00086   TClonesArray* fArray;
00087 
00088   ClassDefT(PHObjectHandleVectorv1,1)
00089 };
00090 
00091 ClassDef2T2(PHObjectHandleVectorv1,BASE,DERIVED)
00092 
00093 #ifndef __CINT__
00094 
00095 ClassImp2T(PHObjectHandleVectorv1,BASE,DERIVED)
00096 
00097 //_____________________________________________________________________________
00098 template<typename BASE, typename DERIVED>
00099 PHObjectHandleVectorv1<BASE,DERIVED>::PHObjectHandleVectorv1()
00100   : fSize(0),
00101     fArray(0)
00102 {
00103   std::cout << PHWHERE << "PHObjectHandleVectorv1<" << BASE::Class()->GetName() 
00104             << "," << DERIVED::Class()->GetName() 
00105             << "> default ctor" 
00106             << std::endl;
00107   init(fgDefaultCapacity);
00108 }
00109 
00110 //_____________________________________________________________________________
00111 template<typename BASE, typename DERIVED>
00112 PHObjectHandleVectorv1<BASE,DERIVED>::PHObjectHandleVectorv1
00113 (const PHObjectHandleVectorv1<BASE,DERIVED>& other)
00114   : PHObjectHandleVector<BASE>(),
00115     fSize(0),
00116     fArray(0)
00117 {
00118   other.copyTo(*this);
00119 }
00120 
00121 //_____________________________________________________________________________
00122 template<typename BASE, typename DERIVED>
00123 PHObjectHandleVectorv1<BASE,DERIVED>& 
00124 PHObjectHandleVectorv1<BASE,DERIVED>::operator=(const PHObjectHandleVectorv1<BASE,DERIVED>&
00125                                           other)
00126 {
00127   if ( this != &other ) 
00128     {
00129       other.copyTo(*this);
00130     }
00131   return *this;
00132 }
00133 
00134 //_____________________________________________________________________________
00135 template<typename BASE, typename DERIVED>
00136 PHObjectHandleVectorv1<BASE,DERIVED>::~PHObjectHandleVectorv1()
00137 {
00138   deallocate();
00139 }
00140 
00141 //_____________________________________________________________________________
00142 template<typename BASE, typename DERIVED>
00143 typename PHObjectHandleVectorv1<BASE,DERIVED>::value_type&
00144 PHObjectHandleVectorv1<BASE,DERIVED>::add(const size_type& index)
00145 {
00146   if ( index >= capacity() )
00147     {
00148       // try to reallocate more space
00149       bool ok = expand_for(index);
00150       if (!ok)
00151         {
00152           std::cerr << PHWHERE << " object is full ?!" << std::endl;
00153           throw;
00154         }                      
00155     }
00156 
00157   new ((*fArray)[index]) value_type(new DERIVED);
00158 
00159   if (index+1>fSize)
00160     {
00161       fSize=index+1; 
00162    }
00163   return get(index);
00164 }
00165 
00166 //_____________________________________________________________________________
00167 template<typename BASE, typename DERIVED>
00168 typename PHObjectHandleVectorv1<BASE,DERIVED>::value_type&
00169 PHObjectHandleVectorv1<BASE,DERIVED>::add(const size_type& index,
00170                                           const value_type& value)
00171 {
00172   // we must first insure that the value we got is of the
00173   // type we expect...
00174   const DERIVED* test = 
00175     dynamic_cast<const DERIVED*>(value.get());
00176 
00177   if (!test)
00178     {
00179       std::cerr << PHWHERE << " handle is of the wrong type" << std::endl;
00180       throw;
00181     }
00182 
00183   if ( index >= capacity() )
00184     {
00185       // try to reallocate more space
00186       bool ok = expand_for(index);
00187       if (!ok)
00188         {
00189           std::cerr << PHWHERE << " object is full ?!" << std::endl;
00190           throw;
00191         }                      
00192     }
00193 
00194   // the next line implies that the DERIVED class must
00195   // have a copy ctor (that should be fairly common, should'nt it ?)
00196   new ((*fArray)[index]) value_type(value);
00197 
00198   if (index+1>fSize)
00199     {
00200       fSize=index+1;
00201     }
00202   return get(index);
00203 }
00204 
00205 //_____________________________________________________________________________
00206 template<typename BASE, typename DERIVED>
00207 typename PHObjectHandleVectorv1<BASE,DERIVED>::size_type
00208 PHObjectHandleVectorv1<BASE,DERIVED>::capacity() const
00209 {
00210   if ( fArray )
00211     {
00212       return fArray->GetSize();
00213     }
00214   else
00215     {
00216       return 0;
00217     }
00218 }
00219 
00220 //_____________________________________________________________________________
00221 template<typename BASE, typename DERIVED>
00222 void
00223 PHObjectHandleVectorv1<BASE,DERIVED>::copyTo
00224 (PHObjectHandleVectorv1<BASE,DERIVED>& other) const
00225 {
00226   other.init(size());
00227 
00228   other.fSize = size();
00229 
00230   for ( size_t i = 0; i < size(); ++i ) 
00231     {
00232       assert(0==1);
00233   //     DERIVED* ptr = static_cast<DERIVED*>(get(i));
00234 //       TClonesArray& arr = *(other.fArray);      
00235 //       if (ptr)
00236 //      {
00237 //        std::cout << "Copying " << i << std::endl;
00238 //        new ( arr[i] ) DERIVED(*ptr);
00239 //      }
00240 //       else
00241 //      {
00242 //        std::cout << i << " is null" << std::endl;
00243 //      }
00244 //      other.fKeepAlive[i] = new value_type(newone);
00245     }
00246 }
00247 
00248 //_____________________________________________________________________________
00249 template<typename BASE, typename DERIVED>
00250 PHObjectHandleVectorv1<BASE,DERIVED>*
00251 PHObjectHandleVectorv1<BASE,DERIVED>::clone() const
00252 {
00253   return new PHObjectHandleVectorv1<BASE,DERIVED>(*this);
00254 }
00255 
00256 //_____________________________________________________________________________
00257 template<typename BASE, typename DERIVED>
00258 PHObjectHandleVectorv1<BASE,DERIVED>*
00259 PHObjectHandleVectorv1<BASE,DERIVED>::create() const
00260 {
00261   return new PHObjectHandleVectorv1<BASE,DERIVED>();
00262 }
00263 
00264 //_____________________________________________________________________________
00265 template<typename BASE, typename DERIVED>
00266 void
00267 PHObjectHandleVectorv1<BASE,DERIVED>::deallocate()
00268 {  
00269   if ( fArray )
00270     {
00271       fArray->Delete();
00272     }
00273   delete fArray;
00274   fArray=0;
00275   fSize=0;
00276 }
00277 
00278 //_____________________________________________________________________________
00279 template<typename BASE, typename DERIVED>
00280 void
00281 PHObjectHandleVectorv1<BASE,DERIVED>::delete_last(size_type n)
00282 {
00283   for ( size_type i = 0; i < n; ++i )
00284     {
00285       assert(size()>=1);
00286       size_type pos = size()-1;
00287       fArray->RemoveAt(pos);
00288       --fSize;
00289     }
00290 }
00291 
00292 //_____________________________________________________________________________
00293 template<typename BASE, typename DERIVED>
00294 typename PHObjectHandleVectorv1<BASE,DERIVED>::iterator
00295 PHObjectHandleVectorv1<BASE,DERIVED>::erase
00296 (PHObjectHandleVectorv1<BASE,DERIVED>::iterator first,
00297  PHObjectHandleVectorv1<BASE,DERIVED>::iterator last)
00298 {
00299   std::copy(last,end(),first);
00300   
00301   delete_last(last-first);
00302 
00303   return first;
00304 }
00305 
00306 //_____________________________________________________________________________
00307 template<typename BASE, typename DERIVED>
00308 bool
00309 PHObjectHandleVectorv1<BASE,DERIVED>::expand(const size_type& newcap)
00310 {
00311   if ( newcap < fgMaxCapacity )
00312     {
00313       assert(fArray!=0);
00314       fArray->Expand(newcap);
00315       return true;
00316     }
00317   else
00318     {
00319       std::cerr << "PHObjectHandleVectorv1<BASE,DERIVED>::expand : attempting to go"
00320                 << " above maxsize of " << fgMaxCapacity
00321                 << ". That's a *big* failure probably."
00322                 << std::endl;
00323       return false;
00324     }
00325 }
00326 
00327 //_____________________________________________________________________________
00328 template<typename BASE, typename DERIVED>
00329 const typename PHObjectHandleVectorv1<BASE,DERIVED>::value_type&
00330 PHObjectHandleVectorv1<BASE,DERIVED>::get(const size_type& index) const
00331 {
00332   TObject* obj = fArray->At(index);
00333   assert(obj!=0);
00334   value_type* val = static_cast<value_type*>(obj);
00335   return *val;
00336 }
00337 
00338 //_____________________________________________________________________________
00339 template<typename BASE, typename DERIVED>
00340 typename PHObjectHandleVectorv1<BASE,DERIVED>::value_type&
00341 PHObjectHandleVectorv1<BASE,DERIVED>::get(const size_type& index)
00342 {
00343   TObject* obj = fArray->At(index);
00344   assert(obj!=0);
00345   value_type* val = static_cast<value_type*>(obj);
00346   return *val;
00347 }
00348 
00349 //_____________________________________________________________________________
00350 template<typename BASE, typename DERIVED>
00351 void
00352 PHObjectHandleVectorv1<BASE,DERIVED>::identify(std::ostream& os) const
00353 {
00354   os << "PHObjectHandleVectorv1<" << BASE::Class()->GetName()
00355      << "," << DERIVED::Class()->GetName()
00356      << ">::identify() " 
00357      << "size=" << size() 
00358      << " capacity=" << capacity()
00359      << " fArray.size=" << fArray->GetLast()
00360      << " fArray.capacity=" << fArray->GetSize()
00361      << std::endl;
00362   for ( size_t i = 0; i < capacity(); ++i ) 
00363     {
00364       os << i << " ptr=" << fArray->At(i)
00365          << " " << " kptr=";
00366       if ( fArray->At(i) )
00367         {
00368           value_type* val = static_cast<value_type*>(fArray->At(i));
00369           (*val)->identify();
00370         }
00371       os << std::endl;
00372     }
00373 }
00374 
00375 //_____________________________________________________________________________
00376 template<typename BASE, typename DERIVED>
00377 void
00378 PHObjectHandleVectorv1<BASE,DERIVED>::init(size_type n)
00379 {
00380   deallocate();
00381   reserve(n);
00382 }
00383 
00384 //_____________________________________________________________________________
00385 template<typename BASE, typename DERIVED>
00386 typename PHObjectHandleVectorv1<BASE,DERIVED>::iterator
00387 PHObjectHandleVectorv1<BASE,DERIVED>::insert(iterator pos, size_type n, const value_type& val)
00388 {
00389   size_type c = pos + n - begin();
00390 
00391   if ( c > capacity() )
00392     {
00393       std::cout << "insert : will have to expand" << std::endl;
00394       bool ok = expand_for(c);
00395       if (!ok)
00396         {
00397           return end();
00398         }
00399     }
00400 
00401   ++fSize;
00402 
00403   std::copy(pos,pos+n,pos+1);
00404 
00405   *pos = val;
00406 
00407   new ((*fArray)[pos-begin()]) DERIVED(*(static_cast<DERIVED*>((*pos).get())));
00408 
00409   fSize +=n ;
00410   return begin()+n;
00411 }
00412 
00413 //_____________________________________________________________________________
00414 template<typename BASE, typename DERIVED>
00415 bool
00416 PHObjectHandleVectorv1<BASE,DERIVED>::remove(const size_type& index)
00417 {
00418   if ( index < size() ) 
00419     {
00420       erase(begin()+index);
00421       return true;
00422     }
00423   else
00424     {
00425       return false;
00426     }
00427 }
00428 
00429 //_____________________________________________________________________________
00430 template<typename BASE, typename DERIVED>
00431 void
00432 PHObjectHandleVectorv1<BASE,DERIVED>::reserve(const size_type& n)
00433 {
00434   if (!fArray)
00435     {
00436       fArray = new TClonesArray(value_type::Class()->GetName(),n);
00437     }
00438   else
00439     {
00440       fArray->Expand(n);
00441     }
00442  
00443 }
00444 
00445 //_____________________________________________________________________________
00446 template<typename BASE, typename DERIVED>
00447 void
00448 PHObjectHandleVectorv1<BASE,DERIVED>::Reset()
00449 {
00450   assert(fArray!=0);
00451   fArray->Delete();
00452   fSize=0;
00453 }
00454 
00455 //_____________________________________________________________________________
00456 template<typename BASE, typename DERIVED>
00457 bool
00458 PHObjectHandleVectorv1<BASE,DERIVED>::resize(const size_type& newsize,
00459                                              const value_type& /*value*/)
00460 {
00461   reserve(newsize);
00462   return true;
00463 }
00464 
00465 //_____________________________________________________________________________
00466 template<typename BASE, typename DERIVED>
00467 bool
00468 PHObjectHandleVectorv1<BASE,DERIVED>::expand_for(const size_type& index)
00469 {
00470   size_type capa = capacity();
00471 
00472   while ( index >= capa && capa < fgMaxCapacity ) 
00473     {
00474       capa *= 2;
00475     }
00476   if ( capa >= fgMaxCapacity )
00477     {
00478       return false;
00479     }
00480   else
00481     {
00482       assert(capa>capacity());
00483       return expand(capa);
00484     }
00485 }
00486 
00487 //_____________________________________________________________________________
00488 template<typename BASE, typename DERIVED>
00489 typename PHObjectHandleVectorv1<BASE,DERIVED>::size_type
00490 PHObjectHandleVectorv1<BASE,DERIVED>::size() const
00491 {
00492   return fSize;
00493 }
00494 
00495 #endif // __CINT__
00496 
00497 #endif