qptrlist.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *                 Q t   P o i n t e r   L i s t   T h u n k                     *
00004 *                                                                               *
00005 *********************************************************************************
00006 * Copyright (C) 2003 by Niall Douglas.   All Rights Reserved.                   *
00007 *       NOTE THAT I DO NOT PERMIT ANY OF MY CODE TO BE PROMOTED TO THE GPL      *
00008 *********************************************************************************
00009 * This code is free software; you can redistribute it and/or modify it under    *
00010 * the terms of the GNU Library General Public License v2.1 as published by the  *
00011 * Free Software Foundation EXCEPT that clause 3 does not apply ie; you may not  *
00012 * "upgrade" this code to the GPL without my prior written permission.           *
00013 * Please consult the file "License_Addendum2.txt" accompanying this file.       *
00014 *                                                                               *
00015 * This code is distributed in the hope that it will be useful,                  *
00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                          *
00018 *********************************************************************************
00019 * $Id:                                                                          *
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:     // For other stuff to access
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; // Fails for non-pointer types
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         {   // Simply swap the pointers
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     {   // Would use Base::sort but this is faster
00255         QValueListQSort<type *, Pol::itMove, swapPolicy, comparePolicyFunc> sorter((QValueList<type *> &) *this);
00256         //sorter.comparer=sortfunc;
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         //list<type *>::erase(list<type *>::begin()+i);
00312         //list<type *>::insert(list<type *>::begin()+i, d);
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 // Don't delete void *
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 &);     // disable copy constructor
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 } // namespace
00663 
00664 #endif
00665 

(C) 2002-2009 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Nov 20 18:31:26 2009 for TnFOX by doxygen v1.4.7