00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef QVALUELIST_H
00023 #define QVALUELIST_H
00024
00025 #if _MSC_VER==1200
00026 #pragma warning(disable: 4786)
00027 #endif
00028
00029 #include <list>
00030 #undef Unsorted
00031 #include "fxdefs.h"
00032 #include "FXException.h"
00033 #include "FXPolicies.h"
00034 #include "FXStream.h"
00035
00036 namespace FX {
00037
00038 typedef FXuint uint;
00039
00057 template<class type> class QValueList : public std::list<type>
00058 {
00059 public:
00060 QValueList() : std::list<type>() { }
00061 QValueList(const std::list<type> &l) : std::list<type>(l) { }
00062 FXADDMOVEBASECLASS(QValueList, std::list<type>)
00063 void remove(const type &d) { std::list<type>::remove(d); }
00064 uint removeAllOf(const type &d)
00065 {
00066 uint count=0;
00067 for(typename std::list<type>::iterator it=std::list<type>::begin(); it!=std::list<type>::end(); ++it)
00068 {
00069 if(*it==d) count++;
00070 }
00071 for(uint n=0; n<count; n++)
00072 std::list<type>::remove(d);
00073 return count;
00074 }
00075 bool isEmpty() const { return std::list<type>::empty(); }
00076 typename std::list<type>::iterator append(const type &d) { FXEXCEPTION_STL1 { std::list<type>::push_back(d); } FXEXCEPTION_STL2; return --std::list<type>::end(); }
00077 typename std::list<type>::iterator append(const QValueList &l)
00078 {
00079 FXEXCEPTION_STL1 {
00080 for(typename std::list<type>::const_iterator it=l.begin(); it!=l.end(); ++it)
00081 {
00082 std::list<type>::push_back(*it);
00083 }
00084 } FXEXCEPTION_STL2;
00085 return --std::list<type>::end();
00086 }
00087 typename std::list<type>::iterator prepend(const type &d) { FXEXCEPTION_STL1 { std::list<type>::push_front(d); } FXEXCEPTION_STL2; return std::list<type>::begin(); }
00088 typename std::list<type>::iterator remove(typename std::list<type>::iterator it) { typename std::list<type>::iterator itafter=it; ++itafter; std::list<type>::erase(it); return itafter; }
00089 typename std::list<type>::iterator at(typename std::list<type>::size_type i) { typename std::list<type>::iterator it; for(it=std::list<type>::begin(); i; --i, ++it); return it; }
00090 typename std::list<type>::const_iterator at(typename std::list<type>::size_type i) const { typename std::list<type>::const_iterator it; for(it=std::list<type>::begin(); i; --i, ++it); return it; }
00091 type &operator[](typename std::list<type>::size_type i) { return *at(i); }
00092 const type &operator[](typename std::list<type>::size_type i) const { return *at(i); }
00093 typename std::list<type>::iterator find(const type &d)
00094 {
00095 typename std::list<type>::iterator it;
00096 for(it=std::list<type>::begin(); it!=std::list<type>::end(); ++it)
00097 if(*it==d) return it;
00098 return it;
00099 }
00100 typename std::list<type>::const_iterator find(const type &d) const
00101 {
00102 typename std::list<type>::const_iterator it;
00103 for(it=std::list<type>::begin(); it!=std::list<type>::end(); ++it)
00104 if(*it==d) return it;
00105 return it;
00106 }
00107 typename std::list<type>::iterator find(typename std::list<type>::iterator it, const type &d)
00108 {
00109 for(; it!=std::list<type>::end(); ++it)
00110 if(*it==d) return it;
00111 return it;
00112 }
00113 typename std::list<type>::const_iterator find(typename std::list<type>::const_iterator it, const type &d) const
00114 {
00115 for(; it!=std::list<type>::end(); ++it)
00116 if(*it==d) return it;
00117 return it;
00118 }
00119 int findIndex(const type &d) const
00120 {
00121 int idx=0;
00122 for(typename std::list<type>::const_iterator it=std::list<type>::begin(); it!=std::list<type>::end(); ++it, ++idx)
00123 if(*it==d) return idx;
00124 return -1;
00125 }
00126 typename std::list<type>::size_type contains(const type &d) const
00127 {
00128 typename std::list<type>::size_type count=0;
00129 for(typename std::list<type>::const_iterator it=std::list<type>::begin(); it!=std::list<type>::end(); ++it)
00130 if(*it==d) count++;
00131 return count;
00132 }
00133 typename std::list<type>::size_type count() const { return std::list<type>::size(); }
00134 QValueList<type> &operator+=(const type &d) { std::list<type>::push_back(d); return *this; }
00135
00136 };
00137
00138
00139
00140
00141
00148 template<class type> class QValueListIterator : public std::list<type>::iterator
00149 {
00150 public:
00151 QValueListIterator() : std::list<type>::iterator() { }
00152 QValueListIterator(const QValueListIterator &o) : std::list<type>::iterator(o) { }
00153 };
00160 template<class type> class QValueListConstIterator : public std::list<type>::const_iterator
00161 {
00162 public:
00163 QValueListConstIterator() : std::list<type>::const_iterator() { }
00164 QValueListConstIterator(const QValueListConstIterator &o) : std::list<type>::const_iterator(o) { }
00165 };
00166
00168 template<class type> FXStream &operator<<(FXStream &s, const QValueList<type> &i)
00169 {
00170 FXuint mysize=(FXuint) i.count();
00171 s << mysize;
00172 for(typename QValueList<type>::const_iterator it=i.begin(); it!=i.end(); ++it)
00173 {
00174 s << *it;
00175 }
00176 return s;
00177 }
00179 template<class type> FXStream &operator>>(FXStream &s, QValueList<type> &i)
00180 {
00181 FXuint mysize;
00182 s >> mysize;
00183 i.clear();
00184 for(FXuint n=0; n<mysize; n++)
00185 {
00186 type item;
00187 s >> item;
00188 i.append(item);
00189 }
00190 return s;
00191 }
00192
00194 enum QVLQSortType
00195 {
00196 QVLQSortDefault=0,
00197 QVLQSortInsertion=1,
00198 QVLQSortMerge=2,
00199 QVLQSortQuick=4,
00200
00201 QVLQSortStable=256
00202 };
00280 template<class type,
00281 template<class> class movePolicy=Pol::itMove,
00282 template<class> class swapPolicy=Pol::itSwap,
00283 template<class> class comparePolicy=Pol::itCompare>
00284 class QValueListQSort : public movePolicy<type>, public swapPolicy<type>, public comparePolicy<type>
00285 {
00286 static const int insertionCutOff=12, mergeCutOff=12;
00287 public:
00288 typedef QValueList<type> list;
00289 typedef typename list::iterator iterator;
00290 protected:
00291 typedef std::pair<int, iterator> intit;
00292 mutable list &mylist;
00293 int sorttype;
00294 public:
00296 QValueListQSort(QValueList<type> &list, int _sorttype=QVLQSortDefault)
00297 : mylist(list), sorttype(_sorttype) { }
00299 void run(int _sorttype=QVLQSortDefault)
00300 {
00301 if(mylist.empty()) return;
00302 if(QVLQSortDefault!=sorttype) sorttype=_sorttype;
00303 if(!sorttype) sorttype=QVLQSortInsertion|QVLQSortMerge|QVLQSortQuick;
00304 int s=(int) mylist.size();
00305 if(s>mergeCutOff && (sorttype & QVLQSortQuick) && !(sorttype & QVLQSortStable))
00306 {
00307 intit l=std::make_pair(0, mylist.begin());
00308 intit u=std::make_pair(s, mylist.end());
00309 qsort(l, u);
00310 }
00311
00312
00313
00314
00315 else
00316 {
00317 iterator l=mylist.begin(), u=mylist.end();
00318 isort(l, u);
00319 }
00320 }
00321 private:
00322 void isort(iterator &lb, iterator &ub)
00323 {
00324 for(iterator it=lb;;)
00325 {
00326 iterator prev=it;
00327 if(++it==ub) break;
00328 if(comparePolicy<type>::compare(mylist, it, prev))
00329 {
00330 bool found=false;
00331 iterator find=lb;
00332 for(; find!=ub; ++find)
00333 {
00334 if(find!=it && comparePolicy<type>::compare(mylist, it, find))
00335 {
00336 bool atStart=(find==lb);
00337 move(mylist, find, it);
00338 if(atStart) lb=it;
00339 found=true;
00340 break;
00341 }
00342 }
00343 if(!found) movePolicy<type>::move(mylist, find, it);
00344 }
00345 }
00346 }
00347 inline void merge(int len, intit &_lb, intit &_m, intit &_ub)
00348 {
00349 bool updlb=true, updm=true, updub=true;
00350 iterator lb=_lb.second, m=_m.second, ub=_ub.second;
00351 while(true)
00352 {
00353
00354 }
00355 }
00356 void msort(intit &_lb, intit &_ub)
00357 {
00358 int len=(_ub.first-_lb.first);
00359 if(len<=2) return;
00360 int mididx=len>>1;
00361 iterator it=_lb.second;
00362 int idx;
00363 for(idx=_lb.first; idx<mididx; ++it, ++idx);
00364 intit m=std::make_pair(idx, it);
00365 msort(_lb, m);
00366 msort(m, _ub);
00367 merge(len, _lb, m, _ub);
00368 }
00369 inline intit partition(intit &_lb, intit &_ub)
00370 {
00371 bool updlb=true;
00372 int lbidx=_lb.first, ubidx=_ub.first;
00373 iterator lb(_lb.second), ub(_ub.second);
00374 while(true)
00375 {
00376 while(lbidx<ubidx && comparePolicy<type>::compare(mylist, _lb.second, (--ubidx, --ub)));
00377 while(lbidx<ubidx && comparePolicy<type>::compare(mylist, (updlb=false, ++lbidx, ++lb), _lb.second));
00378 if(lbidx>=ubidx) break;
00379 swapPolicy<type>::swap(mylist, lb, ub);
00380 if(updlb) _lb.second=lb;
00381 }
00382 if(_lb.second!=ub)
00383 {
00384 swapPolicy<type>::swap(mylist, _lb.second, ub);
00385 }
00386 return std::make_pair(ubidx, ub);
00387 }
00388 void qsort(intit &_lb, intit &_ub)
00389 {
00390 bool updlb=true, updub=true;
00391 intit lb(_lb), ub(_ub);
00392 while(lb.first<ub.first)
00393 {
00394 if(ub.first-lb.first<=insertionCutOff)
00395 {
00396 isort(lb.second, ub.second);
00397 if(updlb) _lb.second=lb.second;
00398 if(updub) _ub.second=ub.second;
00399 return;
00400 }
00401 intit i=partition(lb, ub);
00402 if(updlb) _lb.second=lb.second;
00403 if(updub) _ub.second=ub.second;
00404 int r1=i.first-lb.first, r2=ub.first-i.first-1;
00405 if(r1<=r2)
00406 {
00407 if(r1>0)
00408 {
00409 qsort(lb, i);
00410 if(updlb) _lb.second=lb.second;
00411 }
00412 lb.first=i.first+1; lb.second=++i.second; updlb=false;
00413 }
00414 else
00415 {
00416 ++i.first; ++i.second;
00417 if(r2>0)
00418 {
00419 qsort(i, ub);
00420 if(updub) _ub.second=ub.second;
00421 }
00422 ub.first=i.first-1; ub.second=--i.second; updub=false;
00423 }
00424 }
00425 }
00426 };
00427
00428 }
00429
00430 #endif