Enumerating structs?

Simen Kjærås simen.kjaras at gmail.com
Tue Jan 3 08:51:56 PST 2012


On Tue, 03 Jan 2012 16:35:29 +0100, Heywood Floyd <soul8o8 at gmail.com>  
wrote:

>
> Hello!
>
>
> I have some structs
>
>   struct A { int a; }
>   struct B { int b, c; }
>
> and I'd like to be able to enumerate them (preferrably as integers)  
> based on their names. I've no idea how this would look, but
> some pseudo code that would use this feature:
>
>   // pseudo
>   int type = stream.read!int();
>   switch(type){
>     case A.enumof:
>       auto data = stream.read!A();
>       // ...
>     break;
>     case B.enumof:
>       // ...
>     break;
>     // ...
>
> The idea here is to enable stuff like static if's etc and to enforce the  
> connection between the struct and the enumeration. Right now
> I have a separate enums, like so:
>
>   enum {A_ENUM = 1, B_ENUM = 2};
>   // ...
>     case A_ENUM:
>        auto data = stream.read!A();
>        // ...
>     break;
>   //...
>
> But this means the idea that struct A has the enumeration "1" is only by  
> convention. So when I, for instance, refactor struct A to "C",
> all code still compiles. It would be cool if it didn't, somehow. With  
> this small example it's of course not a problem, but for larger
> more complex code perhaps.
>
> A naive idea I had was to let each struct have an enum:
>
>   struct A{
>     enum TYPE_ENUM = 1;
>     int a;
>   }
>
> That would be refactor-friendly and be a strong connection, but then  
> there's no guarantee two structs don't have the same enum,
> of course. Another idea was to maybe use mixin to somehow construct the  
> enum declaration:
>
>   mixin enumByType!(A,B);
>
> That could generate code like:
>
>   enum {A_ENUM = 1, ...}
>
> and then couple it with a
>
>    // ...
>    case typeEnumFor!A():
>        //...
>    break;
>    // ...
>
> but now it's starting to maybe feel a bit overkill?
> Is there an easier/correct/other way?
>
> -
>
> I usually end up feeling like this a lot with D, I just realized. It's  
> like, yes, with mixins I can more or less do anything, but where
> does one stop? You know what I mean? I like it though. Mixin-paralysis :)


Yeah, D feels like that to me too, sometimes. Anyways, for your question -
would using the struct name be good enough? They're easy to get hold of
and usable in switch statements.

If not, how about this:


import std.typetuple;

struct TypeEnum( T... ) {
     static pure nothrow @property
     int value( U )( ) {
         static assert ( staticIndexOf!( U, T ) != -1 );
         return staticIndexOf!( U, T );
     }
}

struct A {}
struct B {}

void main( ) {
     alias TypeEnum!(A, B) types;

     assert( types.value!A == 0 );
     assert( types.value!B == 1 );
}


More information about the Digitalmars-d-learn mailing list