1 /*
2    Random generators
3    Template wrappers around std.random.
4 */
5 module qcheck.detail.random;
6 
7 private {
8   import std.random;
9   import std.traits;
10   debug import std.stdio : writeln, writefln;
11 
12   import qcheck.detail.conv;
13 }
14 
15 @property void randomSeed(uint seed)
16 {
17     sGen = Random(seed);
18 }
19 
20 package:
21 // debug=RANDOM;
22 
23 ///
24 T randomNumeric(T)() if(isNumeric!T) {
25   return randomNumeric!(T)(T.min, T.max);
26 }
27 
28 ///
29 T randomNumeric(T)(T lo, T hi) if(isNumeric!T)
30 in {
31   assert(hi >= lo);
32  } body {
33   return hi == lo ? hi : uniform!"[]"(lo, hi, sGen);
34 }
35 
36 ///
37 T randomChar(T)() {
38   import std.utf : isValidDchar;
39 
40   T res;
41   do {
42     res = clipTo!T(randomNumeric(cast(uint)T.min, cast(uint)T.max));
43   } while (!isValidDchar(res));
44   return res;
45 }
46 
47 private:
48 
49 static Random sGen;
50 
51 static this()
52 {
53     sGen = Random(unpredictableSeed);
54 }
55 
56 unittest {
57   auto GenBackup = sGen.save();
58   scope(exit) sGen = GenBackup;
59 
60   auto i = 100;
61   while(--i) {
62     auto val = randomNumeric(0u, 1_000_000_000u);
63     assert(val >= 0 && val <= 1_000_000_000u);
64   }
65   i = 100;
66   while(--i) {
67     auto val = randomNumeric(-1_000_000_000, 1_000_000_000);
68     assert(val >= -1_000_000_000 && val <= 1_000_000_000);
69   }
70   auto sizetVal = randomNumeric!size_t();
71 }