View mode: basic / threaded / horizontal-split · Log in · Help
December 25, 2012
[Issue 9206] New: std.exception.isValidEnumValue
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: -------
January 20, 2013
[Issue 9206] std.exception.isValidEnumValue
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: -------
January 20, 2013
[Issue 9206] std.exception.isValidEnumValue
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: -------
January 25, 2013
[Issue 9206] std.exception.isValidEnumValue
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: -------
Top | Discussion index | About this forum | D home