www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5515] New: std.conv.to for safer enum casts

reply d-bugmail puremagic.com writes:
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



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: -------
Feb 01 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5515




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: -------
Aug 18 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
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



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: -------
Feb 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5515





 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: -------
Feb 17 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5515




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: -------
Feb 17 2013
prev sibling parent d-bugmail puremagic.com writes:
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                   |



16:46:53 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);
 }
Ok. Reopening issue. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 17 2013