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 }