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