qptrvector.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *                 Q t   P o i n t e r   V e c t o r   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 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; // Fails for non-pointer types
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         //list<type *>::erase(list<type *>::begin()+i);
00295         //list<type *>::insert(list<type *>::begin()+i, d);
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 // Don't delete void *
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 {   // std::vector::iterator is a ptr on some implementations, so play it safe
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 } // namespace
00499 
00500 #endif
00501 

(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