summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qrandom.cpp34
-rw-r--r--src/corelib/global/qrandom.h18
2 files changed, 29 insertions, 23 deletions
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 6a0b86dd6e..9a6e781b99 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 Intel Corporation.
+** Copyright (C) 2020 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -1177,22 +1177,32 @@ bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
/*!
\internal
- Fills the range pointed by \a buffer and \a bufferEnd with 32-bit random
- values. The buffer must be correctly aligned.
+ Fills the range pointed by \a buffer with \a count 32-bit random values.
+ The buffer must be correctly aligned.
+
+ Returns the value of the first two 32-bit entries as a \c{quint64}.
*/
-void QRandomGenerator::_fillRange(void *buffer, void *bufferEnd)
+quint64 QRandomGenerator::_fillRange(void *buffer, qptrdiff count)
{
// Verify that the pointers are properly aligned for 32-bit
Q_ASSERT(quintptr(buffer) % sizeof(quint32) == 0);
- Q_ASSERT(quintptr(bufferEnd) % sizeof(quint32) == 0);
- quint32 *begin = static_cast<quint32 *>(buffer);
- quint32 *end = static_cast<quint32 *>(bufferEnd);
-
- if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & (UseSystemRNG|SetRandomData)))
- return SystemGenerator::self().generate(begin, end);
+ Q_ASSERT(count >= 0);
+ Q_ASSERT(buffer || count <= 2);
+
+ quint64 dummy;
+ quint32 *begin = static_cast<quint32 *>(buffer ? buffer : &dummy);
+ quint32 *end = begin + count;
+
+ if (type == SystemRNG || Q_UNLIKELY(uint(qt_randomdevice_control.loadAcquire()) & (UseSystemRNG|SetRandomData))) {
+ SystemGenerator::self().generate(begin, end);
+ } else {
+ SystemAndGlobalGenerators::PRNGLocker lock(this);
+ std::generate(begin, end, [this]() { return storage.engine()(); });
+ }
- SystemAndGlobalGenerators::PRNGLocker lock(this);
- std::generate(begin, end, [this]() { return storage.engine()(); });
+ if (end - begin == 1)
+ return *begin;
+ return begin[0] | (quint64(begin[1]) << 32);
}
namespace {
diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h
index 7bb90de2bb..29cb24d1f5 100644
--- a/src/corelib/global/qrandom.h
+++ b/src/corelib/global/qrandom.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 Intel Corporation.
+** Copyright (C) 2020 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -83,16 +83,12 @@ public:
quint32 generate()
{
- quint32 ret;
- fillRange(&ret, 1);
- return ret;
+ return _fillRange(nullptr, 1);
}
quint64 generate64()
{
- quint32 buf[2];
- fillRange(buf);
- return buf[0] | (quint64(buf[1]) << 32);
+ return _fillRange(nullptr, sizeof(quint64) / sizeof(quint32));
}
double generateDouble()
@@ -142,13 +138,13 @@ public:
template <typename UInt, IfValidUInt<UInt> = true>
void fillRange(UInt *buffer, qsizetype count)
{
- _fillRange(buffer, buffer + count);
+ _fillRange(buffer, count * sizeof(UInt) / sizeof(quint32));
}
template <typename UInt, size_t N, IfValidUInt<UInt> = true>
void fillRange(UInt (&buffer)[N])
{
- _fillRange(buffer, buffer + N);
+ _fillRange(buffer, N * sizeof(UInt) / sizeof(quint32));
}
// API like std::seed_seq
@@ -160,7 +156,7 @@ public:
void generate(quint32 *begin, quint32 *end)
{
- _fillRange(begin, end);
+ _fillRange(begin, end - begin);
}
// API like std:: random engines
@@ -181,7 +177,7 @@ protected:
QRandomGenerator(System);
private:
- Q_CORE_EXPORT void _fillRange(void *buffer, void *bufferEnd);
+ Q_CORE_EXPORT quint64 _fillRange(void *buffer, qptrdiff count);
friend class QRandomGenerator64;
struct SystemGenerator;