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