23 template <
typename UInt>
using IfValidUInt =
24 typename std::enable_if<std::is_unsigned<UInt>::value &&
sizeof(UInt) >=
sizeof(uint),
bool>::type;
26 QRandomGenerator(quint32 seedValue = 1)
27 : QRandomGenerator(&seedValue, 1)
29 template <qsizetype N> QRandomGenerator(
const quint32 (&seedBuffer)[N])
30 : QRandomGenerator(seedBuffer, seedBuffer + N)
32 QRandomGenerator(
const quint32 *seedBuffer, qsizetype len)
33 : QRandomGenerator(seedBuffer, seedBuffer + len)
35 Q_CORE_EXPORT QRandomGenerator(std::seed_seq &sseq)
noexcept;
36 Q_CORE_EXPORT QRandomGenerator(
const quint32 *begin,
const quint32 *end);
39 Q_CORE_EXPORT QRandomGenerator(
const QRandomGenerator &other);
40 Q_CORE_EXPORT QRandomGenerator &operator=(
const QRandomGenerator &other);
42 ~QRandomGenerator() =
default;
44 friend Q_CORE_EXPORT
bool operator==(
const QRandomGenerator &rng1,
const QRandomGenerator &rng2);
45 friend bool operator!=(
const QRandomGenerator &rng1,
const QRandomGenerator &rng2)
47 return !(rng1 == rng2);
52 return quint32(_fillRange(
nullptr, 1));
57 return _fillRange(
nullptr,
sizeof(quint64) /
sizeof(quint32));
60 double generateDouble()
68 quint64 x = generate64();
69 quint64 limit = Q_UINT64_C(1) << std::numeric_limits<
double>::digits;
70 x >>= std::numeric_limits<quint64>::digits - std::numeric_limits<
double>::digits;
71 return double(x) /
double(limit);
74 double bounded(
double highest)
76 return generateDouble() * highest;
79 quint32 bounded(quint32 highest)
81 quint64 value = generate();
83 value /= (max)() + quint64(1);
84 return quint32(value);
87 quint32 bounded(quint32 lowest, quint32 highest)
89 Q_ASSERT(highest > lowest);
90 return bounded(highest - lowest) + lowest;
93 int bounded(
int highest)
95 Q_ASSERT(highest > 0);
96 return int(bounded(0U, quint32(highest)));
99 int bounded(
int lowest,
int highest)
101 return bounded(highest - lowest) + lowest;
104 quint64 bounded(quint64 highest);
106 quint64 bounded(quint64 lowest, quint64 highest)
108 Q_ASSERT(highest > lowest);
109 return bounded(highest - lowest) + lowest;
112 qint64 bounded(qint64 highest)
114 Q_ASSERT(highest > 0);
115 return qint64(bounded(quint64(0), quint64(highest)));
118 qint64 bounded(qint64 lowest, qint64 highest)
120 return bounded(highest - lowest) + lowest;
124 qint64 bounded(
int lowest, qint64 highest)
126 return bounded(qint64(lowest), qint64(highest));
128 qint64 bounded(qint64 lowest,
int highest)
130 return bounded(qint64(lowest), qint64(highest));
133 quint64 bounded(
unsigned lowest, quint64 highest)
135 return bounded(quint64(lowest), quint64(highest));
137 quint64 bounded(quint64 lowest,
unsigned highest)
139 return bounded(quint64(lowest), quint64(highest));
142 template <
typename UInt, IfValidUInt<UInt> =
true>
143 void fillRange(UInt *buffer, qsizetype count)
145 _fillRange(buffer, count *
sizeof(UInt) /
sizeof(quint32));
148 template <
typename UInt, size_t N, IfValidUInt<UInt> =
true>
149 void fillRange(UInt (&buffer)[N])
151 _fillRange(buffer, N *
sizeof(UInt) /
sizeof(quint32));
155 template <
typename ForwardIterator>
156 void generate(ForwardIterator begin, ForwardIterator end)
158 std::generate(begin, end, [
this]() {
return generate(); });
161 void generate(quint32 *begin, quint32 *end)
163 _fillRange(begin, end - begin);
167 typedef quint32 result_type;
168 result_type operator()() {
return generate(); }
169 void seed(quint32 s = 1) { *
this = { s }; }
170 void seed(std::seed_seq &sseq)
noexcept { *
this = { sseq }; }
171 Q_CORE_EXPORT
void discard(
unsigned long long z);
172 static constexpr result_type min() {
return (std::numeric_limits<result_type>::min)(); }
173 static constexpr result_type max() {
return (std::numeric_limits<result_type>::max)(); }
175 static inline Q_DECL_CONST_FUNCTION QRandomGenerator *system();
176 static inline Q_DECL_CONST_FUNCTION QRandomGenerator *global();
177 static inline QRandomGenerator securelySeeded();
181 QRandomGenerator(System);
184 Q_CORE_EXPORT quint64 _fillRange(
void *buffer, qptrdiff count);
186 struct InitialRandomData {
187 quintptr data[16 /
sizeof(quintptr)];
189 friend InitialRandomData qt_initial_random_value()
noexcept;
190 friend class QRandomGenerator64;
191 struct SystemGenerator;
192 struct SystemAndGlobalGenerators;
193 using RandomEngine = std::mersenne_twister_engine<quint32,
194 32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253>;
198 RandomEngine twister;
199 RandomEngine &engine() {
return twister; }
200 const RandomEngine &engine()
const {
return twister; }
202 static_assert(std::is_trivially_destructible<RandomEngine>::value,
203 "std::mersenne_twister not trivially destructible as expected");