blob: 8a545712a24a7acbcdd9cd462cc650fb6d477d07 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** 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$
**
****************************************************************************/
//#define QT_STRICT_ITERATORS
#include <QtTest/QtTest>
#include <qset.h>
#include <qdebug.h>
int toNumber(const QString &str)
{
int res = 0;
for (int i = 0; i < str.length(); ++i)
res = (res * 10) + str[i].digitValue();
return res;
}
class tst_QSet : public QObject
{
Q_OBJECT
private slots:
void operator_eq();
void swap();
void size();
void capacity();
void reserve();
void squeeze();
void detach();
void isDetached();
void clear();
void cpp17ctad();
void remove();
void contains();
void containsSet();
void begin();
void end();
void insert();
void reverseIterators();
void setOperations();
void stlIterator();
void stlMutableIterator();
void javaIterator();
void javaMutableIterator();
void makeSureTheComfortFunctionsCompile();
void initializerList();
void qhash();
void intersects();
};
struct IdentityTracker {
int value, id;
};
inline uint qHash(IdentityTracker key) { return qHash(key.value); }
inline bool operator==(IdentityTracker lhs, IdentityTracker rhs) { return lhs.value == rhs.value; }
void tst_QSet::operator_eq()
{
{
QSet<int> set1, set2;
QVERIFY(set1 == set2);
QVERIFY(!(set1 != set2));
set1.insert(1);
QVERIFY(set1 != set2);
QVERIFY(!(set1 == set2));
set2.insert(1);
QVERIFY(set1 == set2);
QVERIFY(!(set1 != set2));
set2.insert(1);
QVERIFY(set1 == set2);
QVERIFY(!(set1 != set2));
set1.insert(2);
QVERIFY(set1 != set2);
QVERIFY(!(set1 == set2));
}
{
QSet<QString> set1, set2;
QVERIFY(set1 == set2);
QVERIFY(!(set1 != set2));
set1.insert("one");
QVERIFY(set1 != set2);
QVERIFY(!(set1 == set2));
set2.insert("one");
QVERIFY(set1 == set2);
QVERIFY(!(set1 != set2));
set2.insert("one");
QVERIFY(set1 == set2);
QVERIFY(!(set1 != set2));
set1.insert("two");
QVERIFY(set1 != set2);
QVERIFY(!(set1 == set2));
}
{
QSet<QString> a;
QSet<QString> b;
a += "otto";
b += "willy";
QVERIFY(a != b);
QVERIFY(!(a == b));
}
{
QSet<int> s1, s2;
s1.reserve(100);
s2.reserve(4);
QVERIFY(s1 == s2);
s1 << 100 << 200 << 300 << 400;
s2 << 400 << 300 << 200 << 100;
QVERIFY(s1 == s2);
}
}
void tst_QSet::swap()
{
QSet<int> s1, s2;
s1.insert(1);
s2.insert(2);
s1.swap(s2);
QCOMPARE(*s1.begin(),2);
QCOMPARE(*s2.begin(),1);
}
void tst_QSet::size()
{
QSet<int> set;
QVERIFY(set.size() == 0);
QVERIFY(set.isEmpty());
QVERIFY(set.count() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.insert(1);
QVERIFY(set.size() == 1);
QVERIFY(!set.isEmpty());
QVERIFY(set.count() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.insert(1);
QVERIFY(set.size() == 1);
QVERIFY(!set.isEmpty());
QVERIFY(set.count() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.insert(2);
QVERIFY(set.size() == 2);
QVERIFY(!set.isEmpty());
QVERIFY(set.count() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.remove(1);
QVERIFY(set.size() == 1);
QVERIFY(!set.isEmpty());
QVERIFY(set.count() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.remove(1);
QVERIFY(set.size() == 1);
QVERIFY(!set.isEmpty());
QVERIFY(set.count() == set.size());
QVERIFY(set.isEmpty() == set.empty());
set.remove(2);
QVERIFY(set.size() == 0);
QVERIFY(set.isEmpty());
QVERIFY(set.count() == set.size());
QVERIFY(set.isEmpty() == set.empty());
}
void tst_QSet::capacity()
{
QSet<int> set;
int n = set.capacity();
QVERIFY(n == 0);
for (int i = 0; i < 1000; ++i) {
set.insert(i);
QVERIFY(set.capacity() >= set.size());
}
}
void tst_QSet::reserve()
{
QSet<int> set;
int n = set.capacity();
QVERIFY(n == 0);
set.reserve(1000);
QVERIFY(set.capacity() >= 1000);
for (int i = 0; i < 500; ++i)
set.insert(i);
QVERIFY(set.capacity() >= 1000);
for (int j = 0; j < 500; ++j)
set.remove(j);
QVERIFY(set.capacity() >= 1000);
set.clear();
QVERIFY(set.capacity() == 0);
}
void tst_QSet::squeeze()
{
QSet<int> set;
int n = set.capacity();
QVERIFY(n == 0);
set.reserve(1000);
QVERIFY(set.capacity() >= 1000);
set.squeeze();
QVERIFY(set.capacity() < 100);
for (int i = 0; i < 500; ++i)
set.insert(i);
QVERIFY(set.capacity() >= 500 && set.capacity() < 10000);
set.reserve(50000);
QVERIFY(set.capacity() >= 50000);
set.squeeze();
QVERIFY(set.capacity() < 500);
set.remove(499);
QVERIFY(set.capacity() < 500);
set.insert(499);
QVERIFY(set.capacity() >= 500);
for (int i = 0; i < 500; ++i)
set.remove(i);
set.squeeze();
QVERIFY(set.capacity() < 100);
}
void tst_QSet::detach()
{
QSet<int> set;
set.detach();
set.insert(1);
set.insert(2);
set.detach();
QSet<int> copy = set;
set.detach();
}
void tst_QSet::isDetached()
{
QSet<int> set1, set2;
QVERIFY(!set1.isDetached()); // shared_null
QVERIFY(!set2.isDetached()); // shared_null
set1.insert(1);
QVERIFY(set1.isDetached());
QVERIFY(!set2.isDetached()); // shared_null
set2 = set1;
QVERIFY(!set1.isDetached());
QVERIFY(!set2.isDetached());
set1.detach();
QVERIFY(set1.isDetached());
QVERIFY(set2.isDetached());
}
void tst_QSet::clear()
{
QSet<QString> set1, set2;
QVERIFY(set1.size() == 0);
set1.clear();
QVERIFY(set1.size() == 0);
set1.insert("foo");
QVERIFY(set1.size() != 0);
set2 = set1;
set1.clear();
QVERIFY(set1.size() == 0);
QVERIFY(set2.size() != 0);
set2.clear();
QVERIFY(set1.size() == 0);
QVERIFY(set2.size() == 0);
}
void tst_QSet::cpp17ctad()
{
#ifdef __cpp_deduction_guides
#define QVERIFY_IS_SET_OF(obj, Type) \
QVERIFY2((std::is_same<decltype(obj), QSet<Type>>::value), \
QMetaType::typeName(qMetaTypeId<decltype(obj)::value_type>()))
#define CHECK(Type, One, Two, Three) \
do { \
const Type v[] = {One, Two, Three}; \
QSet v1 = {One, Two, Three}; \
QVERIFY_IS_SET_OF(v1, Type); \
QSet v2(v1.begin(), v1.end()); \
QVERIFY_IS_SET_OF(v2, Type); \
QSet v3(std::begin(v), std::end(v)); \
QVERIFY_IS_SET_OF(v3, Type); \
} while (false) \
/*end*/
CHECK(int, 1, 2, 3);
CHECK(double, 1.0, 2.0, 3.0);
CHECK(QString, QStringLiteral("one"), QStringLiteral("two"), QStringLiteral("three"));
#undef QVERIFY_IS_SET_OF
#undef CHECK
#else
QSKIP("This test requires C++17 Constructor Template Argument Deduction support enabled in the compiler.");
#endif
}
void tst_QSet::remove()
{
QSet<QString> set1;
for (int i = 0; i < 500; ++i)
set1.insert(QString::number(i));
QCOMPARE(set1.size(), 500);
for (int j = 0; j < 500; ++j) {
set1.remove(QString::number((j * 17) % 500));
QCOMPARE(set1.size(), 500 - j - 1);
}
}
void tst_QSet::contains()
{
QSet<QString> set1;
for (int i = 0; i < 500; ++i) {
QVERIFY(!set1.contains(QString::number(i)));
set1.insert(QString::number(i));
QVERIFY(set1.contains(QString::number(i)));
}
QCOMPARE(set1.size(), 500);
for (int j = 0; j < 500; ++j) {
int i = (j * 17) % 500;
QVERIFY(set1.contains(QString::number(i)));
set1.remove(QString::number(i));
QVERIFY(!set1.contains(QString::number(i)));
}
}
void tst_QSet::containsSet()
{
QSet<QString> set1;
QSet<QString> set2;
// empty set contains the empty set
QVERIFY(set1.contains(set2));
for (int i = 0; i < 500; ++i) {
set1.insert(QString::number(i));
set2.insert(QString::number(i));
}
QVERIFY(set1.contains(set2));
set2.remove(QString::number(19));
set2.remove(QString::number(82));
set2.remove(QString::number(7));
QVERIFY(set1.contains(set2));
set1.remove(QString::number(23));
QVERIFY(!set1.contains(set2));
// filled set contains the empty set as well
QSet<QString> set3;
QVERIFY(set1.contains(set3));
// the empty set doesn't contain a filled set
QVERIFY(!set3.contains(set1));
// verify const signature
const QSet<QString> set4;
QVERIFY(set3.contains(set4));
}
void tst_QSet::begin()
{
QSet<int> set1;
QSet<int> set2 = set1;
{
QSet<int>::const_iterator i = set1.constBegin();
QSet<int>::const_iterator j = set1.cbegin();
QSet<int>::const_iterator k = set2.constBegin();
QSet<int>::const_iterator ell = set2.cbegin();
QVERIFY(i == j);
QVERIFY(k == ell);
QVERIFY(i == k);
QVERIFY(j == ell);
}
set1.insert(44);
{
QSet<int>::const_iterator i = set1.constBegin();
QSet<int>::const_iterator j = set1.cbegin();
QSet<int>::const_iterator k = set2.constBegin();
QSet<int>::const_iterator ell = set2.cbegin();
QVERIFY(i == j);
QVERIFY(k == ell);
QVERIFY(i != k);
QVERIFY(j != ell);
}
set2 = set1;
{
QSet<int>::const_iterator i = set1.constBegin();
QSet<int>::const_iterator j = set1.cbegin();
QSet<int>::const_iterator k = set2.constBegin();
QSet<int>::const_iterator ell = set2.cbegin();
QVERIFY(i == j);
QVERIFY(k == ell);
QVERIFY(i == k);
QVERIFY(j == ell);
}
}
void tst_QSet::end()
{
QSet<int> set1;
QSet<int> set2 = set1;
{
QSet<int>::const_iterator i = set1.constEnd();
QSet<int>::const_iterator j = set1.cend();
QSet<int>::const_iterator k = set2.constEnd();
QSet<int>::const_iterator ell = set2.cend();
QVERIFY(i == j);
QVERIFY(k == ell);
QVERIFY(i == k);
QVERIFY(j == ell);
QVERIFY(set1.constBegin() == set1.constEnd());
QVERIFY(set2.constBegin() == set2.constEnd());
}
set1.insert(44);
{
QSet<int>::const_iterator i = set1.constEnd();
QSet<int>::const_iterator j = set1.cend();
QSet<int>::const_iterator k = set2.constEnd();
QSet<int>::const_iterator ell = set2.cend();
QVERIFY(i == j);
QVERIFY(k == ell);
QVERIFY(i != k);
QVERIFY(j != ell);
QVERIFY(set1.constBegin() != set1.constEnd());
QVERIFY(set2.constBegin() == set2.constEnd());
}
set2 = set1;
{
QSet<int>::const_iterator i = set1.constEnd();
QSet<int>::const_iterator j = set1.cend();
QSet<int>::const_iterator k = set2.constEnd();
QSet<int>::const_iterator ell = set2.cend();
QVERIFY(i == j);
QVERIFY(k == ell);
QVERIFY(i == k);
QVERIFY(j == ell);
QVERIFY(set1.constBegin() != set1.constEnd());
QVERIFY(set2.constBegin() != set2.constEnd());
}
set1.clear();
set2.clear();
QVERIFY(set1.constBegin() == set1.constEnd());
QVERIFY(set2.constBegin() == set2.constEnd());
}
void tst_QSet::insert()
{
{
QSet<int> set1;
QVERIFY(set1.size() == 0);
set1.insert(1);
QVERIFY(set1.size() == 1);
set1.insert(2);
QVERIFY(set1.size() == 2);
set1.insert(2);
QVERIFY(set1.size() == 2);
QVERIFY(set1.contains(2));
set1.remove(2);
QVERIFY(set1.size() == 1);
QVERIFY(!set1.contains(2));
set1.insert(2);
QVERIFY(set1.size() == 2);
QVERIFY(set1.contains(2));
}
{
QSet<int> set1;
QVERIFY(set1.size() == 0);
set1 << 1;
QVERIFY(set1.size() == 1);
set1 << 2;
QVERIFY(set1.size() == 2);
set1 << 2;
QVERIFY(set1.size() == 2);
QVERIFY(set1.contains(2));
set1.remove(2);
QVERIFY(set1.size() == 1);
QVERIFY(!set1.contains(2));
set1 << 2;
QVERIFY(set1.size() == 2);
QVERIFY(set1.contains(2));
}
{
QSet<IdentityTracker> set;
QCOMPARE(set.size(), 0);
const int dummy = -1;
IdentityTracker id00 = {0, 0}, id01 = {0, 1}, searchKey = {0, dummy};
QCOMPARE(set.insert(id00)->id, id00.id);
QCOMPARE(set.size(), 1);
QCOMPARE(set.insert(id01)->id, id00.id); // first inserted is kept
QCOMPARE(set.size(), 1);
QCOMPARE(set.find(searchKey)->id, id00.id);
}
}
void tst_QSet::reverseIterators()
{
QSet<int> s;
s << 1 << 17 << 61 << 127 << 911;
std::vector<int> v(s.begin(), s.end());
std::reverse(v.begin(), v.end());
const QSet<int> &cs = s;
QVERIFY(std::equal(v.begin(), v.end(), s.rbegin()));
QVERIFY(std::equal(v.begin(), v.end(), s.crbegin()));
QVERIFY(std::equal(v.begin(), v.end(), cs.rbegin()));
QVERIFY(std::equal(s.rbegin(), s.rend(), v.begin()));
QVERIFY(std::equal(s.crbegin(), s.crend(), v.begin()));
QVERIFY(std::equal(cs.rbegin(), cs.rend(), v.begin()));
}
void tst_QSet::setOperations()
{
QSet<QString> set1, set2;
set1 << "alpha" << "beta" << "gamma" << "delta" << "zeta" << "omega";
set2 << "beta" << "gamma" << "delta" << "epsilon" << "iota" << "omega";
QSet<QString> set3 = set1;
set3.unite(set2);
QVERIFY(set3.size() == 8);
QVERIFY(set3.contains("alpha"));
QVERIFY(set3.contains("beta"));
QVERIFY(set3.contains("gamma"));
QVERIFY(set3.contains("delta"));
QVERIFY(set3.contains("epsilon"));
QVERIFY(set3.contains("zeta"));
QVERIFY(set3.contains("iota"));
QVERIFY(set3.contains("omega"));
QSet<QString> set4 = set2;
set4.unite(set1);
QVERIFY(set4.size() == 8);
QVERIFY(set4.contains("alpha"));
QVERIFY(set4.contains("beta"));
QVERIFY(set4.contains("gamma"));
QVERIFY(set4.contains("delta"));
QVERIFY(set4.contains("epsilon"));
QVERIFY(set4.contains("zeta"));
QVERIFY(set4.contains("iota"));
QVERIFY(set4.contains("omega"));
QVERIFY(set3 == set4);
QSet<QString> set5 = set1;
set5.intersect(set2);
QVERIFY(set5.size() == 4);
QVERIFY(set5.contains("beta"));
QVERIFY(set5.contains("gamma"));
QVERIFY(set5.contains("delta"));
QVERIFY(set5.contains("omega"));
QSet<QString> set6 = set2;
set6.intersect(set1);
QVERIFY(set6.size() == 4);
QVERIFY(set6.contains("beta"));
QVERIFY(set6.contains("gamma"));
QVERIFY(set6.contains("delta"));
QVERIFY(set6.contains("omega"));
QVERIFY(set5 == set6);
QSet<QString> set7 = set1;
set7.subtract(set2);
QVERIFY(set7.size() == 2);
QVERIFY(set7.contains("alpha"));
QVERIFY(set7.contains("zeta"));
QSet<QString> set8 = set2;
set8.subtract(set1);
QVERIFY(set8.size() == 2);
QVERIFY(set8.contains("epsilon"));
QVERIFY(set8.contains("iota"));
QSet<QString> set9 = set1 | set2;
QVERIFY(set9 == set3);
QSet<QString> set10 = set1 & set2;
QVERIFY(set10 == set5);
QSet<QString> set11 = set1 + set2;
QVERIFY(set11 == set3);
QSet<QString> set12 = set1 - set2;
QVERIFY(set12 == set7);
QSet<QString> set13 = set2 - set1;
QVERIFY(set13 == set8);
QSet<QString> set14 = set1;
set14 |= set2;
QVERIFY(set14 == set3);
QSet<QString> set15 = set1;
set15 &= set2;
QVERIFY(set15 == set5);
QSet<QString> set16 = set1;
set16 += set2;
QVERIFY(set16 == set3);
QSet<QString> set17 = set1;
set17 -= set2;
QVERIFY(set17 == set7);
QSet<QString> set18 = set2;
set18 -= set1;
QVERIFY(set18 == set8);
}
void tst_QSet::stlIterator()
{
QSet<QString> set1;
for (int i = 0; i < 25000; ++i)
set1.insert(QString::number(i));
{
int sum = 0;
QSet<QString>::const_iterator i = set1.begin();
while (i != set1.end()) {
sum += toNumber(*i);
++i;
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QSet<QString>::const_iterator i = set1.end();
while (i != set1.begin()) {
--i;
sum += toNumber(*i);
}
QVERIFY(sum == 24999 * 25000 / 2);
}
}
void tst_QSet::stlMutableIterator()
{
QSet<QString> set1;
for (int i = 0; i < 25000; ++i)
set1.insert(QString::number(i));
{
int sum = 0;
QSet<QString>::iterator i = set1.begin();
while (i != set1.end()) {
sum += toNumber(*i);
++i;
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QSet<QString>::iterator i = set1.end();
while (i != set1.begin()) {
--i;
sum += toNumber(*i);
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
QSet<QString> set2 = set1;
QSet<QString> set3 = set2;
QSet<QString>::iterator i = set2.begin();
QSet<QString>::iterator j = set3.begin();
while (i != set2.end()) {
i = set2.erase(i);
}
QVERIFY(set2.isEmpty());
QVERIFY(!set3.isEmpty());
j = set3.end();
while (j != set3.begin()) {
j--;
if (j + 1 != set3.end())
set3.erase(j + 1);
}
if (set3.begin() != set3.end())
set3.erase(set3.begin());
QVERIFY(set2.isEmpty());
QVERIFY(set3.isEmpty());
// #if QT_VERSION >= 0x050000
// i = set2.insert("foo");
// #else
QSet<QString>::const_iterator k = set2.insert("foo");
i = reinterpret_cast<QSet<QString>::iterator &>(k);
// #endif
QCOMPARE(*i, QLatin1String("foo"));
}
}
void tst_QSet::javaIterator()
{
QSet<QString> set1;
for (int k = 0; k < 25000; ++k)
set1.insert(QString::number(k));
{
int sum = 0;
QSetIterator<QString> i(set1);
while (i.hasNext())
sum += toNumber(i.next());
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QSetIterator<QString> i(set1);
while (i.hasNext()) {
sum += toNumber(i.peekNext());
i.next();
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QSetIterator<QString> i(set1);
while (i.hasNext()) {
i.next();
sum += toNumber(i.peekPrevious());
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QSetIterator<QString> i(set1);
i.toBack();
while (i.hasPrevious())
sum += toNumber(i.previous());
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QSetIterator<QString> i(set1);
i.toBack();
while (i.hasPrevious()) {
sum += toNumber(i.peekPrevious());
i.previous();
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QSetIterator<QString> i(set1);
i.toBack();
while (i.hasPrevious()) {
i.previous();
sum += toNumber(i.peekNext());
}
QVERIFY(sum == 24999 * 25000 / 2);
}
int sum1 = 0;
int sum2 = 0;
QSetIterator<QString> i(set1);
QSetIterator<QString> j(set1);
int n = 0;
while (i.hasNext()) {
QVERIFY(j.hasNext());
set1.remove(i.peekNext());
sum1 += toNumber(i.next());
sum2 += toNumber(j.next());
++n;
}
QVERIFY(!j.hasNext());
QVERIFY(sum1 == 24999 * 25000 / 2);
QVERIFY(sum2 == sum1);
QVERIFY(set1.isEmpty());
}
void tst_QSet::javaMutableIterator()
{
QSet<QString> set1;
for (int k = 0; k < 25000; ++k)
set1.insert(QString::number(k));
{
int sum = 0;
QMutableSetIterator<QString> i(set1);
while (i.hasNext())
sum += toNumber(i.next());
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QMutableSetIterator<QString> i(set1);
while (i.hasNext()) {
i.next();
sum += toNumber(i.value());
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QMutableSetIterator<QString> i(set1);
while (i.hasNext()) {
sum += toNumber(i.peekNext());
i.next();
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QMutableSetIterator<QString> i(set1);
while (i.hasNext()) {
i.next();
sum += toNumber(i.peekPrevious());
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QMutableSetIterator<QString> i(set1);
i.toBack();
while (i.hasPrevious())
sum += toNumber(i.previous());
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QMutableSetIterator<QString> i(set1);
i.toBack();
while (i.hasPrevious()) {
sum += toNumber(i.peekPrevious());
i.previous();
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
int sum = 0;
QMutableSetIterator<QString> i(set1);
i.toBack();
while (i.hasPrevious()) {
i.previous();
sum += toNumber(i.peekNext());
}
QVERIFY(sum == 24999 * 25000 / 2);
}
{
QSet<QString> set2 = set1;
QSet<QString> set3 = set2;
QMutableSetIterator<QString> i(set2);
QMutableSetIterator<QString> j(set3);
while (i.hasNext()) {
i.next();
i.remove();
}
QVERIFY(set2.isEmpty());
QVERIFY(!set3.isEmpty());
j.toBack();
while (j.hasPrevious()) {
j.previous();
j.remove();
}
QVERIFY(set2.isEmpty());
QVERIFY(set3.isEmpty());
}
}
void tst_QSet::makeSureTheComfortFunctionsCompile()
{
QSet<int> set1, set2, set3;
set1 << 5;
set1 |= set2;
set1 |= 5;
set1 &= set2;
set1 &= 5;
set1 += set2;
set1 += 5;
set1 -= set2;
set1 -= 5;
set1 = set2 | set3;
set1 = set2 & set3;
set1 = set2 + set3;
set1 = set2 - set3;
}
void tst_QSet::initializerList()
{
QSet<int> set = {1, 1, 2, 3, 4, 5};
QCOMPARE(set.count(), 5);
QVERIFY(set.contains(1));
QVERIFY(set.contains(2));
QVERIFY(set.contains(3));
QVERIFY(set.contains(4));
QVERIFY(set.contains(5));
// check _which_ of the equal elements gets inserted (in the QHash/QMap case, it's the last):
const QSet<IdentityTracker> set2 = {{1, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}};
QCOMPARE(set2.count(), 5);
const int dummy = -1;
const IdentityTracker searchKey = {1, dummy};
QCOMPARE(set2.find(searchKey)->id, 0);
QSet<int> emptySet{};
QVERIFY(emptySet.isEmpty());
QSet<int> set3{{}, {}, {}};
QVERIFY(!set3.isEmpty());
}
void tst_QSet::qhash()
{
//
// check that sets containing the same elements hash to the same value
//
{
// create some deterministic initial state:
qSetGlobalQHashSeed(0);
QSet<int> s1;
s1.reserve(4);
s1 << 400 << 300 << 200 << 100;
// also change the seed:
qSetGlobalQHashSeed(0x10101010);
QSet<int> s2;
s2.reserve(100); // provoke different bucket counts
s2 << 100 << 200 << 300 << 400; // and insert elements in different order, too
QVERIFY(s1.capacity() != s2.capacity());
QCOMPARE(s1, s2);
QVERIFY(!std::equal(s1.cbegin(), s1.cend(), s2.cbegin())); // verify that the order _is_ different
QCOMPARE(qHash(s1), qHash(s2));
}
//
// check that sets of sets work:
//
{
QSet<QSet<int> > intSetSet = { { 0, 1, 2 }, { 0, 1 }, { 1, 2 } };
QCOMPARE(intSetSet.size(), 3);
}
}
void tst_QSet::intersects()
{
QSet<int> s1;
QSet<int> s2;
QVERIFY(!s1.intersects(s1));
QVERIFY(!s1.intersects(s2));
s1 << 100;
QVERIFY(s1.intersects(s1));
QVERIFY(!s1.intersects(s2));
s2 << 200;
QVERIFY(!s1.intersects(s2));
s1 << 200;
QVERIFY(s1.intersects(s2));
qSetGlobalQHashSeed(0x10101010);
QSet<int> s3;
s3 << 500;
QVERIFY(!s1.intersects(s3));
s3 << 200;
QVERIFY(s1.intersects(s3));
}
QTEST_APPLESS_MAIN(tst_QSet)
#include "tst_qset.moc"