Skip to content

Instantly share code, notes, and snippets.

@JakobOvrum
Created February 13, 2014 03:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakobOvrum/8968977 to your computer and use it in GitHub Desktop.
Save JakobOvrum/8968977 to your computer and use it in GitHub Desktop.
std.random.uniform for enums
import rand = std.random;
import std.traits;
E uniform(E, RNG)(ref RNG rng)
if (is(E == enum) && rand.isUniformRNG!RNG)
{
static if (is(E B == enum))
alias BaseType = B;
else
static assert(false);
static if (!isIntegral!BaseType)
enum isSequential = false;
else
enum isSequential = {
BaseType last = E.min;
foreach (member; EnumMembers!E[1 .. $])
{
if (member != last + 1)
return false;
last = member;
}
return true;
}();
static if (isSequential)
return cast(E)rand.uniform!"[]"(E.min, E.max, rng);
else
{
static immutable E[EnumMembers!E.length] members = [EnumMembers!E];
return members[rand.uniform(0, members.length, rng)];
}
}
E uniform(E)() if (is(E == enum))
{
return uniform!E(rand.rndGen());
}
enum Sequential
{
z = 0,
o = 1,
t = 2
}
enum Sequential2
{
first = 5353355,
second = 5353356,
third = 5353357
}
enum NonSequential
{
a = 2,
b = 1,
c = 0
}
void main()
{
import std.stdio : writeln;
import std.typetuple : TypeTuple;
foreach (E; TypeTuple!(Sequential, Sequential2, NonSequential))
foreach(immutable _; 0 .. 20)
writeln(uniform!E());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment