www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Safe enum conversions (again)

(This is a topic I've already discussed, this time I have a bit of code to show

I sometimes have to perform run-time or compile-time conversions of enums, from
the enum base type to the enum itself, and I'd like such conversions to be safe
(this means no values outside the one listed in the enum get accepted).

I think this is a job for std.conv.to:

In Ada language there is a nice feature, you are allowed to define an
enumerated set of chars, and then put string literals in your code that are
typed as arrays of that char set. The Ada compiler verifies at compile-time the
string contain only those allowed chars. This is useful for a compact and safe
representation of tables, boards, and for other purposes.

I've seen that it's not too much hard to implement something similar in D too:

import std.traits: EnumMembers, OriginalType, Unqual;
import std.stdio: writeln;

private E[] enumConvert(E, T)(in T[] data)  safe pure nothrow
if (is(E == enum) && is(Unqual!T == OriginalType!Foo)) {
    //assert(__ctfe, "This is a compile-time function only.");

    E[T] dict;
    foreach (member; EnumMembers!E)
        dict[member] = member;

    auto result = new E[data.length];
    foreach (i, item; data)
        result[i] = dict[item];
    return result;

enum Foo : char { A='a', B='b', C='c' }

void show(T)(/*ref*/ T x) { // can't be ref

template F(string s) { // helper
    enum F = enumConvert!Foo(s);

void main() {
    enum Foo[9][2] foos = [F!"abcabcabc",

// not supported yet syntax, issue 481 and 3849
//    enum Foo[$][$] foos = [F!"abcabcabc",
//                           F!"cbacbacba"];

// not possible yet, issue 5515
//    import std.conv;
//    const Foo[] foos2 = to!(Foo[])("abcabcabc");

    show(foos); // [[A, B, C, A, B, C, A, B, C],
                //  [C, B, A, C, B, A, C, B, A]]

I think safe compile-time Enum conversion and safe run-time Enum conversion is
a feature worth folding inside std.conv.to!().

Aug 18 2011