summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp')
-rw-r--r--tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp172
1 files changed, 113 insertions, 59 deletions
diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
index 0c453cd0e5..a32045bbbb 100644
--- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
+++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp
@@ -1,32 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** 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>
+// Copyright (C) 2017 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
#include <qlist.h>
#include <qobject.h>
#include <qrandom.h>
@@ -39,7 +14,6 @@
# define HAVE_FALLBACK_ENGINE
#endif
-#define COMMA ,
#define QVERIFY_3TIMES(statement) \
do {\
if (!static_cast<bool>(statement))\
@@ -102,6 +76,10 @@ private slots:
void bounded();
void boundedQuality_data() { generate32_data(); }
void boundedQuality();
+ void bounded64_data();
+ void bounded64();
+ void bounded64Quality_data() { generate32_data(); }
+ void bounded64Quality();
void generateReal_data() { generate32_data(); }
void generateReal();
@@ -150,6 +128,9 @@ void tst_QRandomGenerator::basics()
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wself-move")
QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
+#if defined(Q_CC_GNU_ONLY) && Q_CC_GNU >= 1301
+QT_WARNING_DISABLE_GCC("-Wself-move")
+#endif
// copyable && movable
rng = rng;
rng = std::move(rng);
@@ -186,8 +167,8 @@ QT_WARNING_POP
QRandomGenerator64 systemRng64 = *system64;
systemRng64 = *system64;
- static_assert(std::is_same<decltype(rng64.generate()) COMMA quint64>::value);
- static_assert(std::is_same<decltype(system64->generate()) COMMA quint64>::value);
+ static_assert(std::is_same_v<decltype(rng64.generate()), quint64>);
+ static_assert(std::is_same_v<decltype(system64->generate()), quint64>);
}
void tst_QRandomGenerator::knownSequence()
@@ -567,7 +548,7 @@ void tst_QRandomGenerator::bounded()
QVERIFY(value < sup);
QCOMPARE(value, expected);
- int ivalue = rng.bounded(sup);
+ int ivalue = rng.bounded(int(sup));
QVERIFY(ivalue < int(sup));
QCOMPARE(ivalue, int(expected));
@@ -590,10 +571,11 @@ void tst_QRandomGenerator::bounded()
QVERIFY(ivalue < 0);
}
-void tst_QRandomGenerator::boundedQuality()
+template <typename UInt> static void boundedQuality_template()
{
- enum { Bound = 283 }; // a prime number
- enum {
+ using Int = std::make_signed_t<UInt>;
+ constexpr Int Bound = 283; // a prime number
+ enum : Int {
BufferCount = Bound * 32,
// if the distribution were perfect, each byte in the buffer would
@@ -625,10 +607,13 @@ void tst_QRandomGenerator::boundedQuality()
{
// test the quality of the generator
- QList<quint32> buffer(BufferCount, 0xcdcdcdcd);
+ UInt filler = 0xcdcdcdcd;
+ if (sizeof(filler) > sizeof(quint32))
+ filler |= filler << (std::numeric_limits<UInt>::digits / 2);
+ QVector<UInt> buffer(BufferCount, filler);
generate(buffer.begin(), buffer.end(), [&] { return rng.bounded(Bound); });
- for (quint32 value : qAsConst(buffer)) {
+ for (UInt value : std::as_const(buffer)) {
QVERIFY(value < Bound);
histogram[value]++;
}
@@ -649,6 +634,75 @@ void tst_QRandomGenerator::boundedQuality()
<< "at" << std::min_element(begin(histogram), end(histogram)) - histogram;
}
+void tst_QRandomGenerator::boundedQuality()
+{
+ boundedQuality_template<quint32>();
+}
+
+void tst_QRandomGenerator::bounded64Quality()
+{
+ boundedQuality_template<quint64>();
+}
+
+void tst_QRandomGenerator::bounded64_data()
+{
+#ifndef QT_BUILD_INTERNAL
+ QSKIP("Test only possible in developer builds");
+#endif
+
+ QTest::addColumn<uint>("control");
+ QTest::addColumn<quint64>("sup");
+ QTest::addColumn<quint64>("expected");
+
+ auto newRow = [&](unsigned val, unsigned sup) {
+ Q_ASSERT((val & ~RandomDataMask) == 0);
+
+ unsigned control = SetRandomData | val;
+ QTest::addRow("%u,%u", val, sup) << control << quint64(sup) << quint64(val);
+ };
+
+ // useless: we can only generate zeroes:
+ newRow(0, 1);
+
+ newRow(0x10, 200);
+ newRow(0x20, 200);
+ newRow(0x80, 200);
+}
+
+void tst_QRandomGenerator::bounded64()
+{
+ QFETCH(uint, control);
+ QFETCH(quint64, sup);
+ QFETCH(quint64, expected);
+ RandomGenerator rng(control);
+
+ quint64 value = rng.bounded(sup);
+ QVERIFY(value < sup);
+ QCOMPARE(value, expected);
+
+ qint64 ivalue = rng.bounded(qint64(sup));
+ QVERIFY(ivalue < int(sup));
+ QCOMPARE(ivalue, int(expected));
+
+ // confirm only the bound now
+ setRNGControl(control & (SkipHWRNG|SkipSystemRNG|UseSystemRNG));
+ value = rng.bounded(sup);
+ QVERIFY(value < sup);
+
+ value = rng.bounded(sup / 2, 3 * sup / 2);
+ QVERIFY(value >= sup / 2);
+ QVERIFY(value < 3 * sup / 2);
+
+ ivalue = rng.bounded(-qint64(sup), qint64(sup));
+ QVERIFY(ivalue >= -qint64(sup));
+ QVERIFY(ivalue < qint64(sup));
+
+ // wholly negative range
+ ivalue = rng.bounded(-qint64(sup), qint64(0));
+ QVERIFY(ivalue >= -qint64(sup));
+ QVERIFY(ivalue < 0);
+}
+
void tst_QRandomGenerator::generateReal()
{
QFETCH(uint, control);
@@ -673,18 +727,16 @@ void tst_QRandomGenerator::qualityReal()
return;
RandomGenerator rng(control);
- enum {
- SampleSize = 16000,
+ constexpr int SampleSize = 16000;
- // Expected value: sample size times proportion of the range:
- PerfectOctile = SampleSize / 8,
- PerfectHalf = SampleSize / 2,
+ // Expected value: sample size times proportion of the range:
+ constexpr int PerfectOctile = SampleSize / 8;
+ constexpr int PerfectHalf = SampleSize / 2;
- // Variance is (1 - proportion of range) * expected; sqrt() for standard deviations.
- // Should usually be within twice that and almost never outside four times:
- RangeHalf = 252, // floor(4 * sqrt((1 - 0.5) * PerfectHalf))
- RangeOctile = 167 // floor(4 * sqrt((1 - 0.125) * PerfectOctile))
- };
+ // Variance is (1 - proportion of range) * expected; sqrt() for standard deviations.
+ // Should usually be within twice that and almost never outside four times:
+ constexpr int RangeHalf = 252; // floor(4 * sqrt((1 - 0.5) * PerfectHalf))
+ constexpr int RangeOctile = 167; // floor(4 * sqrt((1 - 0.125) * PerfectOctile))
double data[SampleSize];
std::generate(std::begin(data), std::end(data), [&rng] { return rng.generateDouble(); });
@@ -845,18 +897,20 @@ void tst_QRandomGenerator::stdGenerateCanonical()
{
QFETCH(uint, control);
RandomGenerator rng(control);
+ auto generate_canonical = [&rng]() {
+ return std::generate_canonical<qreal, 32>(rng);
+ };
for (int i = 0; i < 4; ++i) {
QVERIFY_3TIMES([&] {
- qreal value = std::generate_canonical<qreal COMMA 32>(rng);
+ qreal value = generate_canonical();
return value > 0 && value < 1 && value != RandomValueFP;
}());
}
// and should hopefully be different from repeated calls
for (int i = 0; i < 4; ++i)
- QVERIFY_3TIMES(std::generate_canonical<qreal COMMA 32>(rng) !=
- std::generate_canonical<qreal COMMA 32>(rng));
+ QVERIFY_3TIMES(generate_canonical() != generate_canonical());
}
void tst_QRandomGenerator::stdUniformRealDistribution_data()
@@ -923,18 +977,18 @@ template <typename Generator> void stdRandomDistributions_template()
{
Generator rd;
- std::bernoulli_distribution()(rd);
+ (void)std::bernoulli_distribution()(rd);
- std::binomial_distribution<quint32>()(rd);
- std::binomial_distribution<quint64>()(rd);
+ (void)std::binomial_distribution<quint32>()(rd);
+ (void)std::binomial_distribution<quint64>()(rd);
- std::negative_binomial_distribution<quint32>()(rd);
- std::negative_binomial_distribution<quint64>()(rd);
+ (void)std::negative_binomial_distribution<quint32>()(rd);
+ (void)std::negative_binomial_distribution<quint64>()(rd);
- std::poisson_distribution<int>()(rd);
- std::poisson_distribution<qint64>()(rd);
+ (void)std::poisson_distribution<int>()(rd);
+ (void)std::poisson_distribution<qint64>()(rd);
- std::normal_distribution<qreal>()(rd);
+ (void)std::normal_distribution<qreal>()(rd);
{
std::discrete_distribution<int> discrete{0, 1, 1, 10000, 2};