00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef QPTRLIST_H
00023 #define QPTRLIST_H
00024
00025 #if _MSC_VER==1200
00026 #pragma warning(disable: 4786)
00027 #endif
00028
00029 #include "qvaluelist.h"
00030 #include "FXException.h"
00031 #include "FXStream.h"
00032
00033 namespace FX {
00034
00035 typedef FXuint uint;
00036
00060 template<class type, class allocator=FX::aligned_allocator<type *, 0> > class QPtrListIterator;
00061 template<class type, class allocator=FX::aligned_allocator<type *, 0> > class QPtrList;
00062 template<class type, class allocator> class QPtrList : protected std::list<type *, allocator>
00063 {
00064 public:
00065 typedef std::list<type *, allocator> Base;
00066 private:
00067 bool autodel;
00068 typename Base::iterator int_idx(uint i)
00069 {
00070 typename Base::iterator it=Base::begin();
00071 while(i--) ++it;
00072 return it;
00073 }
00074 public:
00075 explicit QPtrList(bool wantAutoDel=false) : autodel(wantAutoDel), Base() {}
00076 explicit QPtrList(Base &l) : autodel(false), Base(l) {}
00077 ~QPtrList() { clear(); }
00078 FXADDMOVEBASECLASS(QPtrList, Base)
00080 bool autoDelete() const { return autodel; }
00082 void setAutoDelete(bool a) { autodel=a; }
00083
00085 uint count() const { return (uint) Base::size(); }
00087 bool isEmpty() const { return Base::empty(); }
00089 bool insert(uint i, const type *d) { FXEXCEPTION_STL1 { Base::insert(int_idx(i), d); } FXEXCEPTION_STL2; return true; }
00091 bool insertAtIter(QPtrListIterator<type, allocator> &it, const type *d);
00093 void inSort(const type *d)
00094 {
00095 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it)
00096 {
00097 if(compareItems(*it, d)>=0)
00098 {
00099 FXEXCEPTION_STL1 { Base::insert(it, d); } FXEXCEPTION_STL2;
00100 }
00101 }
00102 }
00104 void prepend(const type *d) { FXEXCEPTION_STL1 { Base::push_front(const_cast<type *>(d)); } FXEXCEPTION_STL2; }
00106 void append(const type *d) { FXEXCEPTION_STL1 { Base::push_back(const_cast<type *>(d)); } FXEXCEPTION_STL2; }
00108 bool remove(uint i)
00109 {
00110 if(isEmpty()) return false;
00111 typename Base::iterator it=int_idx(i);
00112 deleteItem(*it);
00113 Base::erase(it);
00114 return true;
00115 }
00117 bool remove(const type *d)
00118 {
00119 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it)
00120 {
00121 if(0==compareItems(*it, const_cast<type *>(d)))
00122 {
00123 deleteItem(*it);
00124 Base::erase(it);
00125 return true;
00126 }
00127 }
00128 return false;
00129 }
00131 bool removeRef(const type *d)
00132 {
00133 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it)
00134 {
00135 if(*it==d)
00136 {
00137 deleteItem(*it);
00138 Base::erase(it);
00139 return true;
00140 }
00141 }
00142 return false;
00143 }
00145 bool removeByIter(QPtrListIterator<type, allocator> &it);
00147 bool removeFirst()
00148 {
00149 if(isEmpty()) return false;
00150 typename Base::iterator it=Base::begin();
00151 deleteItem(*it);
00152 Base::pop_front();
00153 return true;
00154 }
00156 bool removeLast()
00157 {
00158 if(isEmpty()) return false;
00159 typename Base::iterator it=--Base::end();
00160 deleteItem(*it);
00161 Base::pop_back();
00162 return true;
00163 }
00165 type *take(uint i)
00166 {
00167 if(isEmpty()) return 0;
00168 typename Base::iterator it=int_idx(i);
00169 type *ret=*it;
00170 Base::erase(it);
00171 return ret;
00172 }
00174 bool take(const type *d)
00175 {
00176 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it)
00177 {
00178 if(0==compareItems(*it, const_cast<type *>(d)))
00179 {
00180 Base::erase(it);
00181 return true;
00182 }
00183 }
00184 return false;
00185 }
00187 bool takeByIter(QPtrListIterator<type, allocator> &it);
00189 bool takeRef(const type *d)
00190 {
00191 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it)
00192 {
00193 if(*it==d)
00194 {
00195 Base::erase(it);
00196 return true;
00197 }
00198 }
00199 return false;
00200 }
00202 bool takeFirst()
00203 {
00204 if(isEmpty()) return false;
00205 typename Base::iterator it=Base::begin();
00206 Base::pop_front();
00207 return true;
00208 }
00210 bool takeLast()
00211 {
00212 if(isEmpty()) return false;
00213 typename Base::iterator it=--Base::end();
00214 Base::pop_back();
00215 return true;
00216 }
00218 void clear()
00219 {
00220 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it)
00221 {
00222 deleteItem(*it);
00223 }
00224 Base::clear();
00225 }
00226 private:
00227 template<class type2> struct swapPolicy
00228 {
00229 template<class L, class I> void swap(L &list, I &a, I &b) const
00230 {
00231 type2 temp=*a;
00232 *a=*b;
00233 *b=temp;
00234 }
00235 };
00236 template<class type2> struct comparePolicyFunc
00237 {
00238 bool (*comparer)(type2 a, type2 b);
00239 template<class L, class I> bool compare(L &list, I &a, I &b) const
00240 {
00241 return comparer(*a, *b);
00242 }
00243 };
00244 template<class type2> struct comparePolicyMe
00245 {
00246 template<class L, class I> bool compare(L &list, I &a, I &b) const
00247 {
00248 return ((QPtrList<type2> &) *this).compareItems(*a, *b)==-1;
00249 }
00250 };
00251 public:
00253 template<typename SortFuncSpec> void sort(SortFuncSpec sortfunc)
00254 {
00255 QValueListQSort<type *, Pol::itMove, swapPolicy, comparePolicyFunc> sorter((QValueList<type *> &) *this);
00256
00257 sorter.run();
00258 }
00260 void sort()
00261 {
00262 QValueListQSort<type *, Pol::itMove, swapPolicy, comparePolicyMe> sorter((QValueList<type *> &) *this);
00263 sorter.run();
00264 }
00266 int find(const type *d)
00267 {
00268 int idx=0;
00269 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it, ++idx)
00270 {
00271 if(0==compareItems(*it, d)) return idx;
00272 }
00273 return -1;
00274 }
00276 int findRef(const type *d)
00277 {
00278 int idx=0;
00279 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it, ++idx)
00280 {
00281 if(*it==d) return idx;
00282 }
00283 return -1;
00284 }
00286 uint contains(const type *d) const
00287 {
00288 uint count=0;
00289 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it)
00290 {
00291 if(0==compareItems(*it, d)) count++;
00292 }
00293 return count;
00294 }
00296 uint containsRef(const type *d) const
00297 {
00298 uint count=0;
00299 for(typename Base::iterator it=Base::begin(); it!=Base::end(); ++it)
00300 {
00301 if(*it==d) count++;
00302 }
00303 return count;
00304 }
00306 bool replace(uint i, const type *d)
00307 {
00308 if(isEmpty()) return false;
00309 typename Base::iterator it=int_idx(i);
00310 *it=d;
00311
00312
00313 return true;
00314 }
00316 bool replaceAtIter(QPtrListIterator<type, allocator> &it, const type *d);
00318 type *at(uint i) { return Base::empty() ? 0 : *int_idx(i); }
00320 type *getFirst() const { return Base::empty() ? 0 : Base::front(); }
00322 type *getLast() const { return Base::empty() ? 0 : Base::back(); }
00324 type *first() { return Base::empty() ? 0 : Base::front(); }
00326 type *last() { return Base::empty() ? 0 : Base::back(); }
00328 virtual int compareItems(type *a, type *b) const { return (a<b) ? -1 : (a==b) ? 0 : -1; }
00329
00330 Base &int_list() { return static_cast<Base &>(*this); }
00331 typename Base::iterator int_begin() { return Base::begin(); }
00332 typename Base::iterator int_end() { return Base::end(); }
00333
00334 protected:
00335 virtual void deleteItem(type *d);
00336 };
00337
00338
00339 template<> inline void QPtrList<void>::deleteItem(void *)
00340 {
00341 }
00342
00343 template<class type, class allocator> inline void QPtrList<type, allocator>::deleteItem(type *d)
00344 {
00345 if(autodel) delete d;
00346 }
00347
00352 template<class type, class allocator> class QPtrListIterator : private std::list<type *, allocator>::iterator
00353 {
00354 typedef std::list<type *, allocator> Base;
00355 mutable bool dead;
00356 QPtrList<type, allocator> *mylist;
00357 protected:
00358 type *retptr() const
00359 {
00360 if(dead) return 0;
00361 typename Base::iterator &me=const_cast<QPtrListIterator<type, allocator> &>(*this);
00362 if(mylist->int_end()==me) { dead=true; return 0; }
00363 return *me;
00364 }
00365 public:
00366 typename Base::iterator &int_getIterator() { return static_cast<typename Base::iterator &>(*this); }
00367 QPtrListIterator() : dead(true), mylist(0) { }
00369 QPtrListIterator(const QPtrList<type, allocator> &l) : dead(false), mylist(&const_cast<QPtrList<type, allocator> &>(l)), Base::iterator(const_cast<QPtrList<type, allocator> &>(l).int_begin()) { retptr(); }
00370 QPtrListIterator(const QPtrListIterator<type, allocator> &l) : dead(l.dead), mylist(l.mylist), Base::iterator(l) { }
00371 QPtrListIterator<type, allocator> &operator=(const QPtrListIterator<type, allocator> &it)
00372 {
00373 dead=it.dead; mylist=it.mylist;
00374 typename Base::iterator &me=*this;
00375 me=it;
00376 return *this;
00377 }
00378 bool operator==(const QPtrListIterator &o) const { return static_cast<typename Base::iterator const &>(*this)==o; }
00379 bool operator!=(const QPtrListIterator &o) const { return static_cast<typename Base::iterator const &>(*this)!=o; }
00380 bool operator<(const QPtrListIterator &o) const { return static_cast<typename Base::iterator const &>(*this)<o; }
00381 bool operator>(const QPtrListIterator &o) const { return static_cast<typename Base::iterator const &>(*this)>o; }
00383 uint count() const { return mylist->count(); }
00385 bool isEmpty() const { return mylist->isEmpty(); }
00387 bool atFirst() const
00388 {
00389 typename Base::iterator &me=const_cast<QPtrListIterator<type, allocator> &>(*this);
00390 return mylist->int_begin()==me;
00391 }
00393 bool atLast() const
00394 {
00395 typename Base::iterator next=*this;
00396 ++next;
00397 return mylist->int_end()==next;
00398 }
00400 type *toFirst()
00401 {
00402 typename Base::iterator &me=const_cast<QPtrListIterator<type, allocator> &>(*this);
00403 me=mylist->int_begin(); dead=false;
00404 return retptr();
00405 }
00407 type *toLast()
00408 {
00409 typename Base::iterator &me=const_cast<QPtrListIterator<type, allocator> &>(*this);
00410 me=mylist->int_end(); dead=false;
00411 if(!mylist->isEmpty()) --me;
00412 return retptr();
00413 }
00415 QPtrListIterator<type, allocator> &makeDead()
00416 {
00417 typename Base::iterator &me=const_cast<QPtrListIterator<type, allocator> &>(*this);
00418 me=mylist->int_end();
00419 dead=true;
00420 return *this;
00421 }
00423 type *operator*() const { return retptr(); }
00425 type *current() const { return retptr(); }
00427 type *operator++()
00428 {
00429 if(!dead)
00430 {
00431 typename Base::iterator &me=int_getIterator(); ++me;
00432 }
00433 return retptr();
00434 }
00436 type *operator+=(uint j)
00437 {
00438 if(!dead)
00439 {
00440 typename Base::iterator &me=*this;
00441 typename Base::iterator myend=mylist->int_end();
00442 for(uint n=0; n<j && me!=myend; n++)
00443 ++me;
00444 }
00445 return retptr();
00446 }
00448 type *operator--()
00449 {
00450 if(!dead)
00451 {
00452 typename Base::iterator &me=*this;
00453 if(mylist->int_begin()==me)
00454 {
00455 me=mylist->int_end();
00456 dead=true;
00457 }
00458 else --me;
00459 }
00460 return retptr();
00461 }
00463 type *operator-=(uint j)
00464 {
00465 if(!dead)
00466 {
00467 typename Base::iterator &me=*this;
00468 typename Base::iterator myend=mylist->int_begin();
00469 for(uint n=0; n<j && !dead; n++)
00470 {
00471 if(myend==me)
00472 {
00473 me=mylist->int_end();
00474 dead=true;
00475 }
00476 else --me;
00477 }
00478 }
00479 return retptr();
00480 }
00481 };
00482
00483 template<class type, class allocator> inline bool QPtrList<type, allocator>::insertAtIter(QPtrListIterator<type, allocator> &it, const type *d)
00484 {
00485 FXEXCEPTION_STL1 { Base::insert(it.int_getIterator(), const_cast<type *>(d));} FXEXCEPTION_STL2;
00486 return true;
00487 }
00488
00489 template<class type, class allocator> inline bool QPtrList<type, allocator>::removeByIter(QPtrListIterator<type, allocator> &it)
00490 {
00491 deleteItem(*it.int_getIterator());
00492 Base::erase(it.int_getIterator());
00493 return true;
00494 }
00495
00496 template<class type, class allocator> inline bool QPtrList<type, allocator>::takeByIter(QPtrListIterator<type, allocator> &it)
00497 {
00498 Base::erase(it.int_getIterator());
00499 return true;
00500 }
00501
00502 template<class type, class allocator> inline bool QPtrList<type, allocator>::replaceAtIter(QPtrListIterator<type, allocator> &it, const type *d)
00503 {
00504 *it.int_getIterator()=const_cast<type *>(d);
00505 return true;
00506 }
00507
00509 #define QList QPtrList
00511 #define QListIterator QPtrListIterator
00512
00514 template<class type, class allocator> FXStream &operator<<(FXStream &s, const QPtrList<type, allocator> &i)
00515 {
00516 FXuint mysize=i.count();
00517 s << mysize;
00518 for(QPtrListIterator<type, allocator> it(i); it.current(); ++it)
00519 {
00520 s << *it.current();
00521 }
00522 return s;
00523 }
00525 template<class type, class allocator> FXStream &operator>>(FXStream &s, QPtrList<type, allocator> &i)
00526 {
00527 FXuint mysize;
00528 s >> mysize;
00529 i.clear();
00530 for(uint n=0; n<mysize; n++)
00531 {
00532 type *item;
00533 FXERRHM(item=new type);
00534 s >> *item;
00535 i.append(item);
00536 }
00537 return s;
00538 }
00539
00546 template<class type, class allocator=FX::aligned_allocator<type *, 0> > class QQuickListIterator;
00547 template<class type, class allocator=FX::aligned_allocator<type *, 0> > class QQuickList;
00548 template<class type, class allocator> class QQuickList : protected QPtrList<type, allocator>
00549 {
00550 typedef QPtrList<type, allocator> Base;
00551 friend class QQuickListIterator<type, allocator>;
00552 public:
00554 QQuickList() : QPtrList<type, allocator>(true) { }
00556 #ifndef HAVE_CPP0XRVALUEREFS
00557 #ifdef HAVE_CONSTTEMPORARIES
00558 QQuickList(const QQuickList &_o) : QPtrList<type, allocator>(true)
00559 {
00560 QQuickList &o=const_cast<QQuickList &>(_o);
00561 #else
00562 QQuickList(QQuickList &o) : QPtrList<type, allocator>(true)
00563 {
00564 #endif
00565 #else
00566 private:
00567 QQuickList(const QQuickList &);
00568 public:
00569 QQuickList(QQuickList &&o) : QPtrList<type, allocator>(true)
00570 {
00571 #endif
00572 Base::splice(Base::begin(), o, o.begin(), o.end());
00573 }
00574 #ifndef HAVE_CPP0XRVALUEREFS
00575 QQuickList &operator=(QQuickList &o)
00576 #else
00577 private:
00578 QQuickList &operator=(QQuickList &o);
00579 public:
00580 QQuickList &&operator=(QQuickList &&o)
00581 #endif
00582 {
00583 clear();
00584 Base::splice(Base::begin(), o, o.begin(), o.end());
00585 return *this;
00586 }
00588 #ifndef HAVE_CPP0XRVALUEREFS
00589 #ifdef HAVE_CONSTTEMPORARIES
00590 explicit QQuickList(const QPtrList<type, allocator> &_o) : QPtrList<type, allocator>(true)
00591 {
00592 QPtrList<type, allocator> &o=const_cast<QPtrList<type, allocator> &>(_o);
00593 #else
00594 explicit QQuickList(QPtrList<type, allocator> &o) : QPtrList<type, allocator>(true)
00595 {
00596 #endif
00597 #else
00598 explicit QQuickList(QPtrList<type, allocator> &&o) : QPtrList<type, allocator>(true)
00599 {
00600 #endif
00601 Base::splice(Base::begin(), o, o.begin(), o.end());
00602 }
00604 const QPtrList<type, allocator> &asPtrList() const throw()
00605 {
00606 return static_cast<QPtrList<type, allocator> &>(*this);
00607 }
00608 using QPtrList<type, allocator>::count;
00609 using QPtrList<type, allocator>::isEmpty;
00610 using QPtrList<type, allocator>::insert;
00611 using QPtrList<type, allocator>::insertAtIter;
00612 using QPtrList<type, allocator>::inSort;
00613 using QPtrList<type, allocator>::prepend;
00614 using QPtrList<type, allocator>::append;
00615 using QPtrList<type, allocator>::remove;
00616 using QPtrList<type, allocator>::removeRef;
00617 using QPtrList<type, allocator>::removeByIter;
00618 using QPtrList<type, allocator>::removeFirst;
00619 using QPtrList<type, allocator>::removeLast;
00620 using QPtrList<type, allocator>::take;
00621 using QPtrList<type, allocator>::takeRef;
00622 using QPtrList<type, allocator>::clear;
00623 using QPtrList<type, allocator>::sort;
00624 using QPtrList<type, allocator>::find;
00625 using QPtrList<type, allocator>::findRef;
00626 using QPtrList<type, allocator>::contains;
00627 using QPtrList<type, allocator>::containsRef;
00628 using QPtrList<type, allocator>::replace;
00629 using QPtrList<type, allocator>::at;
00630 using QPtrList<type, allocator>::getFirst;
00631 using QPtrList<type, allocator>::getLast;
00632 using QPtrList<type, allocator>::first;
00633 using QPtrList<type, allocator>::last;
00634 using QPtrList<type, allocator>::compareItems;
00635 using QPtrList<type, allocator>::int_list;
00636 using QPtrList<type, allocator>::int_begin;
00637 using QPtrList<type, allocator>::int_end;
00638
00639 friend FXStream &operator<<(FXStream &s, const QQuickList<type> &_i)
00640 {
00641 const QPtrList<type, allocator> &i=_i;
00642 s << i;
00643 return s;
00644 }
00645 friend FXStream &operator>>(FXStream &s, QQuickList<type> &_i)
00646 {
00647 QPtrList<type, allocator> &i=_i;
00648 s >> i;
00649 return s;
00650 }
00651 };
00652
00656 template<class type, class allocator> class QQuickListIterator : public QPtrListIterator<type, allocator>
00657 {
00658 public:
00659 QQuickListIterator(const QQuickList<type, allocator> &l) : QPtrListIterator<type, allocator>(l) { }
00660 };
00661
00662 }
00663
00664 #endif
00665