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