1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
/////////////////////////////////////////////////////////////////////////////
#if defined(_MSC_VER)
//#pragma warning(disable: 4267) // 'argument' : conversion from 'size_t' to 'uint32_t', possible loss of data.
#endif
#include "EASTLTest.h"
#include <EASTL/numeric_limits.h>
#include <EASTL/set.h>
#include <EASTL/random.h>
struct GeneratorUint8
{
uint8_t mValue;
GeneratorUint8() : mValue(0) {}
uint8_t operator()(){ return mValue++; } // This is a pretty bad random number generator, but works for our tests.
};
struct GeneratorUint16
{
uint16_t mValue;
GeneratorUint16() : mValue(0) {}
uint16_t operator()(){ return mValue++; }
};
struct GeneratorUint32
{
uint32_t mValue;
GeneratorUint32() : mValue(0) {}
uint32_t operator()(){ return mValue++; }
};
///////////////////////////////////////////////////////////////////////////////
// TestRandom
//
int TestRandom()
{
int nErrorCount = 0;
{
// template<class IntType = int>
// class uniform_int_distribution
// The C++11 Standard defines a number of formal Generators, such as std::mersenne_twister_engine,
// linear_congruential_engine, discard_block_engine, etc.
using namespace eastl;
{
eastl::uniform_int_distribution<uint8_t> uid(1, 6);
GeneratorUint8 g;
for(uint32_t i = 0; i < UINT8_MAX; i += 1)
{
uint8_t value = uid(g);
EATEST_VERIFY((value >= 1) && (value <= 6));
// To do: Validate the randomness of the value.
}
eastl::uniform_int_distribution<uint8_t> uid2(1, 6);
EATEST_VERIFY(uid == uid2);
}
{
eastl::uniform_int_distribution<uint16_t> uid(1, 6);
GeneratorUint16 g;
for(uint32_t i = 0; i < (UINT16_MAX - (UINT16_MAX / 50)); i += (UINT16_MAX / 50))
{
uint16_t value = uid(g);
EATEST_VERIFY((value >= 1) && (value <= 6));
// To do: Validate the randomness of the value.
}
eastl::uniform_int_distribution<uint16_t> uid2(1, 6);
EATEST_VERIFY(uid == uid2);
}
{
eastl::uniform_int_distribution<uint32_t> uid(1, 6);
GeneratorUint32 g;
for(uint32_t i = 0; i < (UINT32_MAX - (UINT32_MAX / 500)); i += (UINT32_MAX / 500))
{
uint32_t value = uid(g);
EATEST_VERIFY((value >= 1) && (value <= 6));
// To do: Validate the randomness of the value.
}
eastl::uniform_int_distribution<uint32_t> uid2(1, 6);
EATEST_VERIFY(uid == uid2);
}
}
/// Example usage:
/// eastl_size_t Rand(eastl_size_t n) { return (eastl_size_t)(rand() % n); } // Note: The C rand function is poor and slow.
/// pointer_to_unary_function<eastl_size_t, eastl_size_t> randInstance(Rand);
/// random_shuffle(pArrayBegin, pArrayEnd, randInstance);
///
/// Example usage:
/// struct Rand{ eastl_size_t operator()(eastl_size_t n) { return (eastl_size_t)(rand() % n); } }; // Note: The C rand function is poor and slow.
/// Rand randInstance;
/// random_shuffle(pArrayBegin, pArrayEnd, randInstance);
{
// void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rng)
using namespace eastl;
EASTLTest_Rand rng(EA::UnitTest::GetRandSeed());
int intArray[] = { 3, 2, 6, 5, 4, 1 };
random_shuffle(intArray, intArray + 0, rng);
EATEST_VERIFY(VerifySequence(intArray, intArray + 6, int(), "random_shuffle", 3, 2, 6, 5, 4, 1, -1));
random_shuffle(intArray, intArray + (sizeof(intArray) / sizeof(intArray[0])), rng);
bool changed = false;
for(int i = 0; (i < 5) && !changed; i++)
{
changed = (intArray[0] != 3) || (intArray[1] != 2) || (intArray[2] != 6) ||
(intArray[3] != 5) || (intArray[4] != 4) || (intArray[5] != 1);
}
EATEST_VERIFY(changed);
// Test of possible bug report by user John Chin.
// The report is that shuffling an ordered array 0, 1, 2, 3, 4 ... results in duplicates, such as 5, 2, 2, 4 ...
eastl::vector<eastl_size_t> rngArray;
for(eastl_size_t i = 0; i < 200; ++i)
rngArray.push_back(i);
random_shuffle(rngArray.begin(), rngArray.end(), rng);
EATEST_VERIFY(rngArray.validate());
eastl::set<eastl_size_t> intSet;
for(eastl_size_t s = 0, sEnd = rngArray.size(); s < sEnd; ++s)
intSet.insert(rngArray[s]);
// If the shuffled array is unique, then a set of its values should be the same size as the array.
EATEST_VERIFY(intSet.size() == rngArray.size());
}
return nErrorCount;
}
|