00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00030 #ifndef QUICKCHECK_GENERATE_H
00031 #define QUICKCHECK_GENERATE_H
00032
00033 #include <algorithm>
00034 #include <cassert>
00035 #include <cstdlib>
00036 #include <limits>
00037 #include <vector>
00038
00039 namespace quickcheck {
00040
00051 template<class A>
00052 A generateInRange(A low, A high)
00053 {
00054 assert(low <= high);
00055 A offset = static_cast<A>(double(rand()) / RAND_MAX * (high - low + 1));
00056 return static_cast<A>(low + offset);
00057 }
00058
00067 template<class A, class Iter>
00068 A oneOf(Iter first, Iter last)
00069 {
00070 size_t len = std::distance(first, last);
00071 assert(len > 0);
00072 size_t index = generateInRange(size_t(0), len - 1);
00073 Iter i;
00074 for (i = first; index != 0; ++i)
00075 --index;
00076 return *i;
00077 }
00078
00091 template<class A>
00092 A generateInteger(size_t n)
00093 {
00094
00095 assert(std::numeric_limits<A>::is_integer);
00096
00097 A max = std::numeric_limits<A>::max();
00098 A min = std::numeric_limits<A>::min();
00099 A high = (n > size_t(max)) ? max : A(n);
00100 A low = (n > size_t(-min)) ? min : A(-n);
00101
00102 return generateInRange(low, high);
00103 }
00104
00110 static inline void generate(size_t, bool& out)
00111 {
00112 static const bool booleans[] = { true, false };
00113 out = oneOf<bool>(&booleans[0], &booleans[2]);
00114 }
00115
00129 static inline void generate(size_t n, char& out)
00130 {
00131 static const char *basicChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
00132 "abcdefghijklmnopqrstuvwxyz";
00133 if (n < sizeof (basicChars) - 1)
00134 out = oneOf<char>(&basicChars[0], &basicChars[n]);
00135 else if (n < 95)
00136 out = generateInRange(' ', '~');
00137 else
00138 out = generateInRange(char(0x00), char(0xff));
00139 }
00140
00144 static inline void generate(size_t n, unsigned char& out)
00145 {
00146 char c;
00147 generate(n, c);
00148 out = static_cast<unsigned char>(c);
00149 }
00150
00157 static inline void generate(size_t n, short& out)
00158 {
00159 out = generateInteger<short>(n);
00160 }
00161
00168 static inline void generate(size_t n, unsigned short& out)
00169 {
00170 out = generateInteger<unsigned short>(n);
00171 }
00172
00179 static inline void generate(size_t n, int& out)
00180 {
00181 out = generateInteger<int>(n);
00182 }
00183
00190 static inline void generate(size_t n, unsigned int& out)
00191 {
00192 out = generateInteger<unsigned int>(n);
00193 }
00194
00201 static inline void generate(size_t n, long& out)
00202 {
00203 out = generateInteger<long>(n);
00204 }
00205
00212 static inline void generate(size_t n, unsigned long& out)
00213 {
00214 out = generateInteger<unsigned long>(n);
00215 }
00216
00223 static inline void generate(size_t n, float& out)
00224 {
00225 out = float(rand()) / float(RAND_MAX) * 2 * float(n) - float(n);
00226 }
00227
00234 static inline void generate(size_t n, double& out)
00235 {
00236 out = double(rand()) / RAND_MAX * 2 * n - n;
00237 }
00238
00245 static inline void generate(size_t n, long double& out)
00246 {
00247 out = static_cast<long double>(rand()) / RAND_MAX * 2 * n - n;
00248 }
00249
00258 template<class A>
00259 void generate(size_t n, std::vector<A>& out)
00260 {
00261 unsigned len;
00262 generate(n, len);
00263 for (size_t i = 0; i < len; ++i) {
00264 A a;
00265 generate(n - 1, a);
00266 out.push_back(a);
00267 }
00268 }
00269
00270 }
00271
00272 #endif // !QUICKCHECK_GENERATE_H