1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtCore module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
45 #include <QtCore/qglobal.h>
53 Warning: The contents of QAlgorithmsPrivate is not a part of the public Qt API
54 and may be changed from version to version or even be completely removed.
56 namespace QAlgorithmsPrivate {
58 template <typename RandomAccessIterator, typename T, typename LessThan>
59 Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
60 template <typename RandomAccessIterator, typename T>
61 inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
63 template <typename RandomAccessIterator, typename T, typename LessThan>
64 Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
65 template <typename RandomAccessIterator, typename T>
66 inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
68 template <typename RandomAccessIterator, typename T, typename LessThan>
69 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
70 template <typename RandomAccessIterator, typename T, typename LessThan>
71 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
72 template <typename RandomAccessIterator, typename T, typename LessThan>
73 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
77 template <typename InputIterator, typename OutputIterator>
78 inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
85 template <typename BiIterator1, typename BiIterator2>
86 inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
93 template <typename InputIterator1, typename InputIterator2>
94 inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
96 for (; first1 != last1; ++first1, ++first2)
97 if (!(*first1 == *first2))
102 template <typename ForwardIterator, typename T>
103 inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
105 for (; first != last; ++first)
109 template <typename Container, typename T>
110 inline void qFill(Container &container, const T &val)
112 qFill(container.begin(), container.end(), val);
115 template <typename InputIterator, typename T>
116 inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
118 while (first != last && !(*first == val))
123 template <typename Container, typename T>
124 inline typename Container::const_iterator qFind(const Container &container, const T &val)
126 return qFind(container.constBegin(), container.constEnd(), val);
129 template <typename InputIterator, typename T, typename Size>
130 inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
132 for (; first != last; ++first)
137 template <typename Container, typename T, typename Size>
138 inline void qCount(const Container &container, const T &value, Size &n)
140 qCount(container.constBegin(), container.constEnd(), value, n);
144 template <typename T>
149 template <typename T>
154 template <typename T>
158 inline bool operator()(const T &t1, const T &t2) const
164 template <typename T>
168 inline bool operator()(const T &t1, const T &t2) const
175 template <typename RandomAccessIterator>
176 inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
179 QAlgorithmsPrivate::qSortHelper(start, end, *start);
182 template <typename RandomAccessIterator, typename LessThan>
183 inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
186 QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
189 template<typename Container>
190 inline void qSort(Container &c)
193 // Work around Borland 5.5 optimizer bug
197 QAlgorithmsPrivate::qSortHelper(c.begin(), c.end(), *c.begin());
200 template <typename RandomAccessIterator>
201 inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
204 QAlgorithmsPrivate::qStableSortHelper(start, end, *start);
207 template <typename RandomAccessIterator, typename LessThan>
208 inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
211 QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan);
214 template<typename Container>
215 inline void qStableSort(Container &c)
218 // Work around Borland 5.5 optimizer bug
222 QAlgorithmsPrivate::qStableSortHelper(c.begin(), c.end(), *c.begin());
225 template <typename RandomAccessIterator, typename T>
226 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
228 // Implementation is duplicated from QAlgorithmsPrivate to keep existing code
229 // compiling. We have to allow using *begin and value with different types,
230 // and then implementing operator< for those types.
231 RandomAccessIterator middle;
237 middle = begin + half;
238 if (*middle < value) {
248 template <typename RandomAccessIterator, typename T, typename LessThan>
249 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
251 return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan);
254 template <typename Container, typename T>
255 Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
257 return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
260 template <typename RandomAccessIterator, typename T>
261 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
263 // Implementation is duplicated from QAlgorithmsPrivate.
264 RandomAccessIterator middle;
270 middle = begin + half;
271 if (value < *middle) {
281 template <typename RandomAccessIterator, typename T, typename LessThan>
282 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
284 return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan);
287 template <typename Container, typename T>
288 Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
290 return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
293 template <typename RandomAccessIterator, typename T>
294 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
296 // Implementation is duplicated from QAlgorithmsPrivate.
297 RandomAccessIterator it = qLowerBound(begin, end, value);
299 if (it == end || value < *it)
305 template <typename RandomAccessIterator, typename T, typename LessThan>
306 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
308 return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan);
311 template <typename Container, typename T>
312 Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
314 return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
317 template <typename ForwardIterator>
318 Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
320 while (begin != end) {
326 template <typename Container>
327 inline void qDeleteAll(const Container &c)
329 qDeleteAll(c.begin(), c.end());
333 Warning: The contents of QAlgorithmsPrivate is not a part of the public Qt API
334 and may be changed from version to version or even be completely removed.
336 namespace QAlgorithmsPrivate {
338 template <typename RandomAccessIterator, typename T, typename LessThan>
339 Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
342 int span = int(end - start);
347 RandomAccessIterator low = start, high = end - 1;
348 RandomAccessIterator pivot = start + span / 2;
350 if (lessThan(*end, *start))
355 if (lessThan(*pivot, *start))
356 qSwap(*pivot, *start);
357 if (lessThan(*end, *pivot))
365 while (low < high && lessThan(*low, *end))
368 while (high > low && lessThan(*end, *high))
380 if (lessThan(*low, *end))
384 qSortHelper(start, low, t, lessThan);
391 template <typename RandomAccessIterator, typename T>
392 inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
394 qSortHelper(begin, end, dummy, qLess<T>());
397 template <typename RandomAccessIterator>
398 Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
402 qSwap(*begin++, *end--);
405 template <typename RandomAccessIterator>
406 Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
408 qReverse(begin, middle);
409 qReverse(middle, end);
410 qReverse(begin, end);
413 template <typename RandomAccessIterator, typename T, typename LessThan>
414 Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
416 const int len1 = pivot - begin;
417 const int len2 = end - pivot;
419 if (len1 == 0 || len2 == 0)
422 if (len1 + len2 == 2) {
423 if (lessThan(*(begin + 1), *(begin)))
424 qSwap(*begin, *(begin + 1));
428 RandomAccessIterator firstCut;
429 RandomAccessIterator secondCut;
432 const int len1Half = len1 / 2;
433 firstCut = begin + len1Half;
434 secondCut = qLowerBound(pivot, end, *firstCut, lessThan);
435 len2Half = secondCut - pivot;
438 secondCut = pivot + len2Half;
439 firstCut = qUpperBound(begin, pivot, *secondCut, lessThan);
442 qRotate(firstCut, pivot, secondCut);
443 const RandomAccessIterator newPivot = firstCut + len2Half;
444 qMerge(begin, firstCut, newPivot, t, lessThan);
445 qMerge(newPivot, secondCut, end, t, lessThan);
448 template <typename RandomAccessIterator, typename T, typename LessThan>
449 Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
451 const int span = end - begin;
455 const RandomAccessIterator middle = begin + span / 2;
456 qStableSortHelper(begin, middle, t, lessThan);
457 qStableSortHelper(middle, end, t, lessThan);
458 qMerge(begin, middle, end, t, lessThan);
461 template <typename RandomAccessIterator, typename T>
462 inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
464 qStableSortHelper(begin, end, dummy, qLess<T>());
467 template <typename RandomAccessIterator, typename T, typename LessThan>
468 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
470 RandomAccessIterator middle;
471 int n = int(end - begin);
476 middle = begin + half;
477 if (lessThan(*middle, value)) {
488 template <typename RandomAccessIterator, typename T, typename LessThan>
489 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
491 RandomAccessIterator middle;
497 middle = begin + half;
498 if (lessThan(value, *middle)) {
508 template <typename RandomAccessIterator, typename T, typename LessThan>
509 Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
511 RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan);
513 if (it == end || lessThan(value, *it))
519 } //namespace QAlgorithmsPrivate
525 #endif // QALGORITHMS_H