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