diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qrandom.cpp | 34 | ||||
-rw-r--r-- | src/corelib/global/qrandom.h | 18 |
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; |