Purge qalgorithm.h of deprecated API
A large slice of it has been deprecated since 5.2. Reflowed a doc paragraph pointed out, in the deprecation commit, as having been left ragged by its edits. Note: qSwap() is documented as \deprecated but not marked, where it's defined, as deprecated. Change-Id: Iaff10ac0c4c38e5b85f10eca4eedeab861f09959 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
17ba201a3f
commit
26547c296b
@ -938,6 +938,7 @@ namespace SwapExceptionTester { // insulate users from the "using std::swap" bel
|
||||
}
|
||||
} // namespace QtPrivate
|
||||
|
||||
// Documented in ../tools/qalgorithm.qdoc
|
||||
template <typename T>
|
||||
inline void qSwap(T &value1, T &value2)
|
||||
noexcept(noexcept(QtPrivate::SwapExceptionTester::checkSwap(value1)))
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -47,271 +47,6 @@
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
|
||||
/*
|
||||
Warning: The contents of QAlgorithmsPrivate is not a part of the public Qt API
|
||||
and may be changed from version to version or even be completely removed.
|
||||
*/
|
||||
namespace QAlgorithmsPrivate {
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 2)
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::sort") Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::sort") inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::stable_sort") Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
|
||||
#endif // QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 2)
|
||||
template <typename InputIterator, typename OutputIterator>
|
||||
QT_DEPRECATED_X("Use std::copy") inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
|
||||
{
|
||||
while (begin != end)
|
||||
*dest++ = *begin++;
|
||||
return dest;
|
||||
}
|
||||
|
||||
template <typename BiIterator1, typename BiIterator2>
|
||||
QT_DEPRECATED_X("Use std::copy_backward") inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
|
||||
{
|
||||
while (begin != end)
|
||||
*--dest = *--end;
|
||||
return dest;
|
||||
}
|
||||
|
||||
template <typename InputIterator1, typename InputIterator2>
|
||||
QT_DEPRECATED_X("Use std::equal") inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
|
||||
{
|
||||
for (; first1 != last1; ++first1, ++first2)
|
||||
if (!(*first1 == *first2))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ForwardIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::fill") inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
*first = val;
|
||||
}
|
||||
|
||||
template <typename Container, typename T>
|
||||
QT_DEPRECATED_X("Use std::fill") inline void qFill(Container &container, const T &val)
|
||||
{
|
||||
qFill(container.begin(), container.end(), val);
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::find") inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
|
||||
{
|
||||
while (first != last && !(*first == val))
|
||||
++first;
|
||||
return first;
|
||||
}
|
||||
|
||||
template <typename Container, typename T>
|
||||
QT_DEPRECATED_X("Use std::find") inline typename Container::const_iterator qFind(const Container &container, const T &val)
|
||||
{
|
||||
return qFind(container.constBegin(), container.constEnd(), val);
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename T, typename Size>
|
||||
QT_DEPRECATED_X("Use std::count") inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
if (*first == value)
|
||||
++n;
|
||||
}
|
||||
|
||||
template <typename Container, typename T, typename Size>
|
||||
QT_DEPRECATED_X("Use std::count") inline void qCount(const Container &container, const T &value, Size &n)
|
||||
{
|
||||
qCount(container.constBegin(), container.constEnd(), value, n);
|
||||
}
|
||||
|
||||
#ifdef Q_QDOC
|
||||
typedef void* LessThan;
|
||||
template <typename T> LessThan qLess();
|
||||
template <typename T> LessThan qGreater();
|
||||
#else
|
||||
template <typename T>
|
||||
class QT_DEPRECATED_X("Use std::less") qLess
|
||||
{
|
||||
public:
|
||||
inline bool operator()(const T &t1, const T &t2) const
|
||||
{
|
||||
return (t1 < t2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class QT_DEPRECATED_X("Use std::greater") qGreater
|
||||
{
|
||||
public:
|
||||
inline bool operator()(const T &t1, const T &t2) const
|
||||
{
|
||||
return (t2 < t1);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename RandomAccessIterator>
|
||||
QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
|
||||
{
|
||||
if (start != end)
|
||||
QAlgorithmsPrivate::qSortHelper(start, end, *start);
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
|
||||
{
|
||||
if (start != end)
|
||||
QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
QT_DEPRECATED_X("Use std::sort") inline void qSort(Container &c)
|
||||
{
|
||||
#ifdef Q_CC_BOR
|
||||
// Work around Borland 5.5 optimizer bug
|
||||
c.detach();
|
||||
#endif
|
||||
if (!c.empty())
|
||||
QAlgorithmsPrivate::qSortHelper(c.begin(), c.end(), *c.begin());
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator>
|
||||
QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
|
||||
{
|
||||
if (start != end)
|
||||
QAlgorithmsPrivate::qStableSortHelper(start, end, *start);
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
|
||||
{
|
||||
if (start != end)
|
||||
QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan);
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(Container &c)
|
||||
{
|
||||
#ifdef Q_CC_BOR
|
||||
// Work around Borland 5.5 optimizer bug
|
||||
c.detach();
|
||||
#endif
|
||||
if (!c.empty())
|
||||
QAlgorithmsPrivate::qStableSortHelper(c.begin(), c.end(), *c.begin());
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
|
||||
{
|
||||
// Implementation is duplicated from QAlgorithmsPrivate to keep existing code
|
||||
// compiling. We have to allow using *begin and value with different types,
|
||||
// and then implementing operator< for those types.
|
||||
RandomAccessIterator middle;
|
||||
int n = end - begin;
|
||||
int half;
|
||||
|
||||
while (n > 0) {
|
||||
half = n >> 1;
|
||||
middle = begin + half;
|
||||
if (*middle < value) {
|
||||
begin = middle + 1;
|
||||
n -= half + 1;
|
||||
} else {
|
||||
n = half;
|
||||
}
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
{
|
||||
return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan);
|
||||
}
|
||||
|
||||
template <typename Container, typename T>
|
||||
QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
|
||||
{
|
||||
return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
|
||||
{
|
||||
// Implementation is duplicated from QAlgorithmsPrivate.
|
||||
RandomAccessIterator middle;
|
||||
int n = end - begin;
|
||||
int half;
|
||||
|
||||
while (n > 0) {
|
||||
half = n >> 1;
|
||||
middle = begin + half;
|
||||
if (value < *middle) {
|
||||
n = half;
|
||||
} else {
|
||||
begin = middle + 1;
|
||||
n -= half + 1;
|
||||
}
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
{
|
||||
return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan);
|
||||
}
|
||||
|
||||
template <typename Container, typename T>
|
||||
QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
|
||||
{
|
||||
return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
|
||||
{
|
||||
// Implementation is duplicated from QAlgorithmsPrivate.
|
||||
RandomAccessIterator it = qLowerBound(begin, end, value);
|
||||
|
||||
if (it == end || value < *it)
|
||||
return end;
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
{
|
||||
return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan);
|
||||
}
|
||||
|
||||
template <typename Container, typename T>
|
||||
QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
|
||||
{
|
||||
return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
|
||||
}
|
||||
#endif // QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
template <typename ForwardIterator>
|
||||
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
|
||||
@ -334,191 +69,6 @@ inline void qDeleteAll(const Container &c)
|
||||
*/
|
||||
namespace QAlgorithmsPrivate {
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::sort") Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
|
||||
{
|
||||
top:
|
||||
int span = int(end - start);
|
||||
if (span < 2)
|
||||
return;
|
||||
|
||||
--end;
|
||||
RandomAccessIterator low = start, high = end - 1;
|
||||
RandomAccessIterator pivot = start + span / 2;
|
||||
|
||||
if (lessThan(*end, *start))
|
||||
qSwap(*end, *start);
|
||||
if (span == 2)
|
||||
return;
|
||||
|
||||
if (lessThan(*pivot, *start))
|
||||
qSwap(*pivot, *start);
|
||||
if (lessThan(*end, *pivot))
|
||||
qSwap(*end, *pivot);
|
||||
if (span == 3)
|
||||
return;
|
||||
|
||||
qSwap(*pivot, *end);
|
||||
|
||||
while (low < high) {
|
||||
while (low < high && lessThan(*low, *end))
|
||||
++low;
|
||||
|
||||
while (high > low && lessThan(*end, *high))
|
||||
--high;
|
||||
|
||||
if (low < high) {
|
||||
qSwap(*low, *high);
|
||||
++low;
|
||||
--high;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lessThan(*low, *end))
|
||||
++low;
|
||||
|
||||
qSwap(*end, *low);
|
||||
qSortHelper(start, low, t, lessThan);
|
||||
|
||||
start = low + 1;
|
||||
++end;
|
||||
goto top;
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::sort") inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
|
||||
{
|
||||
qSortHelper(begin, end, dummy, qLess<T>());
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator>
|
||||
QT_DEPRECATED_X("Use std::reverse") Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
|
||||
{
|
||||
--end;
|
||||
while (begin < end)
|
||||
qSwap(*begin++, *end--);
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator>
|
||||
QT_DEPRECATED_X("Use std::rotate") Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
|
||||
{
|
||||
qReverse(begin, middle);
|
||||
qReverse(middle, end);
|
||||
qReverse(begin, end);
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::merge") Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
|
||||
{
|
||||
const int len1 = pivot - begin;
|
||||
const int len2 = end - pivot;
|
||||
|
||||
if (len1 == 0 || len2 == 0)
|
||||
return;
|
||||
|
||||
if (len1 + len2 == 2) {
|
||||
if (lessThan(*(begin + 1), *(begin)))
|
||||
qSwap(*begin, *(begin + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
RandomAccessIterator firstCut;
|
||||
RandomAccessIterator secondCut;
|
||||
int len2Half;
|
||||
if (len1 > len2) {
|
||||
const int len1Half = len1 / 2;
|
||||
firstCut = begin + len1Half;
|
||||
secondCut = qLowerBound(pivot, end, *firstCut, lessThan);
|
||||
len2Half = secondCut - pivot;
|
||||
} else {
|
||||
len2Half = len2 / 2;
|
||||
secondCut = pivot + len2Half;
|
||||
firstCut = qUpperBound(begin, pivot, *secondCut, lessThan);
|
||||
}
|
||||
|
||||
qRotate(firstCut, pivot, secondCut);
|
||||
const RandomAccessIterator newPivot = firstCut + len2Half;
|
||||
qMerge(begin, firstCut, newPivot, t, lessThan);
|
||||
qMerge(newPivot, secondCut, end, t, lessThan);
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::stable_sort") Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
|
||||
{
|
||||
const int span = end - begin;
|
||||
if (span < 2)
|
||||
return;
|
||||
|
||||
const RandomAccessIterator middle = begin + span / 2;
|
||||
qStableSortHelper(begin, middle, t, lessThan);
|
||||
qStableSortHelper(middle, end, t, lessThan);
|
||||
qMerge(begin, middle, end, t, lessThan);
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T>
|
||||
QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
|
||||
{
|
||||
qStableSortHelper(begin, end, dummy, qLess<T>());
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
{
|
||||
RandomAccessIterator middle;
|
||||
int n = int(end - begin);
|
||||
int half;
|
||||
|
||||
while (n > 0) {
|
||||
half = n >> 1;
|
||||
middle = begin + half;
|
||||
if (lessThan(*middle, value)) {
|
||||
begin = middle + 1;
|
||||
n -= half + 1;
|
||||
} else {
|
||||
n = half;
|
||||
}
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
{
|
||||
RandomAccessIterator middle;
|
||||
int n = end - begin;
|
||||
int half;
|
||||
|
||||
while (n > 0) {
|
||||
half = n >> 1;
|
||||
middle = begin + half;
|
||||
if (lessThan(value, *middle)) {
|
||||
n = half;
|
||||
} else {
|
||||
begin = middle + 1;
|
||||
n -= half + 1;
|
||||
}
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename T, typename LessThan>
|
||||
QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
{
|
||||
RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan);
|
||||
|
||||
if (it == end || lessThan(value, *it))
|
||||
return end;
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
#endif // QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
#ifdef Q_CC_CLANG
|
||||
// Clang had a bug where __builtin_ctz/clz/popcount were not marked as constexpr.
|
||||
# if (defined __apple_build_version__ && __clang_major__ >= 7) || (Q_CC_CLANG >= 307)
|
||||
@ -896,7 +446,6 @@ QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(unsigned long v)
|
||||
return qCountLeadingZeroBits(QIntegerForSizeof<long>::Unsigned(v));
|
||||
}
|
||||
|
||||
QT_WARNING_POP
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QALGORITHMS_H
|
||||
|
@ -54,12 +54,11 @@
|
||||
\l {Output Iterators}{output iterator}), you will always get a
|
||||
compiler error, although not necessarily a very informative one.
|
||||
|
||||
Some algorithms have special requirements on the value type
|
||||
stored in the containers. For example,
|
||||
qDeleteAll() requires that the value type is a
|
||||
non-const pointer type (for example, QWidget *). The value type
|
||||
requirements are specified for each algorithm, and the compiler
|
||||
will produce an error if a requirement isn't met.
|
||||
Some algorithms have special requirements on the value type stored
|
||||
in the containers. For example, qDeleteAll() requires that the
|
||||
value type is a non-const pointer type (for example, QWidget
|
||||
*). The value type requirements are specified for each algorithm,
|
||||
and the compiler will produce an error if a requirement isn't met.
|
||||
|
||||
The generic algorithms can be used on other container classes
|
||||
than those provided by Qt and STL. The syntax of STL-style
|
||||
@ -145,236 +144,9 @@
|
||||
|
||||
QList's non-const iterator type is random access iterator.
|
||||
|
||||
\section1 Qt and the STL Algorithms
|
||||
|
||||
Historically, Qt used to provide functions which were direct equivalents of
|
||||
many STL algorithmic functions. Starting with Qt 5.0, you are instead
|
||||
encouraged to use directly the implementations available in the STL; most
|
||||
of the Qt ones have been deprecated (although they are still available to
|
||||
keep the old code compiling).
|
||||
|
||||
\section2 Porting guidelines
|
||||
|
||||
Most of the time, an application using the deprecated Qt algorithmic functions
|
||||
can be easily ported to use the equivalent STL functions. You need to:
|
||||
|
||||
\list 1
|
||||
\li add the \c{#include <algorithm>} preprocessor directive;
|
||||
\li replace the Qt functions with the STL counterparts, according to the table below.
|
||||
\endlist
|
||||
|
||||
\table
|
||||
\header
|
||||
\li Qt function
|
||||
\li STL function
|
||||
\row
|
||||
\li qBinaryFind
|
||||
\li \c std::binary_search or \c std::lower_bound
|
||||
\row
|
||||
\li qCopy
|
||||
\li \c std::copy
|
||||
\row
|
||||
\li qCopyBackward
|
||||
\li \c std::copy_backward
|
||||
\row
|
||||
\li qEqual
|
||||
\li \c std::equal
|
||||
\row
|
||||
\li qFill
|
||||
\li \c std::fill
|
||||
\row
|
||||
\li qFind
|
||||
\li \c std::find
|
||||
\row
|
||||
\li qCount
|
||||
\li \c std::count
|
||||
\row
|
||||
\li qSort
|
||||
\li \c std::sort
|
||||
\row
|
||||
\li qStableSort
|
||||
\li \c std::stable_sort
|
||||
\row
|
||||
\li qLowerBound
|
||||
\li \c std::lower_bound
|
||||
\row
|
||||
\li qUpperBound
|
||||
\li \c std::upper_bound
|
||||
\row
|
||||
\li qLess
|
||||
\li \c std::less
|
||||
\row
|
||||
\li qGreater
|
||||
\li \c std::greater
|
||||
|
||||
\endtable
|
||||
|
||||
The only cases in which the port may not be straightforward is if the old
|
||||
code relied on template specializations of the qLess() and/or the qSwap()
|
||||
functions, which were used internally by the implementations of the Qt
|
||||
algorithmic functions, but are instead ignored by the STL ones.
|
||||
|
||||
In case the old code relied on the specialization of the qLess() functor,
|
||||
then a workaround is explicitly passing an instance of the qLess() class
|
||||
to the STL function, for instance like this:
|
||||
|
||||
\code
|
||||
std::sort(container.begin(), container.end(), qLess<T>());
|
||||
\endcode
|
||||
|
||||
Instead, since it's not possible to pass a custom swapper functor to STL
|
||||
functions, the only workaround for a template specialization for qSwap() is
|
||||
providing the same specialization for \c std::swap().
|
||||
|
||||
\sa {container classes}, <QtGlobal>
|
||||
*/
|
||||
|
||||
/*! \fn template <typename InputIterator, typename OutputIterator> OutputIterator qCopy(InputIterator begin1, InputIterator end1, OutputIterator begin2)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::copy instead.
|
||||
|
||||
Copies the items from range [\a begin1, \a end1) to range [\a
|
||||
begin2, ...), in the order in which they appear.
|
||||
|
||||
The item at position \a begin1 is assigned to that at position \a
|
||||
begin2; the item at position \a begin1 + 1 is assigned to that at
|
||||
position \a begin2 + 1; and so on.
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 4
|
||||
|
||||
\sa qCopyBackward(), {input iterators}, {output iterators}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename BiIterator1, typename BiIterator2> BiIterator2 qCopyBackward(BiIterator1 begin1, BiIterator1 end1, BiIterator2 end2)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::copy_backward instead.
|
||||
|
||||
Copies the items from range [\a begin1, \a end1) to range [...,
|
||||
\a end2).
|
||||
|
||||
The item at position \a end1 - 1 is assigned to that at position
|
||||
\a end2 - 1; the item at position \a end1 - 2 is assigned to that
|
||||
at position \a end2 - 2; and so on.
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 5
|
||||
|
||||
\sa qCopy(), {bidirectional iterators}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename InputIterator1, typename InputIterator2> bool qEqual(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::equal instead.
|
||||
|
||||
Compares the items in the range [\a begin1, \a end1) with the
|
||||
items in the range [\a begin2, ...). Returns \c true if all the
|
||||
items compare equal; otherwise returns \c false.
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 6
|
||||
|
||||
This function requires the item type (in the example above,
|
||||
QString) to implement \c operator==().
|
||||
|
||||
\sa {input iterators}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename ForwardIterator, typename T> void qFill(ForwardIterator begin, ForwardIterator end, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::fill instead.
|
||||
|
||||
Fills the range [\a begin, \a end) with \a value.
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 7
|
||||
|
||||
\sa qCopy(), {forward iterators}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename Container, typename T> void qFill(Container &container, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::fill instead.
|
||||
|
||||
This is the same as qFill(\a{container}.begin(), \a{container}.end(), \a value);
|
||||
*/
|
||||
|
||||
/*! \fn template <typename InputIterator, typename T> InputIterator qFind(InputIterator begin, InputIterator end, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::find instead.
|
||||
|
||||
Returns an iterator to the first occurrence of \a value in a
|
||||
container in the range [\a begin, \a end). Returns \a end if \a
|
||||
value isn't found.
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 8
|
||||
|
||||
This function requires the item type (in the example above,
|
||||
QString) to implement \c operator==().
|
||||
|
||||
If the items in the range are in ascending order, you can get
|
||||
faster results by using qLowerBound() or qBinaryFind() instead of
|
||||
qFind().
|
||||
|
||||
\sa qBinaryFind(), {input iterators}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename Container, typename T> void qFind(const Container &container, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::find instead.
|
||||
|
||||
This is the same as qFind(\a{container}.constBegin(), \a{container}.constEnd(), \a value);
|
||||
*/
|
||||
|
||||
/*! \fn template <typename InputIterator, typename T, typename Size> void qCount(InputIterator begin, InputIterator end, const T &value, Size &n)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::count instead.
|
||||
|
||||
Returns the number of occurrences of \a value in the range [\a begin, \a end),
|
||||
which is returned in \a n. \a n is never initialized, the count is added to \a n.
|
||||
It is the caller's responsibility to initialize \a n.
|
||||
|
||||
Example:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 9
|
||||
|
||||
This function requires the item type (in the example above,
|
||||
\c int) to implement \c operator==().
|
||||
|
||||
\sa {input iterators}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename Container, typename T, typename Size> void qCount(const Container &container, const T &value, Size &n)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::count instead.
|
||||
|
||||
Instead of operating on iterators, as in the other overload, this function
|
||||
operates on the specified \a container to obtain the number of instances
|
||||
of \a value in the variable passed as a reference in argument \a n.
|
||||
*/
|
||||
|
||||
/*! \fn template <typename T> void qSwap(T &var1, T &var2)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
@ -387,311 +159,6 @@
|
||||
\snippet code/doc_src_qalgorithms.cpp 10
|
||||
*/
|
||||
|
||||
/*! \fn template <typename RandomAccessIterator> void qSort(RandomAccessIterator begin, RandomAccessIterator end)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::sort instead.
|
||||
|
||||
Sorts the items in range [\a begin, \a end) in ascending order
|
||||
using the quicksort algorithm.
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 11
|
||||
|
||||
The sort algorithm is efficient on large data sets. It operates
|
||||
in \l {linear-logarithmic time}, O(\e{n} log \e{n}).
|
||||
|
||||
This function requires the item type (in the example above,
|
||||
\c{int}) to implement \c operator<().
|
||||
|
||||
If neither of the two items is "less than" the other, the items are
|
||||
taken to be equal. It is then undefined which one of the two
|
||||
items will appear before the other after the sort.
|
||||
|
||||
\sa qStableSort(), {random access iterators}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename RandomAccessIterator, typename LessThan> void qSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::sort instead.
|
||||
|
||||
Uses the \a lessThan function instead of \c operator<() to
|
||||
compare the items.
|
||||
|
||||
For example, here's how to sort the strings in a QStringList
|
||||
in case-insensitive alphabetical order:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 12
|
||||
|
||||
To sort values in reverse order, pass
|
||||
\l{qGreater()}{qGreater<T>()} as the \a lessThan parameter. For
|
||||
example:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 13
|
||||
|
||||
If neither of the two items is "less than" the other, the items are
|
||||
taken to be equal. It is then undefined which one of the two
|
||||
items will appear before the other after the sort.
|
||||
|
||||
An alternative to using qSort() is to put the items to sort in a
|
||||
QMap, using the sort key as the QMap key. This is often more
|
||||
convenient than defining a \a lessThan function. For example, the
|
||||
following code shows how to sort a list of strings case
|
||||
insensitively using QMap:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 14
|
||||
|
||||
\sa QMap
|
||||
*/
|
||||
|
||||
/*! \fn template<typename Container> void qSort(Container &container)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::sort instead.
|
||||
|
||||
This is the same as qSort(\a{container}.begin(), \a{container}.end());
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename RandomAccessIterator> void qStableSort(RandomAccessIterator begin, RandomAccessIterator end)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::stable_sort instead.
|
||||
|
||||
Sorts the items in range [\a begin, \a end) in ascending order
|
||||
using a stable sorting algorithm.
|
||||
|
||||
If neither of the two items is "less than" the other, the items are
|
||||
taken to be equal. The item that appeared before the other in the
|
||||
original container will still appear first after the sort. This
|
||||
property is often useful when sorting user-visible data.
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 15
|
||||
|
||||
The sort algorithm is efficient on large data sets. It operates
|
||||
in \l {linear-logarithmic time}, O(\e{n} log \e{n}).
|
||||
|
||||
This function requires the item type (in the example above,
|
||||
\c{int}) to implement \c operator<().
|
||||
|
||||
\sa qSort(), {random access iterators}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename RandomAccessIterator, typename LessThan> void qStableSort(RandomAccessIterator begin, RandomAccessIterator end, LessThan lessThan)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::stable_sort instead.
|
||||
|
||||
Uses the \a lessThan function instead of \c operator<() to
|
||||
compare the items.
|
||||
|
||||
For example, here's how to sort the strings in a QStringList
|
||||
in case-insensitive alphabetical order:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 16
|
||||
|
||||
Note that earlier versions of Qt allowed using a lessThan function that took its
|
||||
arguments by non-const reference. From 4.3 and on this is no longer possible,
|
||||
the arguments has to be passed by const reference or value.
|
||||
|
||||
To sort values in reverse order, pass
|
||||
\l{qGreater()}{qGreater<T>()} as the \a lessThan parameter. For
|
||||
example:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 17
|
||||
|
||||
If neither of the two items is "less than" the other, the items are
|
||||
taken to be equal. The item that appeared before the other in the
|
||||
original container will still appear first after the sort. This
|
||||
property is often useful when sorting user-visible data.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Container> void qStableSort(Container &container)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::stable_sort instead.
|
||||
|
||||
This is the same as qStableSort(\a{container}.begin(), \a{container}.end());
|
||||
*/
|
||||
|
||||
/*! \fn template <typename RandomAccessIterator, typename T> RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::lower_bound instead.
|
||||
|
||||
Performs a binary search of the range [\a begin, \a end) and
|
||||
returns the position of the first occurrence of \a value. If no
|
||||
such item is found, returns the position where it should be
|
||||
inserted.
|
||||
|
||||
The items in the range [\a begin, \e end) must be sorted in
|
||||
ascending order; see qSort().
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 18
|
||||
|
||||
This function requires the item type (in the example above,
|
||||
\c{int}) to implement \c operator<().
|
||||
|
||||
qLowerBound() can be used in conjunction with qUpperBound() to
|
||||
iterate over all occurrences of the same value:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 19
|
||||
|
||||
\sa qUpperBound(), qBinaryFind()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename RandomAccessIterator, typename T, typename LessThan> RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::lower_bound instead.
|
||||
|
||||
Uses the \a lessThan function instead of \c operator<() to
|
||||
compare the items.
|
||||
|
||||
Note that the items in the range must be sorted according to the order
|
||||
specified by the \a lessThan object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Container, typename T> void qLowerBound(const Container &container, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::lower_bound instead.
|
||||
|
||||
For read-only iteration over containers, this function is broadly equivalent to
|
||||
qLowerBound(\a{container}.begin(), \a{container}.end(), value). However, since it
|
||||
returns a const iterator, you cannot use it to modify the container; for example,
|
||||
to insert items.
|
||||
*/
|
||||
|
||||
/*! \fn template <typename RandomAccessIterator, typename T> RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::upper_bound instead.
|
||||
|
||||
Performs a binary search of the range [\a begin, \a end) and
|
||||
returns the position of the one-past-the-last occurrence of \a
|
||||
value. If no such item is found, returns the position where the
|
||||
item should be inserted.
|
||||
|
||||
The items in the range [\a begin, \e end) must be sorted in
|
||||
ascending order; see qSort().
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 20
|
||||
|
||||
This function requires the item type (in the example above,
|
||||
\c{int}) to implement \c operator<().
|
||||
|
||||
qUpperBound() can be used in conjunction with qLowerBound() to
|
||||
iterate over all occurrences of the same value:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 21
|
||||
|
||||
\sa qLowerBound(), qBinaryFind()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename RandomAccessIterator, typename T, typename LessThan> RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::upper_bound instead.
|
||||
|
||||
Uses the \a lessThan function instead of \c operator<() to
|
||||
compare the items.
|
||||
|
||||
Note that the items in the range must be sorted according to the order
|
||||
specified by the \a lessThan object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Container, typename T> void qUpperBound(const Container &container, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::upper_bound instead.
|
||||
|
||||
This is the same as qUpperBound(\a{container}.begin(), \a{container}.end(), \a value);
|
||||
*/
|
||||
|
||||
|
||||
/*! \fn template <typename RandomAccessIterator, typename T> RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::binary_search or \c std::lower_bound instead.
|
||||
|
||||
Performs a binary search of the range [\a begin, \a end) and
|
||||
returns the position of an occurrence of \a value. If there are
|
||||
no occurrences of \a value, returns \a end.
|
||||
|
||||
The items in the range [\a begin, \a end) must be sorted in
|
||||
ascending order; see qSort().
|
||||
|
||||
If there are many occurrences of the same value, any one of them
|
||||
could be returned. Use qLowerBound() or qUpperBound() if you need
|
||||
finer control.
|
||||
|
||||
Example:
|
||||
\snippet code/doc_src_qalgorithms.cpp 22
|
||||
|
||||
This function requires the item type (in the example above,
|
||||
QString) to implement \c operator<().
|
||||
|
||||
\sa qLowerBound(), qUpperBound(), {random access iterators}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename RandomAccessIterator, typename T, typename LessThan> RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::binary_search or \c std::lower_bound instead.
|
||||
|
||||
Uses the \a lessThan function instead of \c operator<() to
|
||||
compare the items.
|
||||
|
||||
Note that the items in the range must be sorted according to the order
|
||||
specified by the \a lessThan object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Container, typename T> void qBinaryFind(const Container &container, const T &value)
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
\overload
|
||||
|
||||
Use \c std::binary_search or \c std::lower_bound instead.
|
||||
|
||||
This is the same as qBinaryFind(\a{container}.begin(), \a{container}.end(), \a value);
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn template <typename ForwardIterator> void qDeleteAll(ForwardIterator begin, ForwardIterator end)
|
||||
\relates <QtAlgorithms>
|
||||
@ -724,39 +191,6 @@
|
||||
This is the same as qDeleteAll(\a{c}.begin(), \a{c}.end()).
|
||||
*/
|
||||
|
||||
/*! \fn template <typename LessThan> LessThan qLess()
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::less instead.
|
||||
|
||||
Returns a functional object, or functor, that can be passed to qSort()
|
||||
or qStableSort().
|
||||
|
||||
Example:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 24
|
||||
|
||||
\sa {qGreater()}{qGreater<T>()}
|
||||
*/
|
||||
|
||||
/*! \fn template <typename LessThan> LessThan qGreater()
|
||||
\relates <QtAlgorithms>
|
||||
\deprecated
|
||||
|
||||
Use \c std::greater instead.
|
||||
|
||||
Returns a functional object, or functor, that can be passed to qSort()
|
||||
or qStableSort().
|
||||
|
||||
Example:
|
||||
|
||||
\snippet code/doc_src_qalgorithms.cpp 25
|
||||
|
||||
\sa {qLess()}{qLess<T>()}
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn uint qPopulationCount(quint8 v)
|
||||
\relates <QtAlgorithms>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
@ -54,31 +54,6 @@ private slots:
|
||||
void swap2();
|
||||
void convenienceAPI();
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 2)
|
||||
void test_qLowerBound_data();
|
||||
void test_qLowerBound();
|
||||
void test_qUpperBound_data();
|
||||
void test_qUpperBound();
|
||||
void test_qBinaryFind_data();
|
||||
void test_qBinaryFind();
|
||||
void qBinaryFindOneEntry();
|
||||
void sortEmptyList();
|
||||
void sortedList();
|
||||
void sortAPItest();
|
||||
void stableSortTest();
|
||||
void stableSortCorrectnessTest_data();
|
||||
void stableSortCorrectnessTest();
|
||||
void convenienceAPI_deprecated();
|
||||
void qCountIterators() const;
|
||||
void qCountContainer() const;
|
||||
void binaryFindOnLargeContainer() const;
|
||||
|
||||
#if Q_TEST_PERFORMANCE
|
||||
void performance();
|
||||
#endif
|
||||
|
||||
#endif // QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
void popCount08_data() { popCount_data_impl(sizeof(quint8 )); }
|
||||
void popCount16_data() { popCount_data_impl(sizeof(quint16)); }
|
||||
void popCount32_data() { popCount_data_impl(sizeof(quint32)); }
|
||||
@ -120,155 +95,6 @@ private:
|
||||
void countLeading_impl();
|
||||
};
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
class TestInt
|
||||
{
|
||||
public:
|
||||
TestInt(int number) :m_number(number) {} ;
|
||||
TestInt() : m_number(0) {};
|
||||
bool operator<(const TestInt &other) const { ++TestInt::lessThanRefCount; return (m_number < other.m_number); }
|
||||
int m_number;
|
||||
static long int lessThanRefCount;
|
||||
};
|
||||
|
||||
long int TestInt::lessThanRefCount;
|
||||
|
||||
|
||||
QStringList dataSetTypes = QStringList() << "Random" << "Ascending"
|
||||
<< "Descending" << "Equal" << "Duplicates" << "Almost Sorted" ;
|
||||
|
||||
template <typename DataType>
|
||||
QList<DataType> generateData(QString dataSetType, const int length)
|
||||
{
|
||||
QList<DataType> container;
|
||||
if (dataSetType == "Random") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(QRandomGenerator::global()->generate());
|
||||
} else if (dataSetType == "Ascending") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(i);
|
||||
} else if (dataSetType == "Descending") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(length - i);
|
||||
} else if (dataSetType == "Equal") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(43);
|
||||
} else if (dataSetType == "Duplicates") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(i % 10);
|
||||
} else if (dataSetType == "Almost Sorted") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(i);
|
||||
for (int i = 0; i <= length / 10; ++i) {
|
||||
const int iswap = i * 9;
|
||||
DataType tmp = container.at(iswap);
|
||||
container[iswap] = container.at(iswap + 1);
|
||||
container[iswap + 1] = tmp;
|
||||
}
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
struct ResultSet
|
||||
{
|
||||
int numSorts;
|
||||
long int lessThanRefCount;
|
||||
};
|
||||
|
||||
|
||||
template <typename ContainerType, typename Algorithm>
|
||||
ResultSet testRun(ContainerType &container, Algorithm &algorithm, int millisecs)
|
||||
{
|
||||
TestInt::lessThanRefCount = 0;
|
||||
int count = 0;
|
||||
QElapsedTimer t;
|
||||
t.start();
|
||||
while(t.elapsed() < millisecs) {
|
||||
++count;
|
||||
algorithm(container);
|
||||
}
|
||||
ResultSet result;
|
||||
result.numSorts = count;
|
||||
result.lessThanRefCount = TestInt::lessThanRefCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename ContainerType, typename LessThan>
|
||||
bool isSorted(ContainerType &container, LessThan lessThan)
|
||||
{
|
||||
for (int i=0; i < container.count() - 1; ++i)
|
||||
if (lessThan(container.at(i+1), container.at(i))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ContainerType>
|
||||
bool isSorted(ContainerType &container)
|
||||
{
|
||||
return isSorted(container, qLess<typename ContainerType::value_type>());
|
||||
}
|
||||
|
||||
|
||||
#if Q_TEST_PERFORMANCE
|
||||
void printHeader(QStringList &headers)
|
||||
{
|
||||
cout << setw(10) << setiosflags(ios_base::left) << " ";
|
||||
for (int h = 0; h < headers.count(); ++h) {
|
||||
cout << setw(20) << setiosflags(ios_base::left) << headers.at(h).toLatin1().constData();
|
||||
}
|
||||
cout << Qt::endl;
|
||||
}
|
||||
|
||||
template <typename ContainerType>
|
||||
void print(ContainerType testContainer)
|
||||
{
|
||||
typedef typename ContainerType::value_type T;
|
||||
|
||||
foreach(T value, testContainer) {
|
||||
cout << value << " ";
|
||||
}
|
||||
|
||||
cout << Qt::endl;
|
||||
}
|
||||
|
||||
template <typename Algorithm, typename DataType>
|
||||
QList<ResultSet> testAlgorithm(Algorithm &algorithm, QStringList dataSetTypes, int size, int time)
|
||||
{
|
||||
QList<ResultSet> results;
|
||||
foreach(QString dataSetType, dataSetTypes) {
|
||||
QList<DataType> container = generateData<DataType>(dataSetType, size);
|
||||
results.append(testRun(container, algorithm, time));
|
||||
if (!isSorted(container))
|
||||
qWarning("%s: container is not sorted after test", Q_FUNC_INFO);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
template <typename Algorithm, typename DataType>
|
||||
void testAlgorithm(Algorithm algorithm, QStringList &dataSetTypes)
|
||||
{
|
||||
QList<int> sizes = QList<int>() << 5 << 15 << 35 << 70 << 200 << 1000 << 10000;
|
||||
printHeader(dataSetTypes);
|
||||
for (int s = 0; s < sizes.count(); ++s){
|
||||
cout << setw(10) << setiosflags(ios_base::left)<< sizes.at(s);
|
||||
QList<ResultSet> results =
|
||||
testAlgorithm<Algorithm, DataType>(algorithm, dataSetTypes, sizes.at(s), 100);
|
||||
foreach(ResultSet result, results) {
|
||||
stringstream numSorts;
|
||||
numSorts << setiosflags(ios_base::left) << setw(10) << result.numSorts;
|
||||
stringstream lessThan;
|
||||
lessThan << setiosflags(ios_base::left) << setw(10) << result.lessThanRefCount / result.numSorts;
|
||||
cout << numSorts.str() << lessThan.str();
|
||||
}
|
||||
cout << Qt::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
void tst_QAlgorithms::swap()
|
||||
{
|
||||
{
|
||||
@ -412,639 +238,6 @@ void tst_QAlgorithms::convenienceAPI()
|
||||
qDeleteAll(pointerList.begin(), pointerList.end());
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
void tst_QAlgorithms::sortEmptyList()
|
||||
{
|
||||
// Only test if it crashes
|
||||
QStringList stringList;
|
||||
stringList.sort();
|
||||
QVERIFY(true);
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::sortedList()
|
||||
{
|
||||
QList<int> list;
|
||||
list << 4 << 3 << 6;
|
||||
|
||||
::qSort(list.begin(), list.end());
|
||||
|
||||
QCOMPARE(list.count(), 3);
|
||||
QCOMPARE(list.at(0), 3);
|
||||
QCOMPARE(list.at(1), 4);
|
||||
QCOMPARE(list.at(2), 6);
|
||||
|
||||
list.insert(qUpperBound(list.begin(), list.end(), 5), 5);
|
||||
list.insert(qUpperBound(list.begin(), list.end(), 1), 1);
|
||||
list.insert(qUpperBound(list.begin(), list.end(), 8), 8);
|
||||
|
||||
QCOMPARE(list.count(), 6);
|
||||
QCOMPARE(list.at(0), 1);
|
||||
QCOMPARE(list.at(1), 3);
|
||||
QCOMPARE(list.at(2), 4);
|
||||
QCOMPARE(list.at(3), 5);
|
||||
QCOMPARE(list.at(4), 6);
|
||||
QCOMPARE(list.at(5), 8);
|
||||
}
|
||||
|
||||
|
||||
void tst_QAlgorithms::test_qLowerBound_data()
|
||||
{
|
||||
QTest::addColumn<QList<int> >("data");
|
||||
QTest::addColumn<int>("resultValue");
|
||||
QTest::addColumn<int>("resultIndex");
|
||||
|
||||
QTest::newRow("sorted-duplicate") << (QList<int>() << 1 << 2 << 2 << 3) << 2 << 1;
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::test_qLowerBound()
|
||||
{
|
||||
QFETCH(QList<int>, data);
|
||||
QFETCH(int, resultValue);
|
||||
QFETCH(int, resultIndex);
|
||||
|
||||
|
||||
QCOMPARE(qLowerBound(data.constBegin(), data.constEnd(), resultValue), data.constBegin() + resultIndex);
|
||||
QCOMPARE(qLowerBound(data.begin(), data.end(), resultValue), data.begin() + resultIndex);
|
||||
QCOMPARE(qLowerBound(data, resultValue), data.constBegin() + resultIndex);
|
||||
QCOMPARE(qLowerBound(data.constBegin(), data.constEnd(), resultValue, qLess<int>()), data.constBegin() + resultIndex);
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::test_qUpperBound_data()
|
||||
{
|
||||
QTest::addColumn<QList<int> >("data");
|
||||
QTest::addColumn<int>("resultValue");
|
||||
QTest::addColumn<int>("resultIndex");
|
||||
|
||||
QTest::newRow("sorted-duplicate") << (QList<int>() << 1 << 2 << 2 << 3) << 2 << 3;
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::test_qUpperBound()
|
||||
{
|
||||
QFETCH(QList<int>, data);
|
||||
QFETCH(int, resultValue);
|
||||
QFETCH(int, resultIndex);
|
||||
|
||||
QCOMPARE(qUpperBound(data.constBegin(), data.constEnd(), resultValue), data.constBegin() + resultIndex);
|
||||
QCOMPARE(qUpperBound(data.begin(), data.end(), resultValue), data.begin() + resultIndex);
|
||||
QCOMPARE(qUpperBound(data, resultValue), data.constBegin() + resultIndex);
|
||||
QCOMPARE(qUpperBound(data.constBegin(), data.constEnd(), resultValue, qLess<int>()), data.constBegin() + resultIndex);
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::test_qBinaryFind_data()
|
||||
{
|
||||
QTest::addColumn<QList<int> >("data");
|
||||
QTest::addColumn<int>("resultValue"); // -42 means not found
|
||||
|
||||
QTest::newRow("sorted-duplicate") << (QList<int>() << 1 << 2 << 2 << 3) << 2;
|
||||
QTest::newRow("sorted-end") << (QList<int>() << -5 << -2 << 0 << 8) << 8;
|
||||
QTest::newRow("sorted-beginning") << (QList<int>() << -5 << -2 << 0 << 8) << -5;
|
||||
QTest::newRow("sorted-duplicate-beginning") << (QList<int>() << -5 << -5 << -2 << 0 << 8) << -5;
|
||||
QTest::newRow("empty") << (QList<int>()) << -42;
|
||||
QTest::newRow("not found 1 ") << (QList<int>() << 1 << 5 << 8 << 65) << -42;
|
||||
QTest::newRow("not found 2 ") << (QList<int>() << -456 << -5 << 8 << 65) << -42;
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::test_qBinaryFind()
|
||||
{
|
||||
QFETCH(QList<int>, data);
|
||||
QFETCH(int, resultValue);
|
||||
|
||||
//-42 means not found
|
||||
if (resultValue == -42) {
|
||||
QVERIFY(qBinaryFind(data.constBegin(), data.constEnd(), resultValue) == data.constEnd());
|
||||
QVERIFY(qBinaryFind(data, resultValue) == data.constEnd());
|
||||
QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue) == data.end());
|
||||
QVERIFY(qBinaryFind(data.begin(), data.end(), resultValue, qLess<int>()) == data.end());
|
||||
return;
|
||||
}
|
||||
|
||||
QCOMPARE(*qBinaryFind(data.constBegin(), data.constEnd(), resultValue), resultValue);
|
||||
QCOMPARE(*qBinaryFind(data.begin(), data.end(), resultValue), resultValue);
|
||||
QCOMPARE(*qBinaryFind(data, resultValue), resultValue);
|
||||
QCOMPARE(*qBinaryFind(data.constBegin(), data.constEnd(), resultValue, qLess<int>()), resultValue);
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::qBinaryFindOneEntry()
|
||||
{
|
||||
QList<int> list;
|
||||
list << 2;
|
||||
|
||||
QVERIFY(::qBinaryFind(list.constBegin(), list.constEnd(), 2) != list.constEnd());
|
||||
}
|
||||
|
||||
|
||||
void tst_QAlgorithms::sortAPItest()
|
||||
{
|
||||
QList<int> testList = generateData<int>("Random", 101).toList();
|
||||
qSort(testList);
|
||||
QVERIFY(isSorted(testList));
|
||||
qSort(testList.begin(), testList.end());
|
||||
QVERIFY(isSorted(testList));
|
||||
qSort(testList.begin(), testList.end(), qLess<int>());
|
||||
QVERIFY(isSorted(testList));
|
||||
|
||||
testList = generateData<int>("Random", 71).toList();
|
||||
qStableSort(testList);
|
||||
QVERIFY(isSorted(testList));
|
||||
qStableSort(testList.begin(), testList.end());
|
||||
QVERIFY(isSorted(testList));
|
||||
qStableSort(testList.begin(), testList.end(), qLess<int>());
|
||||
QVERIFY(isSorted(testList));
|
||||
}
|
||||
|
||||
|
||||
class StableSortTest
|
||||
{
|
||||
public:
|
||||
StableSortTest(){};
|
||||
StableSortTest(int Major, int Minor) : Major(Major), Minor(Minor) {}
|
||||
bool operator<(const StableSortTest &other) const {return (Major < other.Major); }
|
||||
bool testMinor(const StableSortTest &other) const {return Minor < other.Minor; }
|
||||
|
||||
int Major;
|
||||
int Minor;
|
||||
};
|
||||
|
||||
ostream &operator<<(ostream &out, const StableSortTest& obj) { out << obj.Major << "-" << obj.Minor; return out; }
|
||||
|
||||
QList<StableSortTest> createStableTestList()
|
||||
{
|
||||
QList<StableSortTest> stableTestList;
|
||||
for (int i = 500; i >= 0; --i) {
|
||||
for (int j = 0; j < 10; ++j)
|
||||
stableTestList.append(StableSortTest(i, j));
|
||||
}
|
||||
return stableTestList;
|
||||
}
|
||||
|
||||
template <typename ContainerType, typename LessThan>
|
||||
bool isStableSorted(ContainerType &container, LessThan lessThan)
|
||||
{
|
||||
for (int i=0; i < container.count() - 1; ++i) {
|
||||
//not sorted?
|
||||
if (lessThan(container.at(i + 1), container.at(i)))
|
||||
return false;
|
||||
// equal?
|
||||
if (lessThan(container.at(i), container.at(i + 1)))
|
||||
continue;
|
||||
// minor version?
|
||||
if(container.at(i + 1).testMinor(container.at(i)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::stableSortTest()
|
||||
{
|
||||
// Selftests:
|
||||
{
|
||||
QList<StableSortTest> stableTestList = createStableTestList();
|
||||
qSort(stableTestList.begin(), stableTestList.end(), qLess<StableSortTest>());
|
||||
QVERIFY(isSorted(stableTestList, qLess<StableSortTest>()));
|
||||
QVERIFY(!isStableSorted(stableTestList, qLess<StableSortTest>()));
|
||||
}
|
||||
{
|
||||
QList<StableSortTest> stableTestList = createStableTestList();
|
||||
qSort(stableTestList.begin(), stableTestList.end(), qGreater<StableSortTest>());
|
||||
QVERIFY(isSorted(stableTestList, qGreater<StableSortTest>()));
|
||||
QVERIFY(!isStableSorted(stableTestList, qGreater<StableSortTest>()));
|
||||
}
|
||||
{
|
||||
QList<StableSortTest> stableTestList = createStableTestList();
|
||||
qSort(stableTestList.begin(), stableTestList.end(), qGreater<StableSortTest>());
|
||||
QVERIFY(!isSorted(stableTestList, qLess<StableSortTest>()));
|
||||
QVERIFY(!isStableSorted(stableTestList, qGreater<StableSortTest>()));
|
||||
}
|
||||
|
||||
|
||||
// Stable sort with qLess
|
||||
{
|
||||
QList<StableSortTest> stableTestList = createStableTestList();
|
||||
std::stable_sort(stableTestList.begin(), stableTestList.end(), qLess<StableSortTest>());
|
||||
QVERIFY(isSorted(stableTestList, qLess<StableSortTest>()));
|
||||
QVERIFY(isStableSorted(stableTestList, qLess<StableSortTest>()));
|
||||
}
|
||||
{
|
||||
QList<StableSortTest> stableTestList = createStableTestList();
|
||||
qStableSort(stableTestList.begin(), stableTestList.end(), qLess<StableSortTest>());
|
||||
QVERIFY(isSorted(stableTestList, qLess<StableSortTest>()));
|
||||
QVERIFY(isStableSorted(stableTestList, qLess<StableSortTest>()));
|
||||
}
|
||||
|
||||
// Stable sort with qGreater
|
||||
{
|
||||
QList<StableSortTest> stableTestList = createStableTestList();
|
||||
std::stable_sort(stableTestList.begin(), stableTestList.end(), qGreater<StableSortTest>());
|
||||
QVERIFY(isSorted(stableTestList, qGreater<StableSortTest>()));
|
||||
QVERIFY(isStableSorted(stableTestList, qGreater<StableSortTest>()));
|
||||
}
|
||||
|
||||
{
|
||||
QList<StableSortTest> stableTestList = createStableTestList();
|
||||
qStableSort(stableTestList.begin(), stableTestList.end(), qGreater<StableSortTest>());
|
||||
QVERIFY(isSorted(stableTestList, qGreater<StableSortTest>()));
|
||||
QVERIFY(isStableSorted(stableTestList, qGreater<StableSortTest>()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tst_QAlgorithms::stableSortCorrectnessTest_data()
|
||||
{
|
||||
const int dataSize = 1000;
|
||||
QTest::addColumn<QList<int>>("unsorted");
|
||||
QTest::newRow("From documentation") << (QList<int>() << 33 << 12 << 68 << 6 << 12);
|
||||
QTest::newRow("Equal") << (generateData<int>("Equal", dataSize));
|
||||
QTest::newRow("Ascending") << (generateData<int>("Ascending", dataSize));
|
||||
QTest::newRow("Descending") << (generateData<int>("Descending", dataSize));
|
||||
QTest::newRow("Duplicates") << (generateData<int>("Duplicates", dataSize));
|
||||
QTest::newRow("Almost Sorted") << (generateData<int>("Almost Sorted", dataSize));
|
||||
QTest::newRow("Random") << (generateData<int>("Random", dataSize));
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::stableSortCorrectnessTest()
|
||||
{
|
||||
QFETCH(QList<int>, unsorted);
|
||||
|
||||
QList<int> sorted = unsorted;
|
||||
qStableSort(sorted.begin(), sorted.end());
|
||||
|
||||
// Verify that sorted contains the same numbers as unsorted.
|
||||
foreach(int value, unsorted) {
|
||||
QVERIFY(sorted.contains(value));
|
||||
int unsortedCount = 0;
|
||||
qCount(unsorted.begin(), unsorted.end(), value, unsortedCount);
|
||||
int sortedCount = 0;
|
||||
qCount(sorted.begin(), sorted.end(), value, sortedCount);
|
||||
QCOMPARE(sortedCount, unsortedCount);
|
||||
}
|
||||
|
||||
QVERIFY(isSorted(sorted));
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::convenienceAPI_deprecated()
|
||||
{
|
||||
// Compile-test for QAlgorithm convenience functions.
|
||||
QList<int> list, list2;
|
||||
|
||||
qCopy(list.begin(), list.end(), list2.begin());
|
||||
qCopyBackward(list.begin(), list.end(), list2.begin());
|
||||
qEqual(list.begin(), list.end(), list2.begin());
|
||||
|
||||
qFill(list, 1);
|
||||
qFill(list.begin(), list.end(), 1);
|
||||
|
||||
qFind(list, 1);
|
||||
qFind(list.begin(), list.end(), 1);
|
||||
|
||||
int count1 = 0 , count2 = 0, count3 = 0;
|
||||
qCount(list, 1, count1);
|
||||
qCount(list.begin(), list.end(), 1, count2);
|
||||
QCOMPARE(count1, count2);
|
||||
QCOMPARE(count2, count3);
|
||||
|
||||
qSort(list);
|
||||
qSort(list.begin(), list.end());
|
||||
qSort(list.begin(), list.end(), qLess<int>());
|
||||
|
||||
qStableSort(list);
|
||||
qStableSort(list.begin(), list.end());
|
||||
qStableSort(list.begin(), list.end(), qLess<int>());
|
||||
|
||||
qLowerBound(list, 1);;
|
||||
qLowerBound(list.begin(), list.end(), 1);
|
||||
qLowerBound(list.begin(), list.end(), 1, qLess<int>());
|
||||
|
||||
qUpperBound(list, 1);
|
||||
qUpperBound(list.begin(), list.end(), 1);
|
||||
qUpperBound(list.begin(), list.end(), 1, qLess<int>());
|
||||
|
||||
qBinaryFind(list, 1);
|
||||
qBinaryFind(list.begin(), list.end(), 1);
|
||||
qBinaryFind(list.begin(), list.end(), 1, qLess<int>());
|
||||
}
|
||||
|
||||
template <typename DataType>
|
||||
class QuickSortHelper
|
||||
{
|
||||
public:
|
||||
void operator()(QList<DataType> list)
|
||||
{
|
||||
::qSort(list);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DataType>
|
||||
class StableSortHelper
|
||||
{
|
||||
public:
|
||||
void operator()(QList<DataType> list)
|
||||
{
|
||||
::qStableSort(list);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DataType>
|
||||
class StlSortHelper
|
||||
{
|
||||
public:
|
||||
void operator()(QList<DataType> list)
|
||||
{
|
||||
std::sort(list.begin(), list.end());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DataType>
|
||||
class StlStableSortHelper
|
||||
{
|
||||
public:
|
||||
void operator()(QList<DataType> list)
|
||||
{
|
||||
std::stable_sort(list.begin(), list.end());
|
||||
}
|
||||
};
|
||||
|
||||
#if Q_TEST_PERFORMANCE
|
||||
void tst_QAlgorithms::performance()
|
||||
{
|
||||
cout << Qt::endl << "Quick sort" << Qt::endl;
|
||||
testAlgorithm<QuickSortHelper<TestInt>, TestInt>(QuickSortHelper<TestInt>(), dataSetTypes);
|
||||
cout << Qt::endl << "stable sort" << Qt::endl;
|
||||
testAlgorithm<StableSortHelper<TestInt>, TestInt>(StableSortHelper<TestInt>(), dataSetTypes);
|
||||
cout << Qt::endl << "std::sort" << Qt::endl;
|
||||
testAlgorithm<StlSortHelper<TestInt>, TestInt>(StlSortHelper<TestInt>(), dataSetTypes);
|
||||
cout << Qt::endl << "std::stable_sort" << Qt::endl;
|
||||
testAlgorithm<StlStableSortHelper<TestInt>, TestInt>(StlStableSortHelper<TestInt>(), dataSetTypes);
|
||||
/*
|
||||
cout << Qt::endl << "Sorting lists of ints" << Qt::endl;
|
||||
cout << Qt::endl << "Quick sort" << Qt::endl;
|
||||
testAlgorithm<QuickSortHelper<int>, int>(QuickSortHelper<int>(), dataSetTypes);
|
||||
cout << Qt::endl << "std::sort" << Qt::endl;
|
||||
testAlgorithm<StlSortHelper<int>, int>(StlSortHelper<int>(), dataSetTypes);
|
||||
cout << Qt::endl << "std::stable_sort" << Qt::endl;
|
||||
testAlgorithm<StlStableSortHelper<int>, int>(StlStableSortHelper<int>(), dataSetTypes);
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
void tst_QAlgorithms::qCountIterators() const
|
||||
{
|
||||
QList<int> list;
|
||||
list << 3 << 3 << 6 << 6 << 6 << 8;
|
||||
|
||||
{
|
||||
int countOf7 = 0;
|
||||
::qCount(list.begin(), list.end(), 7, countOf7);
|
||||
QCOMPARE(countOf7, 0);
|
||||
}
|
||||
|
||||
{
|
||||
int countOf3 = 0;
|
||||
::qCount(list.begin(), list.end(), 3, countOf3);
|
||||
QCOMPARE(countOf3, 2);
|
||||
}
|
||||
|
||||
{
|
||||
int countOf6 = 0;
|
||||
::qCount(list.begin(), list.end(), 6, countOf6);
|
||||
QCOMPARE(countOf6, 3);
|
||||
}
|
||||
|
||||
{
|
||||
int countOf8 = 0;
|
||||
::qCount(list.begin(), list.end(), 8, countOf8);
|
||||
QCOMPARE(countOf8, 1);
|
||||
}
|
||||
|
||||
/* Check that we add to the count, not set it. */
|
||||
{
|
||||
int countOf8 = 5;
|
||||
::qCount(list.begin(), list.end(), 8, countOf8);
|
||||
QCOMPARE(countOf8, 6);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::qCountContainer() const
|
||||
{
|
||||
QList<int> list;
|
||||
list << 3 << 3 << 6 << 6 << 6 << 8;
|
||||
|
||||
{
|
||||
int countOf7 = 0;
|
||||
::qCount(list, 7, countOf7);
|
||||
QCOMPARE(countOf7, 0);
|
||||
}
|
||||
|
||||
{
|
||||
int countOf3 = 0;
|
||||
::qCount(list, 3, countOf3);
|
||||
QCOMPARE(countOf3, 2);
|
||||
}
|
||||
|
||||
{
|
||||
int countOf6 = 0;
|
||||
::qCount(list, 6, countOf6);
|
||||
QCOMPARE(countOf6, 3);
|
||||
}
|
||||
|
||||
{
|
||||
int countOf8 = 0;
|
||||
::qCount(list, 8, countOf8);
|
||||
QCOMPARE(countOf8, 1);
|
||||
}
|
||||
|
||||
/* Check that we add to the count, not set it. */
|
||||
{
|
||||
int countOf8 = 5;
|
||||
::qCount(list, 8, countOf8);
|
||||
QCOMPARE(countOf8, 6);
|
||||
}
|
||||
}
|
||||
|
||||
class RAI
|
||||
{
|
||||
public:
|
||||
typedef int difference_type;
|
||||
typedef int value_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef int *pointer;
|
||||
typedef int &reference;
|
||||
|
||||
RAI(int searched = 5, int hidePos = 4, int len = 10)
|
||||
: curPos_(0)
|
||||
, length_(len)
|
||||
, searchedVal_(searched)
|
||||
, searchedValPos_(hidePos)
|
||||
{
|
||||
}
|
||||
|
||||
int at(int pos) const
|
||||
{
|
||||
if (pos == searchedValPos_) {
|
||||
return searchedVal_;
|
||||
}
|
||||
else if (pos < searchedValPos_) {
|
||||
return searchedVal_ - 1;
|
||||
}
|
||||
|
||||
return searchedVal_ + 1;
|
||||
}
|
||||
|
||||
RAI begin() const
|
||||
{
|
||||
RAI rai = *this;
|
||||
rai.setCurPos(0);
|
||||
return rai;
|
||||
}
|
||||
|
||||
RAI end() const
|
||||
{
|
||||
RAI rai = *this;
|
||||
rai.setCurPos(length_);
|
||||
return rai;
|
||||
}
|
||||
|
||||
int pos() const
|
||||
{
|
||||
return curPos();
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return length_;
|
||||
}
|
||||
|
||||
RAI operator+(int i) const
|
||||
{
|
||||
RAI rai = *this;
|
||||
rai.setCurPos( rai.curPos() + i );
|
||||
if (rai.curPos() > length_) {
|
||||
rai.setCurPos(length_);
|
||||
}
|
||||
return rai;
|
||||
}
|
||||
|
||||
RAI operator-(int i) const
|
||||
{
|
||||
RAI rai = *this;
|
||||
rai.setCurPos( rai.curPos() - i );
|
||||
if (rai.curPos() < 0) {
|
||||
rai.setCurPos(0);
|
||||
}
|
||||
return rai;
|
||||
}
|
||||
|
||||
int operator-(const RAI& it) const
|
||||
{
|
||||
return curPos() - it.curPos();
|
||||
}
|
||||
|
||||
RAI& operator+=(int i)
|
||||
{
|
||||
setCurPos( curPos() + i );
|
||||
if (curPos() > length_) {
|
||||
setCurPos(length_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
RAI& operator-=(int i)
|
||||
{
|
||||
setCurPos( curPos() - i);
|
||||
if (curPos() < 0) {
|
||||
setCurPos(0);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
RAI& operator++()
|
||||
{
|
||||
if (curPos() < length_) {
|
||||
setCurPos( curPos() + 1 );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
RAI operator++(int)
|
||||
{
|
||||
RAI rai = *this;
|
||||
|
||||
if (curPos() < length_) {
|
||||
setCurPos( curPos() + 1 );
|
||||
}
|
||||
|
||||
return rai;
|
||||
}
|
||||
|
||||
RAI& operator--()
|
||||
{
|
||||
if (curPos() > 0) {
|
||||
setCurPos( curPos() - 1 );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
RAI operator--(int)
|
||||
{
|
||||
RAI rai = *this;
|
||||
|
||||
if (curPos() > 0) {
|
||||
setCurPos( curPos() - 1 );
|
||||
}
|
||||
|
||||
return rai;
|
||||
}
|
||||
|
||||
bool operator==(const RAI& rai) const
|
||||
{
|
||||
return rai.curPos() == curPos();
|
||||
}
|
||||
|
||||
bool operator!=(const RAI& rai) const
|
||||
{
|
||||
return !operator==(rai);
|
||||
}
|
||||
|
||||
int operator*() const
|
||||
{
|
||||
return at(curPos());
|
||||
}
|
||||
|
||||
int operator[](int i) const
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int curPos() const
|
||||
{
|
||||
return curPos_;
|
||||
}
|
||||
|
||||
void setCurPos(int pos)
|
||||
{
|
||||
curPos_ = pos;
|
||||
}
|
||||
|
||||
int curPos_;
|
||||
int length_;
|
||||
int searchedVal_;
|
||||
int searchedValPos_;
|
||||
};
|
||||
|
||||
void tst_QAlgorithms::binaryFindOnLargeContainer() const
|
||||
{
|
||||
const int len = 2 * 1000 * 1000 * 537;
|
||||
const int pos = len - 12345;
|
||||
RAI rai(5, pos, len);
|
||||
|
||||
RAI foundIt = qBinaryFind(rai.begin(), rai.end(), 5);
|
||||
QCOMPARE(foundIt.pos(), 1073987655);
|
||||
}
|
||||
|
||||
#endif // QT_DEPRECATED_SINCE(5, 2)
|
||||
|
||||
// alternative implementation of qPopulationCount for comparison:
|
||||
static constexpr const uint bitsSetInNibble[] = {
|
||||
0, 1, 1, 2, 1, 2, 2, 3,
|
||||
|
@ -10,4 +10,3 @@ add_subdirectory(qrect)
|
||||
add_subdirectory(qringbuffer)
|
||||
add_subdirectory(qstack)
|
||||
add_subdirectory(qvector)
|
||||
add_subdirectory(qalgorithms)
|
||||
|
@ -1 +0,0 @@
|
||||
tst_qalgorithms
|
@ -1,12 +0,0 @@
|
||||
# Generated from qalgorithms.pro.
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_qalgorithms Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_add_benchmark(tst_bench_qalgorithms
|
||||
SOURCES
|
||||
tst_qalgorithms.cpp
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Test
|
||||
)
|
@ -1,5 +0,0 @@
|
||||
CONFIG += benchmark
|
||||
QT = core testlib
|
||||
|
||||
TARGET = tst_bench_qalgorithms
|
||||
SOURCES = tst_qalgorithms.cpp
|
@ -1,127 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2012 Robin Burchell <robin+qt@viroteck.net>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <qalgorithms.h>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class tst_QAlgorithms : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void stableSort_data();
|
||||
void stableSort();
|
||||
|
||||
void sort_data();
|
||||
void sort();
|
||||
};
|
||||
|
||||
template<typename DataType>
|
||||
QList<DataType> generateData(QString dataSetType, const int length)
|
||||
{
|
||||
QList<DataType> container;
|
||||
if (dataSetType == "Random") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(QRandomGenerator::global()->generate());
|
||||
} else if (dataSetType == "Ascending") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(i);
|
||||
} else if (dataSetType == "Descending") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(length - i);
|
||||
} else if (dataSetType == "Equal") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(43);
|
||||
} else if (dataSetType == "Duplicates") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(i % 10);
|
||||
} else if (dataSetType == "Almost Sorted") {
|
||||
for (int i = 0; i < length; ++i)
|
||||
container.append(i);
|
||||
for (int i = 0; i<= length / 10; ++i) {
|
||||
const int iswap = i * 9;
|
||||
DataType tmp = container.at(iswap);
|
||||
container[iswap] = container.at(iswap + 1);
|
||||
container[iswap + 1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
|
||||
void tst_QAlgorithms::stableSort_data()
|
||||
{
|
||||
const int dataSize = 5000;
|
||||
QTest::addColumn<QList<int>>("unsorted");
|
||||
QTest::newRow("Equal") << (generateData<int>("Equal", dataSize));
|
||||
QTest::newRow("Ascending") << (generateData<int>("Ascending", dataSize));
|
||||
QTest::newRow("Descending") << (generateData<int>("Descending", dataSize));
|
||||
QTest::newRow("Duplicates") << (generateData<int>("Duplicates", dataSize));
|
||||
QTest::newRow("Almost Sorted") << (generateData<int>("Almost Sorted", dataSize));
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::stableSort()
|
||||
{
|
||||
QFETCH(QList<int>, unsorted);
|
||||
|
||||
QBENCHMARK {
|
||||
QList<int> sorted = unsorted;
|
||||
qStableSort(sorted.begin(), sorted.end());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::sort_data()
|
||||
{
|
||||
stableSort_data();
|
||||
}
|
||||
|
||||
void tst_QAlgorithms::sort()
|
||||
{
|
||||
QFETCH(QList<int>, unsorted);
|
||||
|
||||
QBENCHMARK {
|
||||
QList<int> sorted = unsorted;
|
||||
qSort(sorted.begin(), sorted.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_QAlgorithms)
|
||||
#include "tst_qalgorithms.moc"
|
||||
|
@ -9,5 +9,4 @@ SUBDIRS = \
|
||||
qrect \
|
||||
qringbuffer \
|
||||
qstack \
|
||||
qvector \
|
||||
qalgorithms
|
||||
qvector
|
||||
|
Loading…
Reference in New Issue
Block a user