Compile time mapping

Bastiaan Veelo Bastiaan at Veelo.net
Sun May 12 17:53:56 UTC 2019


On Saturday, 11 May 2019 at 15:48:44 UTC, Bogdan wrote:
> What would be the most straight-forward way of mapping the 
> members of an enum to the members of another enum (one-to-one 
> mapping) at compile time?

If I understand your question correctly, you have two enums of 
equal length, and you want to convert members across enums 
according to their position, right? You can do that with a little 
bit of template programming and static foreach. The following 
works irrespective of underlying value and type, the only 
requirement is that there are no duplicate values:

https://run.dlang.io/is/dNssel
```
void main()
{
     enum FromEnum {F1 = 10, F2, F3}
     enum ToEnum   {T1 = 20, T2, T3}
     enum CharEnum : char {C1 = 'c', C2, C3}

     static assert(to!ToEnum(FromEnum.F2) == ToEnum.T2);
     static assert(to!ToEnum(FromEnum.F2) == 21);
     static assert(to!CharEnum(FromEnum.F2) == CharEnum.C2);
     static assert(to!CharEnum(FromEnum.F2) == 'd');
}

// Converts enumerations by position.
T to(T, F)(F f) if (is(F==enum) && is(T == enum))
{
     import std.traits;
     import std.meta;
     static assert(NoDuplicates!(EnumMembers!F).length == 
EnumMembers!F.length,
                   F.stringof ~ " has duplicates.");
     static assert(NoDuplicates!(EnumMembers!T).length == 
EnumMembers!T.length,
                   F.stringof ~ " has duplicates.");
     static assert(EnumMembers!F.length == EnumMembers!T.length,
                   F.stringof ~ " and " ~ T.stringof ~ " differ in 
length.");
     static foreach(i, t; EnumMembers!T)
         if (rank(f) == i)
             return t;
     assert(0, "Not an enum member");
}

// Returns i if e is the i-th enumerator of E.
static size_t rank(E)(E e) if (is(E == enum))
{
     import std.traits;
     static foreach (i, member; EnumMembers!E)
         if (e == member)
             return i;
     assert(0, "Not an enum member");
}
```


More information about the Digitalmars-d-learn mailing list