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