www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9206] New: std.exception.isValidEnumValue

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9206

           Summary: std.exception.isValidEnumValue
           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 2012-12-25 01:54:16 PST ---
Sometimes in a program instances of enumerates values contain a value that's
not one of the allowed ones, because of missed initialization ("= void"), data
corruption, badly done casts of integral values to enum instance values, and so
on.

So I sometimes validate an enum instance in function pre-conditions. Below
there is a first implementation of such isValidEnumValue() validating function,
meant to be used mostly in pre-conditions. I suggest to add something similar
to this to std.exception:


//------------------------------------------
import std.traits: EnumMembers, isIntegral, isSomeChar;
import std.algorithm: canFind;

 property bool isCompleteIntervalEnum(E)()
pure nothrow if (is(E == enum)) {
    static if (isIntegral!E || isSomeChar!E) {
        return EnumMembers!E.length == (E.max - E.min + 1);
    } else {
        return false;
    }
} unittest { // isCompleteIntervalEnum tests
    enum E01 : string { S1="abb", S2="booh", S3="zum" }
    static assert(!isCompleteIntervalEnum!E01);

    enum E02 : byte { A=-3, S2=4 }
    static assert(!isCompleteIntervalEnum!E02);

    enum E03: byte { A=0, B=1, C=2 }
    static assert(isCompleteIntervalEnum!E03);

    enum E04: char { A, B, C }
    static assert(isCompleteIntervalEnum!E04);

    enum E05: ulong { A=ulong.max, B=ulong.min }
    static assert(!isCompleteIntervalEnum!E05);

    enum E06: ulong { A=ulong.max, B=ulong.max-1 }
    static assert(isCompleteIntervalEnum!E06);

    enum E07: char { A='a', B='b', C='c' }
    static assert(isCompleteIntervalEnum!E07);
}

bool isValidEnumValue(E)(E e)
pure nothrow if (is(E == enum)) {
    static if (isCompleteIntervalEnum!E) {
        return e >= E.min && e <= E.max; // Optimization.
    } else {
        return [EnumMembers!Foo].canFind(e);
    }
}

enum Foo { A, B, C=10 }

void bar(Foo f)
in {
    assert(isValidEnumValue(f));
} body {
}

void main() {
    //Foo f;
    Foo f = void;
    bar(f);
}
//------------------------------------------

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 25 2012
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9206


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-01-20
13:55:08 PST ---
Is this a duplicate or just related to Issue 8594?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9206



--- Comment #2 from bearophile_hugs eml.cc 2013-01-20 14:45:03 PST ---
(In reply to comment #1)
 Is this a duplicate or just related to Issue 8594?

This enhancement request is for a function to be used mostly at run-time, like inside pre-conditions, to validate single enum arguments. Issue 8597 is meant to be used mostly at compile-time to validate array literals of enums (like strings literals of enum chars). So they are related but they are not the same thing, they aren't a duplicate of each other. (Maybe it's possible to implement part of one using the other, but not fully). So I think they should be kept separated. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 20 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9206



--- Comment #3 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-01-25
15:53:47 PST ---
(In reply to comment #0)
  property bool isCompleteIntervalEnum(E)()
 pure nothrow if (is(E == enum)) {
     static if (isIntegral!E || isSomeChar!E) {
         return EnumMembers!E.length == (E.max - E.min + 1);
     } else {
         return false;
     }
 }

That's an interesting optimization.
 bool isValidEnumValue(E)(E e)
 pure nothrow if (is(E == enum)) {
     static if (isCompleteIntervalEnum!E) {
         return e >= E.min && e <= E.max; // Optimization.
     } else {
         return [EnumMembers!Foo].canFind(e);
     }
 }

A mixed-in switch will be slightly faster in the else clause, except in the case of floating-point which can't be used with switches. Anyway I think it's worth adding. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 25 2013