digitalmars.D - Safe enum conversions (again)
- bearophile (41/41) Aug 18 2011 (This is a topic I've already discussed, this time I have a bit of code ...
(This is a topic I've already discussed, this time I have a bit of code to show
too.)
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:
http://d.puremagic.com/issues/show_bug.cgi?id=5515
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
writeln(x);
}
template F(string s) { // helper
enum F = enumConvert!Foo(s);
}
void main() {
enum Foo[9][2] foos = [F!"abcabcabc",
F!"cbacbacba"];
// 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!().
Bye,
bearophile
Aug 18 2011








bearophile <bearophileHUGS lycos.com>