00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef QALGORITHMS_H
00043 #define QALGORITHMS_H
00044
00045 #include <QtCore/qglobal.h>
00046
00047 QT_BEGIN_HEADER
00048
00049 QT_BEGIN_NAMESPACE
00050
00051 QT_MODULE(Core)
00052
00053
00054
00055
00056
00057 namespace QAlgorithmsPrivate {
00058
00059 template <typename RandomAccessIterator, typename T, typename LessThan>
00060 Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
00061 template <typename RandomAccessIterator, typename T>
00062 inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
00063
00064 template <typename RandomAccessIterator, typename T, typename LessThan>
00065 Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
00066 template <typename RandomAccessIterator, typename T>
00067 inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
00068
00069 template <typename RandomAccessIterator, typename T, typename LessThan>
00070 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
00071 template <typename RandomAccessIterator, typename T, typename LessThan>
00072 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
00073 template <typename RandomAccessIterator, typename T, typename LessThan>
00074 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
00075
00076 }
00077
00078 template <typename InputIterator, typename OutputIterator>
00079 inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
00080 {
00081 while (begin != end)
00082 *dest++ = *begin++;
00083 return dest;
00084 }
00085
00086 template <typename BiIterator1, typename BiIterator2>
00087 inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
00088 {
00089 while (begin != end)
00090 *--dest = *--end;
00091 return dest;
00092 }
00093
00094 template <typename InputIterator1, typename InputIterator2>
00095 inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
00096 {
00097 for (; first1 != last1; ++first1, ++first2)
00098 if (!(*first1 == *first2))
00099 return false;
00100 return true;
00101 }
00102
00103 template <typename ForwardIterator, typename T>
00104 inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
00105 {
00106 for (; first != last; ++first)
00107 *first = val;
00108 }
00109
00110 template <typename Container, typename T>
00111 inline void qFill(Container &container, const T &val)
00112 {
00113 qFill(container.begin(), container.end(), val);
00114 }
00115
00116 template <typename InputIterator, typename T>
00117 inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
00118 {
00119 while (first != last && !(*first == val))
00120 ++first;
00121 return first;
00122 }
00123
00124 template <typename Container, typename T>
00125 inline typename Container::const_iterator qFind(const Container &container, const T &val)
00126 {
00127 return qFind(container.constBegin(), container.constEnd(), val);
00128 }
00129
00130 template <typename InputIterator, typename T, typename Size>
00131 inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
00132 {
00133 for (; first != last; ++first)
00134 if (*first == value)
00135 ++n;
00136 }
00137
00138 template <typename Container, typename T, typename Size>
00139 inline void qCount(const Container &container, const T &value, Size &n)
00140 {
00141 qCount(container.constBegin(), container.constEnd(), value, n);
00142 }
00143
00144 #ifdef qdoc
00145 template <typename T>
00146 LessThan qLess()
00147 {
00148 }
00149
00150 template <typename T>
00151 LessThan qGreater()
00152 {
00153 }
00154 #else
00155 template <typename T>
00156 class qLess
00157 {
00158 public:
00159 inline bool operator()(const T &t1, const T &t2) const
00160 {
00161 return (t1 < t2);
00162 }
00163 };
00164
00165 template <typename T>
00166 class qGreater
00167 {
00168 public:
00169 inline bool operator()(const T &t1, const T &t2) const
00170 {
00171 return (t2 < t1);
00172 }
00173 };
00174 #endif
00175
00176 template <typename RandomAccessIterator>
00177 inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
00178 {
00179 if (start != end)
00180 QAlgorithmsPrivate::qSortHelper(start, end, *start);
00181 }
00182
00183 template <typename RandomAccessIterator, typename LessThan>
00184 inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
00185 {
00186 if (start != end)
00187 QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
00188 }
00189
00190 template<typename Container>
00191 inline void qSort(Container &c)
00192 {
00193 #ifdef Q_CC_BOR
00194
00195 c.detach();
00196 #endif
00197 if (!c.empty())
00198 QAlgorithmsPrivate::qSortHelper(c.begin(), c.end(), *c.begin());
00199 }
00200
00201 template <typename RandomAccessIterator>
00202 inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
00203 {
00204 if (start != end)
00205 QAlgorithmsPrivate::qStableSortHelper(start, end, *start);
00206 }
00207
00208 template <typename RandomAccessIterator, typename LessThan>
00209 inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
00210 {
00211 if (start != end)
00212 QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan);
00213 }
00214
00215 template<typename Container>
00216 inline void qStableSort(Container &c)
00217 {
00218 #ifdef Q_CC_BOR
00219
00220 c.detach();
00221 #endif
00222 if (!c.empty())
00223 QAlgorithmsPrivate::qStableSortHelper(c.begin(), c.end(), *c.begin());
00224 }
00225
00226 template <typename RandomAccessIterator, typename T>
00227 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
00228 {
00229
00230
00231
00232 RandomAccessIterator middle;
00233 int n = end - begin;
00234 int half;
00235
00236 while (n > 0) {
00237 half = n >> 1;
00238 middle = begin + half;
00239 if (*middle < value) {
00240 begin = middle + 1;
00241 n -= half + 1;
00242 } else {
00243 n = half;
00244 }
00245 }
00246 return begin;
00247 }
00248
00249 template <typename RandomAccessIterator, typename T, typename LessThan>
00250 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
00251 {
00252 return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan);
00253 }
00254
00255 template <typename Container, typename T>
00256 Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
00257 {
00258 return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
00259 }
00260
00261 template <typename RandomAccessIterator, typename T>
00262 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
00263 {
00264
00265 RandomAccessIterator middle;
00266 int n = end - begin;
00267 int half;
00268
00269 while (n > 0) {
00270 half = n >> 1;
00271 middle = begin + half;
00272 if (value < *middle) {
00273 n = half;
00274 } else {
00275 begin = middle + 1;
00276 n -= half + 1;
00277 }
00278 }
00279 return begin;
00280 }
00281
00282 template <typename RandomAccessIterator, typename T, typename LessThan>
00283 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
00284 {
00285 return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan);
00286 }
00287
00288 template <typename Container, typename T>
00289 Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
00290 {
00291 return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
00292 }
00293
00294 template <typename RandomAccessIterator, typename T>
00295 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
00296 {
00297
00298 RandomAccessIterator it = qLowerBound(begin, end, value);
00299
00300 if (it == end || value < *it)
00301 return end;
00302
00303 return it;
00304 }
00305
00306 template <typename RandomAccessIterator, typename T, typename LessThan>
00307 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
00308 {
00309 return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan);
00310 }
00311
00312 template <typename Container, typename T>
00313 Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
00314 {
00315 return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
00316 }
00317
00318 template <typename ForwardIterator>
00319 Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
00320 {
00321 while (begin != end) {
00322 delete *begin;
00323 ++begin;
00324 }
00325 }
00326
00327 template <typename Container>
00328 inline void qDeleteAll(const Container &c)
00329 {
00330 qDeleteAll(c.begin(), c.end());
00331 }
00332
00333
00334
00335
00336
00337 namespace QAlgorithmsPrivate {
00338
00339 template <typename RandomAccessIterator, typename T, typename LessThan>
00340 Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
00341 {
00342 top:
00343 int span = int(end - start);
00344 if (span < 2)
00345 return;
00346
00347 --end;
00348 RandomAccessIterator low = start, high = end - 1;
00349 RandomAccessIterator pivot = start + span / 2;
00350
00351 if (lessThan(*end, *start))
00352 qSwap(*end, *start);
00353 if (span == 2)
00354 return;
00355
00356 if (lessThan(*pivot, *start))
00357 qSwap(*pivot, *start);
00358 if (lessThan(*end, *pivot))
00359 qSwap(*end, *pivot);
00360 if (span == 3)
00361 return;
00362
00363 qSwap(*pivot, *end);
00364
00365 while (low < high) {
00366 while (low < high && lessThan(*low, *end))
00367 ++low;
00368
00369 while (high > low && lessThan(*end, *high))
00370 --high;
00371
00372 if (low < high) {
00373 qSwap(*low, *high);
00374 ++low;
00375 --high;
00376 } else {
00377 break;
00378 }
00379 }
00380
00381 if (lessThan(*low, *end))
00382 ++low;
00383
00384 qSwap(*end, *low);
00385 qSortHelper(start, low, t, lessThan);
00386
00387 start = low + 1;
00388 ++end;
00389 goto top;
00390 }
00391
00392 template <typename RandomAccessIterator, typename T>
00393 inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
00394 {
00395 qSortHelper(begin, end, dummy, qLess<T>());
00396 }
00397
00398 template <typename RandomAccessIterator>
00399 Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
00400 {
00401 --end;
00402 while (begin < end)
00403 qSwap(*begin++, *end--);
00404 }
00405
00406 template <typename RandomAccessIterator>
00407 Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
00408 {
00409 qReverse(begin, middle);
00410 qReverse(middle, end);
00411 qReverse(begin, end);
00412 }
00413
00414 template <typename RandomAccessIterator, typename T, typename LessThan>
00415 Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
00416 {
00417 const int len1 = pivot - begin;
00418 const int len2 = end - pivot;
00419
00420 if (len1 == 0 || len2 == 0)
00421 return;
00422
00423 if (len1 + len2 == 2) {
00424 if (lessThan(*(begin + 1), *(begin)))
00425 qSwap(*begin, *(begin + 1));
00426 return;
00427 }
00428
00429 RandomAccessIterator firstCut;
00430 RandomAccessIterator secondCut;
00431 int len2Half;
00432 if (len1 > len2) {
00433 const int len1Half = len1 / 2;
00434 firstCut = begin + len1Half;
00435 secondCut = qLowerBound(pivot, end, *firstCut, lessThan);
00436 len2Half = secondCut - pivot;
00437 } else {
00438 len2Half = len2 / 2;
00439 secondCut = pivot + len2Half;
00440 firstCut = qUpperBound(begin, pivot, *secondCut, lessThan);
00441 }
00442
00443 qRotate(firstCut, pivot, secondCut);
00444 const RandomAccessIterator newPivot = firstCut + len2Half;
00445 qMerge(begin, firstCut, newPivot, t, lessThan);
00446 qMerge(newPivot, secondCut, end, t, lessThan);
00447 }
00448
00449 template <typename RandomAccessIterator, typename T, typename LessThan>
00450 Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
00451 {
00452 const int span = end - begin;
00453 if (span < 2)
00454 return;
00455
00456 const RandomAccessIterator middle = begin + span / 2;
00457 qStableSortHelper(begin, middle, t, lessThan);
00458 qStableSortHelper(middle, end, t, lessThan);
00459 qMerge(begin, middle, end, t, lessThan);
00460 }
00461
00462 template <typename RandomAccessIterator, typename T>
00463 inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
00464 {
00465 qStableSortHelper(begin, end, dummy, qLess<T>());
00466 }
00467
00468 template <typename RandomAccessIterator, typename T, typename LessThan>
00469 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
00470 {
00471 RandomAccessIterator middle;
00472 int n = int(end - begin);
00473 int half;
00474
00475 while (n > 0) {
00476 half = n >> 1;
00477 middle = begin + half;
00478 if (lessThan(*middle, value)) {
00479 begin = middle + 1;
00480 n -= half + 1;
00481 } else {
00482 n = half;
00483 }
00484 }
00485 return begin;
00486 }
00487
00488
00489 template <typename RandomAccessIterator, typename T, typename LessThan>
00490 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
00491 {
00492 RandomAccessIterator middle;
00493 int n = end - begin;
00494 int half;
00495
00496 while (n > 0) {
00497 half = n >> 1;
00498 middle = begin + half;
00499 if (lessThan(value, *middle)) {
00500 n = half;
00501 } else {
00502 begin = middle + 1;
00503 n -= half + 1;
00504 }
00505 }
00506 return begin;
00507 }
00508
00509 template <typename RandomAccessIterator, typename T, typename LessThan>
00510 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
00511 {
00512 RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan);
00513
00514 if (it == end || lessThan(value, *it))
00515 return end;
00516
00517 return it;
00518 }
00519
00520 }
00521
00522 QT_END_NAMESPACE
00523
00524 QT_END_HEADER
00525
00526 #endif // QALGORITHMS_H