00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef QPTRVECTOR_H
00023 #define QPTRVECTOR_H
00024
00025 #if _MSC_VER==1200
00026 #pragma warning(disable: 4786)
00027 #endif
00028
00029 #include <vector>
00030 #include <algorithm>
00031 #include "fxdefs.h"
00032 #include "FXStream.h"
00033 #include "FXException.h"
00034
00035 namespace FX {
00036
00037 typedef FXuint uint;
00038
00070 template<class type> class QPtrVectorIterator;
00071 template<class type> class QPtrVector : private std::vector<type *>
00072 {
00073 bool autodel;
00074 public:
00075 explicit QPtrVector(bool wantAutoDel=false) : autodel(wantAutoDel), std::vector<type *>() {}
00076 explicit QPtrVector(std::vector<type *> &l) : autodel(false), std::vector<type *>(l) {}
00077 ~QPtrVector() { clear(); }
00078 FXADDMOVEBASECLASS(QPtrVector, std::vector<type *>)
00080 bool autoDelete() const { return autodel; }
00082 void setAutoDelete(bool a) { autodel=a; }
00083
00085 type **data() const { return &std::vector<type *>::front(); }
00086 using std::vector<type *>::size;
00088 using std::vector<type *>::capacity;
00090 using std::vector<type *>::reserve;
00092 uint count() const { return (uint) std::vector<type *>::size(); }
00094 bool isEmpty() const { return std::vector<type *>::empty(); }
00096 bool insert(uint i, const type *d) { FXEXCEPTION_STL1 { std::vector<type *>::insert(std::vector<type *>::begin()+i, const_cast<type *>(d)); } FXEXCEPTION_STL2; return true; }
00098 bool insertAtIter(QPtrVectorIterator<type> &it, const type *d);
00100 void inSort(const type *d)
00101 {
00102 for(typename std::vector<type *>::iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it)
00103 {
00104 if(compareItems(*it, const_cast<type *>(d))>=0)
00105 {
00106 FXEXCEPTION_STL1 { std::vector<type *>::insert(it, const_cast<type *>(d)); } FXEXCEPTION_STL2;
00107 }
00108 }
00109 }
00111 void append(const type *d) { FXEXCEPTION_STL1 { push_back(const_cast<type *>(d)); } FXEXCEPTION_STL2; }
00113 bool extend(uint no)
00114 {
00115 uint cs=(uint) std::vector<type *>::size();
00116 if(cs<no)
00117 {
00118 std::vector<type *>::resize(no);
00119 return true;
00120 }
00121 return false;
00122 }
00124 bool remove(uint i)
00125 {
00126 if(isEmpty()) return false;
00127 typename std::vector<type *>::iterator it=std::vector<type *>::begin()+i;
00128 deleteItem(*it);
00129 erase(it);
00130 return true;
00131 }
00133 bool remove(const type *d)
00134 {
00135 for(typename std::vector<type *>::iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it)
00136 {
00137 if(0==compareItems(*it, const_cast<type *>(d)))
00138 {
00139 deleteItem(*it);
00140 erase(it);
00141 return true;
00142 }
00143 }
00144 return false;
00145 }
00147 bool removeRef(const type *d)
00148 {
00149 for(typename std::vector<type *>::iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it)
00150 {
00151 if(*it==d)
00152 {
00153 deleteItem(*it);
00154 erase(it);
00155 return true;
00156 }
00157 }
00158 return false;
00159 }
00161 bool removeByIter(QPtrVectorIterator<type> &it);
00163 bool removeLast()
00164 {
00165 if(isEmpty()) return false;
00166 typename std::vector<type *>::iterator it=--std::vector<type *>::end();
00167 deleteItem(*it);
00168 std::vector<type *>::pop_back();
00169 return true;
00170 }
00172 type *take(uint i)
00173 {
00174 if(isEmpty()) return 0;
00175 typename std::vector<type *>::iterator it=std::vector<type *>::begin()+i;
00176 type *ret=*it;
00177 std::vector<type *>::erase(it);
00178 return ret;
00179 }
00181 bool take(const type *d)
00182 {
00183 for(typename std::vector<type *>::iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it)
00184 {
00185 if(0==compareItems(*it, const_cast<type *>(d)))
00186 {
00187 std::vector<type *>::erase(it);
00188 return true;
00189 }
00190 }
00191 return false;
00192 }
00194 bool takeRef(const type *d)
00195 {
00196 for(typename std::vector<type *>::iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it)
00197 {
00198 if(*it==d)
00199 {
00200 std::vector<type *>::erase(it);
00201 return true;
00202 }
00203 }
00204 return false;
00205 }
00207 bool takeByIter(QPtrVectorIterator<type> &it);
00209 bool takeLast()
00210 {
00211 if(isEmpty()) return false;
00212 typename std::vector<type *>::iterator it=--std::vector<type *>::end();
00213 std::vector<type *>::pop_back();
00214 return true;
00215 }
00217 void clear()
00218 {
00219 for(typename std::vector<type *>::iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it)
00220 {
00221 deleteItem(*it);
00222 }
00223 std::vector<type *>::clear();
00224 }
00225 private:
00226 struct SortPredicate
00227 {
00228 QPtrVector *me;
00229 SortPredicate(QPtrVector *_me) : me(_me) { }
00230 bool operator()(type *a, type *b)
00231 {
00232 return me->compareItems(a, b)==-1;
00233 }
00234 };
00235 public:
00237 template<class SortFunc> void sort(SortFunc sortfunc)
00238 {
00239 std::sort(std::vector<type *>::begin(), std::vector<type *>::end(), sortfunc);
00240 }
00242 void sort()
00243 {
00244 std::sort(std::vector<type *>::begin(), std::vector<type *>::end(), SortPredicate(this));
00245 }
00247 int find(const type *d)
00248 {
00249 int idx=0;
00250 for(typename std::vector<type *>::iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it, ++idx)
00251 {
00252 if(0==compareItems(*it, const_cast<type *>(d))) return idx;
00253 }
00254 return -1;
00255 }
00257 int findRef(const type *d)
00258 {
00259 int idx=0;
00260 for(typename std::vector<type *>::iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it, ++idx)
00261 {
00262 if(*it==d) return idx;
00263 }
00264 return -1;
00265 }
00267 uint contains(const type *d) const
00268 {
00269 uint count=0;
00270 for(typename std::vector<type *>::const_iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it)
00271 {
00272 if(0==compareItems(const_cast<type *>(*it), const_cast<type *>(d))) count++;
00273 }
00274 return count;
00275 }
00277 uint containsRef(const type *d) const
00278 {
00279 uint count=0;
00280 for(typename std::vector<type *>::const_iterator it=std::vector<type *>::begin(); it!=std::vector<type *>::end(); ++it)
00281 {
00282 if(*it==d) count++;
00283 }
00284 return count;
00285 }
00287 bool replace(uint i, const type *d, bool callDeleteItem=true)
00288 {
00289 if(isEmpty()) return false;
00290 typename std::vector<type *>::iterator it=std::vector<type *>::begin()+i;
00291 if(callDeleteItem)
00292 deleteItem(*it);
00293 *it=const_cast<type *>(d);
00294
00295
00296 return true;
00297 }
00299 bool replaceAtIter(QPtrVectorIterator<type> &it, const type *d, bool callDeleteItem=true);
00301 type *at(uint i) const { return std::vector<type *>::empty() ? 0 : *(std::vector<type *>::begin()+i); }
00303 type *operator[](uint i) const { return at(i); }
00305 type *operator[](int i) const { return at((uint) i); }
00307 type *getFirst() const { return std::vector<type *>::empty() ? 0 : std::vector<type *>::front(); }
00309 type *getLast() const { return std::vector<type *>::empty() ? 0 : std::vector<type *>::back(); }
00311 type *first() { return std::vector<type *>::empty() ? 0 : std::vector<type *>::front(); }
00313 type *last() { return std::vector<type *>::empty() ? 0 : std::vector<type *>::back(); }
00315 virtual int compareItems(type *a, type *b) const { return (a<b) ? -1 : (a==b) ? 0 : -1; }
00316
00317 typename std::vector<type *> &int_vector() { return static_cast<std::vector<type *> &>(*this); }
00318 typename std::vector<type *>::iterator int_begin() { return std::vector<type *>::begin(); }
00319 typename std::vector<type *>::iterator int_end() { return std::vector<type *>::end(); }
00320
00321 protected:
00322 virtual void deleteItem(type *d);
00323 };
00324
00325
00326 template<> inline void QPtrVector<void>::deleteItem(void *)
00327 {
00328 }
00329
00330 template<class type> inline void QPtrVector<type>::deleteItem(type *d)
00331 {
00332 if(autodel) delete d;
00333 }
00334
00339 template<class type> class QPtrVectorIterator
00340 {
00341 typename std::vector<type *>::iterator me;
00342 mutable bool dead;
00343 QPtrVector<type> *myvector;
00344 protected:
00345 type *retptr() const
00346 {
00347 if(dead) return 0;
00348 if(myvector->int_end()==me) { dead=true; return 0; }
00349 return *me;
00350 }
00351 public:
00352 typename std::vector<type *>::iterator &int_getIterator() { return me; }
00353 QPtrVectorIterator() : dead(true), myvector(0) { }
00355 QPtrVectorIterator(const QPtrVector<type> &l) : dead(false), myvector(&const_cast<QPtrVector<type> &>(l)), me(const_cast<QPtrVector<type> &>(l).int_begin()) { }
00356 QPtrVectorIterator(const QPtrVectorIterator<type> &l) : dead(l.dead), myvector(l.myvector), me(l) { }
00357 QPtrVectorIterator<type> &operator=(const QPtrVectorIterator<type> &it)
00358 {
00359 dead=it.dead; myvector=it.myvector;
00360 me=it.me;
00361 return *this;
00362 }
00363 bool operator==(const QPtrVectorIterator &o) const { return me==o.me; }
00364 bool operator!=(const QPtrVectorIterator &o) const { return me!=o.me; }
00365 bool operator<(const QPtrVectorIterator &o) const { return me<o.me; }
00366 bool operator>(const QPtrVectorIterator &o) const { return me>o.me; }
00368 uint count() const { return myvector->count(); }
00370 bool isEmpty() const { return myvector->isEmpty(); }
00372 bool atFirst() const
00373 {
00374 return myvector->int_begin()==me;
00375 }
00377 bool atLast() const
00378 {
00379 typename std::vector<type *>::iterator next(me);
00380 ++next;
00381 return myvector->int_end()==next;
00382 }
00384 type *toFirst()
00385 {
00386 me=myvector->int_begin(); dead=false;
00387 return retptr();
00388 }
00390 type *toLast()
00391 {
00392 me=myvector->int_end(); dead=false;
00393 if(!myvector->isEmpty()) --me;
00394 return retptr();
00395 }
00397 QPtrVectorIterator<type> &makeDead()
00398 {
00399 me=myvector->int_end();
00400 dead=true;
00401 return *this;
00402 }
00404 operator type *() const { return retptr(); }
00406 type *operator*() { return retptr(); }
00408 type *current() const { return retptr(); }
00410 type *operator()() { return retptr(); }
00412 type *operator++()
00413 {
00414 ++me;
00415 return retptr();
00416 }
00418 type *operator+=(uint j)
00419 {
00420 typename std::vector<type *>::difference_type left=myvector->int_end()-me;
00421 if(j>left) dead=true; else me+=j;
00422 return retptr();
00423 }
00425 type *operator--()
00426 {
00427 if(myvector->int_begin()==me) dead=true; else --me;
00428 return retptr();
00429 }
00431 type *operator-=(uint j)
00432 {
00433 typename std::vector<type *>::difference_type left=me-myvector->int_begin();
00434 if(j>left+1) dead=true; else me-=j;
00435 return retptr();
00436 }
00437 };
00438
00439 template<class type> inline bool QPtrVector<type>::insertAtIter(QPtrVectorIterator<type> &it, const type *d)
00440 {
00441 FXEXCEPTION_STL1 { std::vector<type *>::insert(it.int_getIterator(), const_cast<type *>(d));} FXEXCEPTION_STL2;
00442 return true;
00443 }
00444
00445 template<class type> inline bool QPtrVector<type>::removeByIter(QPtrVectorIterator<type> &it)
00446 {
00447 deleteItem(*it.int_getIterator());
00448 std::vector<type *>::erase(it.int_getIterator());
00449 return true;
00450 }
00451
00452 template<class type> inline bool QPtrVector<type>::takeByIter(QPtrVectorIterator<type> &it)
00453 {
00454 std::vector<type *>::erase(it.int_getIterator());
00455 return true;
00456 }
00457
00458 template<class type> inline bool QPtrVector<type>::replaceAtIter(QPtrVectorIterator<type> &it, const type *d, bool callDeleteItem)
00459 {
00460 if(callDeleteItem)
00461 deleteItem(*it);
00462 *it.int_getIterator()=const_cast<type *>(d);
00463 return true;
00464 }
00465
00467 #define QVector QPtrVector
00469 #define QVectorIterator QPtrVectorIterator
00470
00472 template<class type> FXStream &operator<<(FXStream &s, const QPtrVector<type> &i)
00473 {
00474 FXuint mysize=i.count();
00475 s << mysize;
00476 for(QPtrVectorIterator<type> it(i); it.current(); ++it)
00477 {
00478 s << *it.current();
00479 }
00480 return s;
00481 }
00483 template<class type> FXStream &operator>>(FXStream &s, QPtrVector<type> &i)
00484 {
00485 FXuint mysize;
00486 s >> mysize;
00487 i.clear();
00488 for(uint n=0; n<mysize; n++)
00489 {
00490 type *item;
00491 FXERRHM(item=new type);
00492 s >> *item;
00493 i.append(item);
00494 }
00495 return s;
00496 }
00497
00498 }
00499
00500 #endif
00501