Thread overview
[Issue 5515] New: std.conv.to for safer enum casts
Feb 17, 2013
Andrej Mitrovic
Feb 18, 2013
Andrej Mitrovic
February 02, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5515

           Summary: std.conv.to for safer enum casts
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody@puremagic.com
        ReportedBy: bearophile_hugs@eml.cc


--- Comment #0 from bearophile_hugs@eml.cc 2011-02-01 16:22:32 PST ---
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
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 18, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5515



--- Comment #1 from bearophile_hugs@eml.cc 2011-08-18 14:51:07 PDT ---
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!().

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 17, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=5515


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |andrej.mitrovich@gmail.com
         Resolution|                            |DUPLICATE


--- Comment #2 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-02-17 15:05:24 PST ---
Implemented in Issue8143.

*** This issue has been marked as a duplicate of issue 8143 ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 18, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=5515



--- Comment #3 from bearophile_hugs@eml.cc 2013-02-17 16:04:00 PST ---
(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 :-)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 18, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=5515



--- Comment #4 from bearophile_hugs@eml.cc 2013-02-17 16:33:03 PST ---
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)();
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 18, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=5515


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|DUPLICATE                   |


--- Comment #5 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-02-17 16:46:53 PST ---
(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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------