Bug 5515 – std.conv.to for safer enum casts

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-02-01T16:22:32Z
Last change time
2018-05-22T09:36:08Z
Keywords
bootcamp
Assigned to
No Owner
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2011-02-01T16:22:32Z
If I have an enum of chars, and I have a variable that contains a generic char, I may want to convert the second to an instance of the first one. A normal cast is enough to do it unsafely, but I'd like to be allowed to use to!() to convert it safely (it may raise an error if it's not among the enum cases). An example: import std.conv: to; enum Foo : char { a = 'A', b = 'B' } void main() { Foo r1 = cast(Foo)'A'; // OK Foo r2 = cast(Foo)'X'; // error undetected Foo r3 = to!Foo('A'); // OK Foo r4 = to!Foo('X'); // error detected }
Comment #1 by bearophile_hugs — 2011-08-18T14:51:07Z
This enhancement request comes from a handy feature of the Ada language. It's not too much hard to implement something similar in D too, with I think an acceptable final user syntax: import std.traits: EnumMembers, OriginalType, Unqual; import std.stdio: writeln; private E[] convertEnum(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)(T x) { writeln(x); } template F(string s) { enum F = convertEnum!Foo(s); } void main() { enum Foo[][] foos = [F!"abcabcabc", F!"cbacbacba"]; //import std.conv; //const Foo[] foos2 = to!(Foo[])("abcabcabc"); // not possible yet show(foos); // [[A, B, C, A, B, C, A, B, C], // [C, B, A, C, B, A, C, B, A]] } Still, I think safe compile-time Enum conversion and safe run-time Enum conversion is a feature worth folding inside to!().
Comment #2 by andrej.mitrovich — 2013-02-17T15:05:24Z
Implemented in Issue8143. *** This issue has been marked as a duplicate of issue 8143 ***
Comment #3 by bearophile_hugs — 2013-02-17T16:04:00Z
(In reply to comment #2) > Implemented in Issue8143. > > *** This issue has been marked as a duplicate of issue 8143 *** Given that "Enums with floating-point or string base types are not supported." this is more a WONTFIX :-)
Comment #4 by bearophile_hugs — 2013-02-17T16:33:03Z
But probably this should be supported: import std.conv: to; enum Foo : char { A = 'a' } void main() { dchar d = 'a'; Foo f = to!Foo(d); } Currently it gives: ...\dmd2\src\phobos\std\conv.d(274): Error: template std.conv.toImpl does not match any function template declaration. Candidates are: ... It's useful when you want to write (the argument of this map is a dchar): import std.conv: to; import std.algorithm: map; enum Foo : char { A='a', B='b', C='c' } void main() { auto foos = "abcabcabc".map!(to!Foo)(); }
Comment #5 by andrej.mitrovich — 2013-02-17T16:46:53Z
(In reply to comment #4) > But probably this should be supported: > > > import std.conv: to; > enum Foo : char { A = 'a' } > void main() { > dchar d = 'a'; > Foo f = to!Foo(d); > } Ok. Reopening issue.
Comment #6 by dmitry.olsh — 2018-05-22T09:36:08Z
import std.conv: to; import std.algorithm: map; enum Foo : char { A='a', B='b', C='c' } void main() { auto foos = "abcabcabc".map!(to!Foo)(); } Compiles today, that was the last of it.