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

PHObjectVectorSTL.h

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