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

PHObjectVectorTCA.h

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