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

PHObjectHandleVectorv2.h

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