std.random.uniform for enums
Meta
jared771 at gmail.com
Wed Feb 12 19:08:09 PST 2014
On Thursday, 13 February 2014 at 02:30:47 UTC, Frustrated wrote:
> On Thursday, 13 February 2014 at 02:14:02 UTC, Jakob Ovrum
> wrote:
>> On Thursday, 13 February 2014 at 02:02:38 UTC, Anton wrote:
>>> I'm confused about how to use random.uniform to select a
>>> member of an enum.
>>>
>>> Say I have an enum like
>>>
>>> enum Animals
>>> {
>>> cat = 0,
>>> dog = 1,
>>> chimpanzee = 2
>>> }
>>>
>>> I want to select a random animal. So far I've been trying to
>>> do uniform(Animals), but every time I try to compile that, I
>>> get a "does not match any function template declaration"
>>> error.
>>>
>>> Am I misunderstanding how this function is meant to be used?
>>
>> The problem with using `uniform` for enums is that not all
>> enums are sequential without holes, which would make the
>> `uniform` implementation quite non-trivial if it were to try
>> to handle enums generically.
>>
>> If you know your enum is sequential and doesn't have any
>> holes, assume responsibility for that fact with a cast:
>>
>> ---
>> enum Animals
>> {
>> cat = 0,
>> dog = 1,
>> chimpanzee = 2
>> }
>>
>> void main()
>> {
>> import std.random, std.stdio;
>>
>> foreach(immutable _; 0 .. 10)
>> writeln(cast(Animals)uniform!"[]"(Animals.min, Animals.max));
>> }
>> ---
>
> Could you not simply select one at random by "name"? Even though
> the values of the enum may not be sequential the keys are.
import std.random, std.stdio, std.traits;
enum Animals
{
dog = "dog",
cat = "cat",
fox = "fox",
cow = "cow",
}
void main()
{
auto animals = [EnumMembers!Animals];
auto rnd = uniform!"[)"(0, animals.length);
writeln(animals[rnd]);
}
You have to wrap the EnumMembers template in an array, because
tuples can only be sliced at compile-time, and uniform doesn't
work at compile time.
More information about the Digitalmars-d-learn
mailing list